Can TypeScript ensure that a parameter is of a specific type or its derivatives, rather than just an instance of that type?
TypeScript type checking on type rather than instance
In the first part, the solution involves using the typeof
keyword
Example
function giveMeAType(type: typeof Foo): void {
}
or with generics
function giveMeAType<T extends typeof Foo>(type: T): void {
}
Exploring this solution further reveals an issue when constructors are introduced to derived types
class Mangler<T> {
protected constructor(
public readonly item: T) {
}
public static getManglers(mangler: typeof Mangler): typeof Mangler[] {
var whatever = [];
return whatever;
}
}
class StringMangler extends Mangler<string> {
// No constructor override here...
}
class NumberMangler extends Mangler<number> {
// However, in this case, I need one...
private constructor(
public readonly item: number) {
super(item);
}
}
// This works since StringMangler does not override the constructor.
Mangler.getManglers(StringMangler);
// But it fails when overriding the constructor for NumberMangler
Mangler.getManglers(NumberMangler);
How can we have Type checking with constructor overrides?
P.S. It is desired for derived types to have options for private or protected constructors!
Update 1
Expanding on Nitzan Tomer's answer, giving the constructor a protected
status resolves the error, but polymorphism cannot be achieved...
class NumberMangler extends Mangler<number> {
// The polymorphic constructor in this example doesn't function as expected.
public constructor(
public readonly item: number,
public readonly name: string) {
super(item);
}
}