Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating instance of generic types #2037

Closed
ghost opened this issue Feb 15, 2015 · 4 comments
Closed

Creating instance of generic types #2037

ghost opened this issue Feb 15, 2015 · 4 comments
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Question An issue which isn't directly actionable in code

Comments

@ghost
Copy link

ghost commented Feb 15, 2015

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:)

@DanielRosenwasser
Copy link
Member

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!

@danquirk danquirk added By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Question An issue which isn't directly actionable in code labels Feb 16, 2015
@ghost
Copy link
Author

ghost commented Feb 16, 2015

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:)

@AlicanC
Copy link

AlicanC commented May 17, 2015

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
Copy link
Member

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

Even if not, TypeScript loves you. 😄

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

3 participants