我定義了一個Manager來管理一組模塊,我想Module通過Manager實體來訪問實體的方法。這可以推斷嗎?
interface Module<T extends string> {
readonly moduleName: T;
}
class Manager<
T extends Module<any>[],
> {
api: any;
constructor(modules: T) {}
}
class AMoudle {
static moduleName = 'a'
aFun() {}
}
class BMoudle {
static moduleName = 'b'
bFun() {}
}
const manager = new Manager([AMoudle, BMoudle]);
manager.api.a.aFun()
操場
uj5u.com熱心網友回復:
我們可以!首先我們得到一個模塊名稱陣列:
type GetModNames<Mods, Names extends string[] = []> = Mods extends readonly [Module<infer Name>, ...infer Rest] ? GetModNames<Rest, [...Names, Name]> : Names;
這“回圈”通過模塊并推斷每個名稱,然后將名稱添加到結果中。最后,當它完成時,它“回傳”它推斷的名稱。
這需要事先進行一些更改:
模塊名稱也必須是readonly:
class AMoudle {
// READONLY
static readonly moduleName = 'a'
aFun() {}
}
Manager 類應該期望只讀陣列:
class Manager<
T extends ReadonlyArray<Module<string>>,
> {
當您制作經理時,您必須使用as const:
const manager = new Manager([AMoudle, BMoudle] as const);
有了這些,我們將如何制作api屬性的型別:
type MakeApi<Mods> = {
//@ts-ignore ˉ\_(ツ)_/ˉ
[K in GetModNames<Mods>[number]]: InstanceType<Exclude<Mods[number], Exclude<Mods[number], { moduleName: K }>>>
};
我們遍歷我們獲得的每個 mod 名稱,并獲得具有這種有趣結構的模塊:
Exclude<Mods[number], Exclude<Mods[number], { moduleName: K }>>
然后因為模塊是一個類,我們需要它的一個實體,所以我們將它包裝在InstanceType.
不幸的是,我不知道解決該錯誤的方法,所以我在ts-ignore那里使用了:(
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/445939.html
標籤:打字稿
上一篇:使用打字稿在函式中保持物件形狀
