从 TypeScript 开始,我尝试使用keyof
定义类的动态属性:
type UserType = {
id: number,
name: string,
}
class Domain<T> {
_data: T;
[K in keyof T]: T[K]; // Does not build:
// (1) A computed property name must be of type
// 'string', 'number', 'symbol', or 'any'
// (2) Cannot find name 'keyof'
constructor(data: T) {
this._data = data;
Object.keys(data).forEach((key) => Object.defineProperty(this, key, { get: () => this._data[key] }));
}
}
const joeData: UserType = {
id: 1,
name: 'Joe',
}
const joe = new Domain(joeData); // type: Domain<UserType>
console.log(joe.id);
我确实使用与以下相同的(工作)语法编写了这段代码:
type Foo<T> = {
[K in keyof T]: T[K];
}
有关如何解决该问题的任何提示吗?
映射类型不能在接口或类中使用。它们只能在类型别名中使用。
如果涉及泛型,接口和类继承就不能与映射类型很好地混合。 Typescript 希望预先了解基类/接口的形状,因此我们可以编写如下内容:
interface Foo extends Pick<UserType, keyof UserType> {
}
我们不能写
interface Foo<T> extends Pick<T, keyof T> { //An interface can only extend an object type or intersection of object types with statically known members
}
这消除了通过类接口合并欺骗编译器的任何可能性。
唯一的解决方法是单独定义类,并使用自定义构造函数签名。自定义构造函数签名可以具有泛型类型参数,并且可以在返回的实例类型中使用它。我们可以使返回类型成为Domain
类在交叉点T
:
type UserType = {
id: number,
name: string,
}
class _Domain<T> {
_data: T;
constructor(data: T) {
this._data = data;
Object.keys(data).forEach((key) => Object.defineProperty(this, key, { get: () => this._data[key] }));
}
}
const Domain = _Domain as ({
new <T>(data: T): _Domain<T> & T
})
const joeData: UserType = {
id: 1,
name: 'Joe',
}
const joe = new Domain(joeData); // type: _Domain<UserType> & UserType
console.log(joe.id);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)