我正在嘗試創建一個MyClass在建構式中動態設定實體屬性的打字稿類:
const myInstance = new MyClass(({
someField: 'foo'
}))
myInstance.someField // typescript should show this as type string
如何使用打字稿創建MyClass以顯示someField為的字串屬性myInstance?
我可以使用泛型嗎?有可能嗎?
uj5u.com熱心網友回復:
從概念上講,您想說類似class MyClass<T extends object> extends Tor 的內容class MyClass<T extends object> implements T,但 TypeScript 不允許class實體或 aninterface具有動態鍵。classorinterface宣告的所有鍵必須是靜態已知的。因此,如果您想要這種行為,您將需要做一些不同于class宣告的事情。
相反,您可以描述所需MyClass<T>實體的型別以及MyClass類建構式的型別,然后使用型別斷言告訴編譯器您的實際建構式物件屬于該型別。
假設您想要的MyClass<T>類實體具有 的所有屬性T,以及一個名為 的方法someMethodIGuess()。那么你的MyClass<T>型別可以這樣定義:
type MyClass<T extends object> = T & {
someMethodIGuess(): void;
}
您希望您的MyClass類建構式具有一個構造簽名,該簽名接受T某個通用 T物件型別的型別引數,并生成MyClass<T>. 可以這樣定義:
type MyClassConstructor = {
new <T extends object>(arg: T): MyClass<T>
}
為了實作這個類,我們可以使用 [ Object.assign()] 將建構式引數屬性復制到實體中,以及我們需要的任何方法或其他東西。
const MyClass = class MyClass {
constructor(arg: any) {
Object.assign(this, arg);
}
someMethodIGuess() {
}
}
但是當然如果我們這樣保留的話,編譯器不會把它MyClass看成a MyClassConstructor(畢竟它不能有動態鍵,我什至沒有嘗試在T這里告訴它)。我們需要一個型別斷言來告訴它,像這樣:
const MyClass = class MyClass {
constructor(arg: any) {
Object.assign(this, arg);
}
someMethodIGuess() {
}
} as MyClassConstructor;
編譯沒有錯誤。再次注意,編譯器無法理解MyClass實作符合MyClassConstructor型別。通過使用型別斷言,我將確保它正確實作的負擔從編譯器(它無法做到)轉移到了我(或者如果您使用此代碼的您)。所以我們應該非常小心地檢查我們做了什么并且我們沒有寫錯東西(例如,Object.assign(arg, this);而不是Object.assign(this, arg);會是一個問題)。
讓我們測驗一下:
const myInstance = new MyClass(({
someField: 'foo'
}))
console.log(myInstance.someField.toUpperCase()); // FOO
myInstance.someMethodIGuess(); // okay
看起來挺好的!編譯器希望myInstance有一個someFieldtype 屬性string,以及那個someMethodIGuess()方法。
就是這樣了。請注意,MyClass以與使用另一個類建構式相同的方式使用時有一些注意事項。例如,編譯器永遠不會class對具有動態鍵的宣告感到滿意,因此如果您嘗試MyClass使用class宣告創建泛型子類,則會出現錯誤:
class SubClass<T extends object> extends MyClass<T> { // error
anotherMethod() { }
}
如果您需要那種東西,您會發現自己必須對子類使用與以前相同的技巧:
type SubClass<T extends object> = MyClass<T> & { anotherMethod(): void };
type SubClassConstructor = { new <T extends object>(arg: T): SubClass<T> };
const SubClass = class SubClass extends MyClass<any> {
anotherMethod() { }
} as SubClassConstructor;
Playground 鏈接到代碼
uj5u.com熱心網友回復:
這個怎么樣?
class MyClass{
constructor(props: any) {
Object.assign(this, props);
}
baz(): string {
return "Hello World";
}
static create<T>(props = {} as T) {
return new MyClass(props || {}) as MyClass & T
}
}
const o = MyClass.create({
foo: 1,
bar: "Hello World"
});
console.log(o.foo);
console.log(o.bar);
console.log(o.baz());
TS游樂場
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/363408.html
上一篇:C#沒有裝箱轉換CS0315錯誤
下一篇:Java雙向引數化類
