You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 21:07:50