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

Typescript泛型推断为何未识别rec与rec2类型不一致?

问题原因

你的写法里createMyType的泛型约束是T extends MyType<Record<string, any>>,TypeScript在做类型推断时,会自动推导满足约束的最宽松的公共超类型:

  • 第一个示例中,rec的类型是{idFoo: number},rec2是number,二者的公共超类型不满足Record<string, any>的要求,所以直接报错,符合预期。
  • 第二个示例中,{idFoo: number}和空对象{}的公共超类型正好是Record<string, any>,TypeScript会直接把MyType的泛型参数TRecord推导为Record<string, any>,此时两个属性都符合类型要求,自然不会抛出错误。

你原来的写法没有让TypeScript优先锁定TRecord的具体类型,而是允许它自动放宽到满足约束的公共超类型,所以才会出现第二个示例不报错的问题。

正确写法

你只需要把createMyType的泛型参数调整为直接对应TRecord,让TypeScript优先从入参里推导TRecord的具体类型,而不是先推导整个MyType实例的类型即可:

type MyType<TRecord extends Record<string,any>> = {
    rec: TRecord
    rec2: TRecord
}

const myRec = { idFoo: 3 } 

// 泛型参数直接对应TRecord
function createMyType<TRecord extends Record<string, any>>(obj: MyType<TRecord>): MyType<TRecord> {
    return obj
}

const myType = createMyType({
    rec: myRec,
    rec2: 3, // 依然报错
})

const myType2 = createMyType({
    rec: myRec,
    rec2: {}, // 现在会正常报错:类型 "{}" 中缺少属性 "idFoo",但类型 "{ idFoo: number; }" 中需要该属性
})

如果你的TS版本在5.4以上,还可以配合NoInfer工具类型强制让TS只从rec属性推导TRecord,避免出现双向推导放宽类型的情况,写法更严谨:

function createMyType<TRecord extends Record<string, any>>(obj: {
  rec: TRecord,
  rec2: NoInfer<TRecord>
}): MyType<TRecord> {
    return obj
}

内容的提问来源于stack exchange,提问作者sam256

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:06:06