让我们创建你的DOM类
create
方法变得通用:
type InstanceTypeOf<T> = T extends new () => infer I ? I : never; // get type from a constructor
export class DOM<T extends Record<string, new () => Node>> { // Genneric T, infer constructor param
private readonly defs: T = {} as T;
constructor(nodeDefs: T) {
for (const [nodeName, NodePrototype] of Object.entries(nodeDefs) as Array<[keyof T, T[string]]>) { // fix typing error
this.defs[nodeName] = NodePrototype;
}
}
create<K extends Extract<keyof T, string>>(nodeName: K) { // generic, infer by nodeName type
const newNode = new this.defs[nodeName]();
newNode.name = nodeName;
return newNode as InstanceTypeOf<T[K]>; // casting
}
}
const dom = new DOM({
paragraph: Paragraph,
text: Text,
});
const p = dom.create('paragraph');
// ?^ const p: Paragraph