我正在嘗試在 TypeScript 中撰寫一個類,它允許我在某種網路中連接不同型別的元素。每種元素的允許目標型別應該是可約束的,所以我撰寫了這個非常簡單的泛型類:
abstract class Element<Target = unknown> {
targets: Target[] = [];
into(...targets: Target[]): this {
// implementation omitted for brevity
return this;
}
}
這使我可以對以下內容進行正確的型別檢查:
class First extends Element<First | Second> { // Can connect to First or Second
firstProp = "";
}
class Second extends Element<First | Second> { // Can connect to First or Second
secondProp = "";
}
class Third extends Element<Third> { // Can only connect to itself
thirdProp = "";
}
const first = new First();
const second = new Second();
const third = new Third();
first.into(first); // works, OK
first.into(second); // works, OK
first.into(third); // error, OK
到目前為止,一切都很好。然后,我想為類添加一個方便的方法,允許我通過指定一組要連接的源來指定連接。但是,我似乎無法提出正確的簽名來完成此操作,因此我嘗試添加此方法:
from(...sources: Element<this>): this {
// omitted again
return this;
}
// This should work now:
first.from(second); // But errors
但它不起作用,因為它的簽名要求sources是 type Element<First>,而是secondtype Element<First | Second>,所以 TypeScript 錯誤正確,因為First不extends First | Second,但反過來。這是一個問題,因為可以撰寫泛型 likeX extends this但當然不是泛型 like this extends X。
所以 of 的型別sources應該是一個Elements 的陣列,它們的聯合中有thisoffrom的實體Target,但我不知道如何在 TypeScript 中拉出這樣的東西,或者是否有可能。
我嘗試了許多對簽名的變體,嘗試與條件型別和其他好東西組合。盡管如此,到目前為止沒有任何效果,我慢慢開始相信我已經嘗試了這么多錯誤的事情,以至于我現在完全走錯了路,而且我在這里遺漏了一些完全明顯的東西,因此非常感謝任何輸入。
uj5u.com熱心網友回復:
from<Sources extends Element<unknown>[]>(...sources: {
[K in keyof Sources]: this extends Sources[K]["targets"][number] ? Sources[K] : Error & { error: ["This class's targets do not include", Target] };
}): this {
// omitted again
return this;
}
使用泛型來推斷目標的型別,然后我們可以在其余引數的型別中檢查每個給定元素的目標。如果它與 不匹配this,那么我們將預期的型別“更改”為Error & { ... },本質上是給用戶一個有用的錯誤訊息。
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/514940.html
標籤:打字稿打字稿泛型
