求TypeScript强类型Instantiate方法的正确返回类型定义
解决TypeScript Instantiate方法的返回类型匹配问题
你的问题出在TInstances类型的定义上,使用Record会导致所有属性的类型被统一为所有属性类型的联合,而非每个键对应单独的类型。正确的做法是使用映射类型逐个处理每个属性:
class Person { name!: "John Doe" } class Cat { scream!: "Help!!!" } const configApp = { isComplicated: true } const testData = { person: Person, cat: Cat, config: configApp, } as const type TClass = abstract new (...args: any) => any; // 改用映射类型,逐个处理每个键对应的类型 type TInstances<OBJ> = { [K in keyof OBJ]: OBJ[K] extends TClass ? InstanceType<OBJ[K]> : OBJ[K] }; const instantiate = <T>(obj: T): TInstances<T> => { return {} as any} // 现在以下代码均不会报错 const result = instantiate(testData); result.person.name; result.cat.scream; result.config.isComplicated;
为什么原来的写法会出错?
原来的Record<keyof OBJ, OBJ[keyof OBJ] extends TClass ? ... : ...>中,OBJ[keyof OBJ]会取所有属性类型的联合(即typeof Person | typeof Cat | typeof configApp),这会导致每个属性的类型都变成这个联合类型的判断结果——也就是InstanceType<typeof Person> | InstanceType<typeof Cat> | typeof configApp。所以result.person的类型会包含Cat实例和config对象,访问name自然会报错。
而映射类型{[K in keyof OBJ]: ...}会针对每个键K单独判断OBJ[K]的类型,确保每个属性的类型都是对应原属性的实例化结果或原类型,完美匹配键与值的对应关系。
内容的提问来源于stack exchange,提问作者Don John
相关产品推荐
相关产品推荐

