Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: new() Interface contract not enforced

I'm attempting to test a rather contrived example in the playground on Typescriptlang.org. My INewable interface specifies a single string constructor argument. In the body of my factory method I am not respecting this constraint (either by using a number or calling with a void argument list). I am not getting an error squigly or warning.

Have I done something wrong or is this a bug?

interface INewable<T> {

    new(param: string): T;
}

interface IToStringable {

    toString(): string;
}

module Factory {

    export function createInstance<T extends IToStringable>(ctor: INewable<T>): T {

        return new ctor(1024); //why doesn't this fail?
    }
}

var d = Factory.createInstance(Function);

alert(d.toString());

EDIT: The simpler form:

function createInstance<T>(ctor:new(s:string)=>T):T {
    return new ctor(42); //why doesn't this fail either
}

exhibits the same bug.

like image 718
richardpj Avatar asked Nov 02 '22 15:11

richardpj


1 Answers

Nice catch. Its a bug in the compiler. Simpler sample:

interface INewable<T> {
    new(param: string): T;
}

function createInstance<T>(ctor: INewable<T>): T {
   return new ctor(1024); //why doesn't this fail?
}

Basically I think its because T is of type any within a generic item. That is confusing the compiler and parts of it (not entirely) think ctor is also any.

E.g. the following is not an error :

interface INewable<T> {
    new(param: string,anotherparam): T;
}

function createInstance<T>(ctor: INewable<T>): T {
   return new ctor(1024); //why doesn't this fail?
}

But the following does:

interface INewable<T> {
    anything(): T;
}

function createInstance<T>(ctor: INewable<T>): T {
   return new ctor(1024); //fails
} 

You can report it here : https://typescript.codeplex.com/workitem/list/basic, and if you do I'd appreciate a link so I can vote on the bug

like image 173
basarat Avatar answered Nov 10 '22 04:11

basarat