给定一个类的对象,如何在Typescript中输入初始化类示例的对象?

2cmtqfgy  于 2022-12-19  发布在  TypeScript
关注(0)|答案(1)|浏览(168)

我有一个像这样的对象:

const classMap = {service1: Service1, service2: Service2}

其中Service1和Service2是对类的引用,可以有几百个类。
现在我有了一个动态创建的对象,它对应于:

const instanceMap = {service1: new classMap.service1(), service2: new classMap.service2()}

并且我想输入这个instanceMap(这里类型推导失败,因为对象是动态创建的)。
“typeof classMap”的幼稚方法不起作用,当我使用instanceMap.service1时,我在自动完成中看不到Service1类的方法,似乎typeof操作符正在做一个typeof ServiceX,它擦除了ServiceX类的所有方法。

8gsdolmq

8gsdolmq1#

您可以在classMap的属性上创建mapped type,其中将InstanceType<T>实用程序类型应用于每个属性值:

const classMap = { service1: Service1, service2: Service2 };
type ClassMap = typeof classMap;
type InstanceMap = { [K in keyof ClassMap]: InstanceType<ClassMap[K]> };

这相当于

/* type InstanceMap = {
    service1: Service1;
    service2: Service2;
} */

因此,您可以使用该类型注解instanceMap,而不会出错:

const instanceMap: InstanceMap = {
    service1: new classMap.service1(),
    service2: new classMap.service2()
}; // okay

现在,如果你想动态地创建instanceMap,那么你还需要在你的函数中Map类型,并在实现中自由地使用类型Assert,因为编译器还没有足够的智能来遵循逻辑。

function makeInstanceMap<T extends Record<keyof T, object>>(
    classMap: { [K in keyof T]: new () => T[K] }): T {
    return Object.fromEntries(
        Object.entries(classMap).map(([k, v]) => [k, new (v as any)()])
    ) as T;
}

const instanceMap = makeInstanceMap(classMap);
/* const instanceMap: {
    service1: Service1;
    service2: Service2;
} */

Playground代码链接

相关问题