打字稿通用为参数

时间:2018-12-19 18:08:14

标签: typescript generics reflection prototypal-inheritance type-safety

我有一堂课

export class BaseClass<T> {
    constructor(data?: Partial<T>) {
        Object.assign(this, data);
    }
    name: string;
    id: number;
}

从此类中,我扩展属性:

export class ExampleOne extends BaseClass<ExampleOne> {
    isReusable: boolean;
}

export class ExampleTwo extends BaseClass<ExampleTwo> {
    propOne: string;
    propTwo: boolean;

}

我在BaseClass中使用了映射类型,因此我可以具有与C#相似的语法来初始化对象,并在后续继承BaseClass的类中重用构造函数。

var x = new ExampleTwo({name: 'test', id: 1, propOne: 'test', propTwo: false});

这一切似乎都工作正常,但是我想将这些派生类中的任何一个作为参数传递给另一个函数。

testFunction(data: BaseClass<T>) {
    //logic
}

我收到一条错误消息,指出构建Cannot find name T。我将签名更改为

testFunction(data: BaseClass<any>) {
    //logic
}

似乎可行,但是我觉得应该有更好的方法来解决这个问题。

我想念什么?

1 个答案:

答案 0 :(得分:1)

您的解决方案有效,但前提是您以{em> opaque 对象的身份访问data中的// logic。这意味着您只是将其作为参考传递,而您的逻辑则不在乎对象BaseClass以外的其他属性。

为了使它可以作为 transparent 对象进行访问,从而可以对实例keyof等进行类型安全的反射,应使用通用类型参数{ {1}}像这样:

T

您第一次尝试导致错误的原因是因为testFunction<T>(data: BaseClass<T>) { // logic } 所属的类显然不是像testFunction这样的泛型类,而只是class Foo<T> { ... }。 / p>

如果您的类中有几个需要访问类型class Foo { ... }的函数,那么我建议将其设为通用类,这样就不必为每个成员添加类型参数T方法。