TypeScript条件extends判断可选嵌套对象属性校验失效问题
问题根因
- 可选属性的类型会自动被TypeScript追加
undefined联合项:例如parent?: {child: number}的实际类型为{child: number} | undefined。条件类型对联合类型采用分布式判定逻辑,会逐一校验联合中的每一个成员,undefined不满足对象类型校验规则,最终会得到对象类型和"something"的错误联合结果。 - 原判断条件
{[k:string]: any}存在误判:TypeScript中string、number等原始类型支持索引访问,会被该规则判定为匹配,导致原始类型属性无法被正确替换为"something"。
修复方案
使用TypeScript内置的object类型作为非原始对象的判定标准(该类型仅匹配对象、数组、函数等非原始值,排除所有原始类型和null/undefined),同时用NonNullable工具类型先剥离属性类型中的null和undefined再做判定,即可保留原属性的可选修饰符和对象类型结构:
type myType<T> = { [K in keyof T]: NonNullable<T[K]> extends object ? T[K] : "something" }
效果验证
修复后的类型完全符合预期,以下写法可以正常通过校验:
declare class myObject { name?: string id?: number parent?: { child: number } } const example: myType<myObject> = { parent: { child: 0 }, name: "something", id: "something" }
不符合规则的写法会被正确拦截:
// 以下代码均会抛出类型错误 const badCase1: myType<myObject> = { parent: { child: "not a number" // child类型不匹配 }, name: "something", id: "something" } const badCase2: myType<myObject> = { parent: { child: 0 }, name: "invalid value", // name只能传"something" id: "something" }
内容的提问来源于stack exchange,提问作者asnaeb
相关产品推荐
相关产品推荐

