如何解决Typescript,不要使用泛型丢失类型信息
在getValue
类的DataBankService
方法下面的代码中,丢失了类型信息(请参见示例)。是否可以保留类型信息?
https://stackblitz.com/edit/typescript-rx-playground-gqnzuq?file=index.ts
import { Subject } from "rxjs/";
export interface DataObject<T> {
value: T;
observable: Subject<T>;
}
export class DataBankService {
private dataBank: DataBankProperties;
constructor() {
this.dataBank = new DataBankProperties();
}
public getValue<T extends keyof DataBankProperties,V>(property: T) {
return this.dataBank[property].value;
}
}
class DataBankProperties {
money: DataObject<number> = this.createDataObject();
token: DataObject<string> = this.createDataObject();
testament: DataObject<object> = this.createDataObject();
private createDataObject<T>() {
return {
value: null,observable: new Subject<T>(),};
}
}
const dataBank = new DataBankService();
// token is now type >> token: string | number | object
const token = dataBank.getValue('token');
// I would like this to be type string
// token is now type >> token: string | number | object
const money = dataBank.getValue('money');
// I would like this to be type number
解决方法
您可以在返回类型上使用断言来执行此操作-将泛型用作DataBankProperties的键。我已将其重命名为K以表示约定(如K表示密钥)
public getValue<K extends keyof DataBankProperties>(property: K): DataBankProperties[K]['value'] {
return this.dataBank[property].value;
}
,
我建议创建一个类型来推断DataObject的通用类型:
type DataObjectTypeInference<T> = T extends DataObject<infer U> ? U : never;
然后像这样使用它:
public getValue<K extends keyof DataBankProperties>(property: K) {
return this.dataBank[property].value as DataObjectTypeInference<
DataBankProperties[T]
>;
}
首先,定义一个类型,该类型将照顾当前类型实例的DataObject的通用类型。我个人更希望不要在属性名称之间加上任何文字,也不要喜欢我之前的评论。我希望它是由TypeScript推断的,因此,如果您决定将value键更改为另一个名称,则不会影响类型推断。
然后,将变量的类型声明为DataBankProperties [T],它为您提供DataObject的类型,现在您使用我们构建的类型并推断出DataObject的通用类型。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。