Can Poyrazoğlu
Can Poyrazoğlu

Reputation: 34810

How to define Typescript function that takes a type as a strongly typed argument

I want to create a function that takes in a type (created with export class and imported normally) that extends a specific type. I have a Page class and many derived classes. In plain English, I'd like to have a function accept Page, DerivedPage, AnotherDerivedPage classes (not instances), obviously, trying to avoid any and keep strong typing.

How do I do it?

Upvotes: 2

Views: 308

Answers (2)

Doğancan Arabacı
Doğancan Arabacı

Reputation: 3992

If you want only the classes Page, DerivedPage, AnotherDerivedPage; you can use something as follows:

function foo (foo: Page | DerivedPage | AnotherDerivedPage)

If you want an argument which extends Page, probably below is the way to go:

function foo<T extends Page> (a: T) { ... }

EDIT:
Adding an example of such type to use with arrow functions

type foo<T extends Page> = (v: T) => void
const fn: foo<DeribedPage> = (v) => { /* ... */ }

Upvotes: 2

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250106

You just need to use a constructor signature:

class Page {
    private p!: string;
}
class DerivedPage extends Page { }
class OtherPage extends Page { 
    constructor(param: number){
        super();
    }
}
class NotPage { private np!: string; }

function createPage(ctor: new (...a: any[])=> Page, ...a: any[]) {
    new ctor(...a);
}

Depending on need you can also create a more generic version that preserves parameter and class type:

//Preserves argument and class type
function genericCreatePage<T extends Page, A extends any[]>(ctor: new (...a: A)=> T, ...a:A){
    return new ctor(...a);
}

genericCreatePage(DerivedPage)
genericCreatePage(OtherPage, 0)
genericCreatePage(OtherPage, "0") //err

Upvotes: 1

Related Questions