如何使用交叉类型实现TypeScript中对象属性访问的正确类型检查?
解决TypeScript类型关联问题的可扩展方案
你的代码里TypeScript报错的核心原因是:它没办法自动把letter.type的字面量类型和letter的具体结构类型关联起来,导致调用Result(letter)时,参数类型被缩小到never。
下面是两种不需要写分支判断、具备扩展性的解决方案:
方案一:泛型函数(推荐)
通过泛型约束,让TypeScript精准推断letter类型和对应处理函数的参数类型,完全不需要手动分支:
const a = { type: "a", original: "a", } as const const b = { type: "b", extra: "b", } as const const letters = { a, b, } as const type Letters = typeof letters // 提取所有合法的type值 type LetterType = keyof Letters const Comp = { a: (a: typeof letters.a) => console.log(a.original), b: (b: typeof letters.b) => console.log(b.extra), } // 泛型T绑定type的具体值,同时约束letter为对应类型 function log<T extends LetterType>(letter: Letters[T]) { const handler = Comp[letter.type] handler(letter) // 类型校验完全通过 } // 测试调用 log(a) log(b)
后续新增类型(比如c)时,只需要在letters和Comp里添加对应的对象和处理函数,log函数不需要任何修改,扩展性拉满。
方案二:类型断言快速修复
如果不想改动函数的参数定义,可以用类型断言明确处理函数的参数类型,但这种方式是绕过TypeScript的自动推断,不如泛型方案严谨:
function log(letter: Letters[keyof Letters]) { const handler = Comp[letter.type] as (arg: typeof letter) => void handler(letter) }
内容的提问来源于stack exchange,提问作者Lino Rabolini
相关产品推荐
相关产品推荐

