我有几个动态创建的类(可以是数组、对象、w/e)保存在一个变量中,我使用迭代来实例化它们。
例如:
// This is created in another file.
import { ClassOne } from '@data/ClassOne';
import { ClassTwo } from '@data/ClassTwo';
export const myClasses = [
ClassOne,
ClassTwo,
] as const;
// Then, we iterate over it.
const classesInstances = myClasses.reduce((acc, CurClass) => {
acc[_.camelCase(CurClass.name)] = new CurClass({
// Some example variables just to give context.
globalOptions,
sharedCache,
});
return acc;
}, {});
我只想将类添加到数组/对象以实例化新类。
我的问题是如何正确键入
classesInstances
变量,使其代表具有以下结构的对象:
classesInstances: {
classOne: // Instance of ClassOne
classTwo: // Instance of ClassTwo
}
我尝试使用
reduce
函数的第二个参数并将其转换为带有 Record<string, ???>
或 { [key: string]: ??? }
的东西,但我不知道我应该向这些值添加什么。好像是递归问题?我遇到了麻烦。
据我所知,使用一个对象:
type Instance = InstanceType<
(typeof myClassesObj)[keyof typeof myClassesObj]
>;
type DataSourcesInstances = {
[key in keyof typeof dataSourcesObj]: Instance;
};
但是
Instance
没有正确映射到相应的类。
编辑 [22/02]:
快到了!我能够获得正确的值,但在 reduce 循环中仍然存在问题。
// First file
import { ClassOne } from '@data/ClassOne';
import { ClassTwo } from '@data/ClassTwo';
export const myClasses = {
classOne: ClassOne,
classTwo: ClassTwo,
};
// Second file
type ClassesInstances = {
[key in keyof typeof myClasses]: InstanceType<
(typeof myClasses)[key]
>;
};
const myClassesInstances = Object.entries(myClasses).reduce(
(acc, [key, MyClass]) => {
// Here I'm getting: No index signature with a parameter of type 'string' was found on type 'ClassesInstances'.
acc[key] = new MyClass({
context,
cache,
});
return acc;
},
{} as ClassesInstances,
);
// myClassesInstances is correctly typed!
有没有办法告诉 TS 接收字符串是有效密钥?我试过
as keyof ClassesInstances
但问题变成了:Type 'ClassOne | ClassTwo' is not assignable to type 'ClassOne & ClassTwo'.
.
所以,我认为这是一个两部分的问题。
key
变量是 ClassesInstances
类型的有效键。要解决第一个问题,您可以使用类型断言告诉打字稿
key
确实是ClassesInstances
的有效键
MyClass
是 ClassOne
或 ClassTwo
类型。
要解决第二个问题,您可以使用类型断言指定 MyClass
的类型。把它们放在一起看起来像这样:
const myClassesInstances = Object.entries(myClasses).reduce(
(acc, [key, MyClass]) => {
acc[key as keyof ClassesInstances] = new (MyClass as new ({
context,
cache,
}) => InstanceType<typeof MyClass>)({
context,
cache,
});
return acc;
},
{} as ClassesInstances,
);
不能 100% 确定如果不做一堆设置让它在我这边运行,它是否会立即运行,但我认为这对你来说是朝着正确方向迈出的一步。