我尝试实现将包含类实例的JS Object返回为值并将类名称作为键的函数。
类似的东西:
const init = (construcorsMap) => {
return Object.keys(construcorsMap).reduce((ret, constructorName) => {
ret[constructorName] = new (construcorsMap[constructorName])();
return ret;
}, {});
class C1 {};
class C2 {};
const instances = init({C1: C1, C2: C2});
如何在TypeScript上标注它?
答案 0 :(得分:2)
这可以使用InstanceType
和自定义映射类型来完成。您将在实现中需要一些类型断言,但调用站点将完全是类型安全的
type InstanceTypes<T extends Record<keyof T, new () => any>> = {
[P in keyof T]: InstanceType<T[P]>
}
const init = <T extends Record<keyof T, new () => any>>(construcorsMap: T): InstanceTypes<T> => {
return (Object.keys(construcorsMap) as Array<keyof T>).reduce((ret, constructorName) => {
ret[constructorName] = new (construcorsMap[constructorName])();
return ret;
}, {} as InstanceTypes<T>);
}
class C1 { c1!: number};
class C2 { c2!: string};
const instances = init({C1: C1, C2: C2});
instances.C1.c1;
instances.C2.c2
实时副本on the playground。
答案 1 :(得分:1)
您可以使用内置InstanceMap
创建InstanceType
类型:
type InstanceMap<C extends Record<string, new () => any>> = {
[k in keyof C]: InstanceType<C[k]>
};
function init<C extends Record<string, new () => any>>(classMap: C): InstanceMap<C> {
// your implementation
return {} as any
}
class C1 { foo1() {} }
class C2 { foo2() {} }
const classMap = { C1, C2 };
const instances = init(classMap)
instances.C1.foo1()
instances.C2.foo2()