我正在嘗試創建一個 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]
}), {});
}
}
這似乎類似于這個問題,但我不知道在這種情況下如何應用它,因為屬性是從外部傳入的。
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,而是從初始化實體時傳遞的道具派生它們?
我試圖圍繞泛型,并在想可能是這樣的:
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'。” (我的意思是,有道理;它超出了范圍。)
更新:這感覺更接近,但我遇到了一個問題,即首先在類上定義屬性(在建構式之上):
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傳入的可能有自己的鍵,但必須是屬性型別的實體,它限制了值。
uj5u.com熱心網友回復:
您的泛型型別需要繼續class宣告,而不是其建構式。然后keyof Type需要是匿名型別。您還需要鍵入properties,以便 TypeScript 知道它可以用 索引keyof Type,我在這個例子中通過給它一個型別來做到這一點Partial<Type>。
我還使用了型別斷言,因此{}您的初始物件的reduce型別為Partial<Type>,因此 TypeScript 將了解如何在創建它后對其進行索引。
class MyClass<Type> {
properties: Partial<Type> = {};
constructor(properties: Type) {
this.properties = properties;
}
pick(...propNames: (keyof Type)[]) {
return propNames.reduce((obj, name) => ({
...obj,
[name]: this.properties[name]
}), {} as Partial<Type>);
}
}
打字稿游樂場
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/475393.html
