1

Im using typescipt 2. Im writing some parser method which receives a model from the server and converts it to an instance I can use.

Code:

export interface Constructable {
     copy(other : any) : void;
}

//in my Convert class which converts server responses to model
private static _parseT<T extends Constructable>(obj : any) : T {
    let instance = Object.create(T); // the row of the compile-time error
    instance.constructor.apply(instance);
    instance.copy(obj);
    return instance;
}

and lets assume I have the following class

export class Foo implements  Constructable {
    private test : string  = null;

    public copy(other:any) : void {
        this.test = other.test;
    }
}

I have a compile time error

Could not find name T

now, Im sure its not the syntax but I couldn't find how.

To clear things out. this is how the useage looks like:

public static ParseFoo(data: any) : Foo{
    return Convert._parseT<Foo>(data.mResult); // data is a server response object
}

NOTE

Although some factory pattern would solve this, I would really like to stay with the Copy method instead of some Generate which creates and returns an instance

1 Answer 1

2

You get this error because T is a type, not a class.

A class in typescript has this signature: new(...args: any[]) => any and you can call Object.create on it, since T isn't a variable in your function you can't do such a thing.

To achieve what you want to do, you have to pass the class itself as argument:

private static _parseT<T extends Constructable>(clazz: new(...args: any[]) => any, obj : any) : T {
    let instance = <Constructable>new clazz();
    instance.copy(obj);
    return <T>instance;
}

This way, the only clazz that will be accepted is the one that constructs your type.

You can have an example on something I made recently on github (not an angular project but your issue is a pure typescript issue).

An example call for this function:

let FooInstance = this._parseT<FooClass>(FooClass, myObj);

Here, the first FooClass is the type, while the seconde one reefers to the class itself.

Since you can't get the class of a type at runtime, it's the only olution for you to construct a class from its type.

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

7 Comments

its synatictically incorrect. clazz:new(...args:any[]):T is wrong. tried to convert it to clazz:new(...args:any[])=>T and then I have compile errors as well
oh yes sorry I'll fix this typo, but the second one should compile... oO (check the example I linked, it compiles perfectly)
Property 'copy' does not exist on type 'new (...args: any[]) => T' Also Type 'new (...args: any[]) => T' is not assignable to type T
Oh yes, that's because I created an implementation without knowing what you wanted to achieve, if I'm right you want to create an instance from an object and its class, with properties already set? EDIT: I think you have to change =>T for =>any because the T returned by new doesn't have the copy method, I'll change the response a bit to fit this.
yes. but I always want to create the object via the empty ctor and then just invoke the copy method.
|

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.