0

Part one asks the question - "Is it possible for TypeScript to ensure that a parameter is of a given type or its derivatives, rather than an instance of a type or its derivatives?"

TypeScript type checking on type rather than instance

The solution in part one is to use the typeof keyword

Example

function giveMeAType(type: typeof Foo): void {
}

or with generics

function giveMeAType<T extends typeof Foo>(type: T): void {
}

Expanding on this solution, I have a new problem 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> {
    // But in this case, I need one...
    private constructor(
        public readonly item: number) {
        super(item);
    }
}

// This one works while StringMangler does not override the constructor.
Mangler.getManglers(StringMangler);

// But when I override the constructor, it doesn't work.
Mangler.getManglers(NumberMangler);

Playground

How then do me maintain Type checking with constructor overrides?

P.S. I want the derived types to have the ability to have private or protected constructors!

Update 1

To elaborate on Nitzan Tomer's answer, I can make the constructor protected, and the error goes away, but I can't make the constructor polymophic...

class NumberMangler extends Mangler<number> {
    // This polymorphic constructor doesn't work.
    public constructor(
        public readonly item: number,
        public readonly name: string) {
        super(item);
    }
}
1
  • In order to help with the "polymorphic constructor" problem, it will be best if you elaborate on how you plan to use this Mangler. Commented Feb 13, 2017 at 21:37

1 Answer 1

1

If you make the NumberMangler.constructor protected then the error goes away:

class NumberMangler extends Mangler<number> {
    protected constructor(
        public readonly item: number) {
        super(item);
    }
}

Edit

This should work:

class NumberMangler extends Mangler<number> {
    protected constructor(item: number);
    protected constructor(item: number, name: string);
    protected constructor(
        public readonly item: number,
        public readonly name?: string) {
        super(item);
    }
}

You don't really need the non-implementation signatures, but I think it makes it more readable.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Nitzan...with a bit of playing I worked that out, but apologies, I neglected to point out in my question that overridden constructors can't be polymorphic. See my update.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.