通用类作为内部类型的参数

时间:2016-03-25 13:20:43

标签: json generics typescript

我使用Cerialize作为Json序列化器/反序列化器。

我的Api连接器以这种方式工作:

ApiService.get<T>(endpoint:string):Promise<T>

来电

ApiConnectorService.get<ApiResponse<T>>(tClazz:{new():T;}, endpoint:string);

要反序列化,Cerialize使用类参数:

function Deserialize(json: any, type?: Function | ISerializable): any;

因此,当我致电ApiService.get<T>(endpoint)时,我会在其中拨打ApiConnectorService.get<ApiResponse<T>>(ApiResponse, endpoint)

问题

我无法提供ApiResponse<T>作为tClazz参数,编译器说

  

TS1109:预期的表达

有没有办法为Generic类提供Generic类型作为参数?这样,当我调用get<User>()时,我得到ApiResponse<User>类型的用户,目前我只在ApiResponse中获得一个对象,这不是我们需要的。

这是ApiResponse类:

export class ApiResponse<T>{

    @deserialize
    data:T;

    @deserializeAs(ErrorData)
    error:ErrorData;

    @deserialize
    meta:Object;
}

编辑:如果我想将数组作为类参数提供相同的错误:

ApiService.get<Foo[]>(Foo[], '/bar');
  

TS1109:预期的表达

2 个答案:

答案 0 :(得分:0)

你不能,如果你在这里查看转换后的泛型类:Typescript Playground它会丢失泛型,所以在运行时你没有类型,所以你不能得到泛型的类型,意思是,运行时你不知道你的T是什么类型。你必须将类本身作为参数传递。您可以使用泛型进行编译帮助,但这是您可以做的最好的事情。

答案 1 :(得分:0)

考虑到不支持嵌套泛型,并且泛型只是编译时构造,我已经做了一个小样本,希望对你有所帮助:

export class User
{
    private name: string;

    constructor(serializedValue: string)
    {
        this.name = serializedValue;
    }
}

export class ApiResponse<T>
{
    constructor(val: T)
    {
        this.data = val;    
    }

    data:T;

    error:string;

    meta:Object;
}

class ApiConnectorService<T>
{
    public get<U extends ApiResponse<T>>(tClazz: {new(s: string):T;}, uClazz: {new(t: T):U;}, endpoint:string): U
    {
        let val = 'user';//get serializedvalue from endpoint
        return new uClazz(new tClazz(val));
    }
}   

class ApiService
{
    public get<T>(tClazz: {new(s: string):T;}, endpoint:string): T
    {
        let s = new ApiConnectorService<T>();
        return s.get(tClazz, ApiResponse, '123').data;
    }
}

let a = new ApiService();
console.log(a.get<User>(User, '12'));