我试图创建一个用对象初始化的TypeScript类,该类有一个方法,该方法只能将该对象的键作为参数.所以:
class MyClass {
properties = {};
constructor(properties) {
this.properties = properties;
}
// Passed propNames should only be keys of this.properties
pick(...propNames) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
这似乎类似于this problem,但我不知道如何在这种情况下应用它,因为属性是从外部传入的.
const props = { key: 'value', key2: 'value2' };
interface PropKeys {
key: string;
key2: string;
}
type KeyName = keyof(PropKeys);
// But what do I do to the class to get this to work?
const instance = new MyClass(props);
instance.pick('key', 'key2'); // Great
instance.pick('key3'); // Should throw a type error
这可能吗?有没有一种方法可以不显式定义InstanceKeys
,而是从初始化实例时传递的props 派生它们?
我试着用泛型来概括我的 idea ,可能是这样的:
class MyClass {
properties = {};
constructor<Type>(properties: Type) {
this.properties = properties;
type TypeKeys = keyof(Type);
}
pick(...propNames: TypeKeys[]) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
但这会引发两种类型的错误:
- 在
<Type>
上:"类型参数不能出现在构造函数声明上." - 在
TypeKeys[]
上:"找不到名称‘TypeKeys’."(我的意思是,这是有道理的;它超出了范围.)
UPDATE:这感觉更接近了,但我遇到了一个问题,即首先在类(构造函数上方)上定义属性:
class MyClass<PropType extends Properties> {
properties: PropType = {};
constructor(properties: PropType) {
this.properties = properties;
}
pick(...propNames: Array<keyof(PropType)>) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {});
}
}
我在那条线上遇到的TS错误是
Type '{}' is not assignable to type 'PropType'. '{}' is assignable to the constraint of type 'PropType', but 'PropType' could be instantiated with a different subtype of constraint 'Properties'
这里的问题是,传入的任何properties
都可能有自己的键,但必须是类型属性的实例,这会限制值.