Typescript: Creating instance of generic types

Created on 15 Feb 2015  路  4Comments  路  Source: microsoft/TypeScript

Hello,

Why can't I do following?

image

In above case TypeScript compiler knows lexically that T is MyData, so why it can't exchange new T() with new MyData() ?

Thanks:)

By Design Question

Most helpful comment

You have to remember what new does in JavaScript, in that you need an actual _constructor value_ to be new-ed. T is just a type, not a value.

In our type system, we require a value to have a construct signature in its type to be new-able. So this is something closer to what you want:

interface NoParamConstructor<T> {
    new (): T;
}

class View<T> {
    data: T;
    constructor(ctor: NoParamConstructor<T>) {
        this.data = new ctor();
    }
}

class MyData {
    user: string
}

class MyView extends View<MyData> {
    constructor() {
        // This will work because 'MyData' is also an entity
        // in the value space.
        super(MyData);
    }
}

var view = new MyView();

Hope that helps!

All 4 comments

You have to remember what new does in JavaScript, in that you need an actual _constructor value_ to be new-ed. T is just a type, not a value.

In our type system, we require a value to have a construct signature in its type to be new-able. So this is something closer to what you want:

interface NoParamConstructor<T> {
    new (): T;
}

class View<T> {
    data: T;
    constructor(ctor: NoParamConstructor<T>) {
        this.data = new ctor();
    }
}

class MyData {
    user: string
}

class MyView extends View<MyData> {
    constructor() {
        // This will work because 'MyData' is also an entity
        // in the value space.
        super(MyData);
    }
}

var view = new MyView();

Hope that helps!

Thanks for the answer - I'm aware of the workaround you mentioned.

However I still think you could solve this "lexically" - just by replacing type parameter with original type definition in generate JS.
In fact my above example is just to validate types during design time - in pure JS this is exactly how I would exchange it - and it's seems like this could be done by TSC based on type parameters.

Anyway - thanks for fast response:)

You have the exact same situation in C#. Making new T() doable would be weird since T is a type.

However, in C#, you have Type.GetConstructor and Activator.CreateInstance to help you tackle this problem.

@DanielRosenwasser, could we have any of that love in TypeScript?

@DanielRosenwasser, could we have any of that love in TypeScript?

Even if not, TypeScript loves you. :smile:

You have the exact same situation in C#.

Actually, @AlicanC, you can specify a new Constraint in C#.

The difference is that in C#, there is a straightforward correspondence between types and their constructors. We're not really blessed with that benefit. In my example, I've done something loosely similar, except you have to explicitly pass the constructor function (in this case ctor) as an argument.

If you think about the example though, we've sort of just replaced the type argument with a regular argument, which is not much worse really.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Antony-Jones picture Antony-Jones  路  3Comments

remojansen picture remojansen  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

jbondc picture jbondc  路  3Comments