TypeScript中如何访问传入函数的联合类型字段?
TypeScript联合类型索引报错解决
我是TypeScript新手,正在通过编写代码学习它。尝试了以下代码,但无法访问传入函数的类型字段:
interface Overview1 { name: string; family: string; } interface Overview2 { name: string; storage: string; } type OverView = Overview1 | Overview2; function LogKeyValuePair(data: OverView) { const keys : string[] = Object.keys(data); keys.forEach((key) => { console.log(data[key]) }) } const o2 = { name: "john", storage: "10 gb" } LogKeyValuePair(volume) // 注:此处变量名错误,应为o2
报错信息
错误出现在console.log(data[key])行,提示:
元素隐式拥有'any'类型,因为类型为'string'的表达式不能用于索引类型'OverView'。在类型'OverView'上未找到具有类型为'string'的参数的索引签名。
问题原因
TypeScript的联合类型OverView由Overview1和Overview2组成,两者的键并不完全一致(family和storage是各自独有的)。而Object.keys()返回的是string[]类型,TypeScript无法确定每个key到底属于哪个联合类型的合法键,因此抛出索引类型不匹配的错误。
解决方法
方法一:类型断言(简单直接)
将key断言为联合类型的合法键,让TypeScript确认索引的合法性:
function LogKeyValuePair(data: OverView) { const keys : string[] = Object.keys(data); keys.forEach((key) => { console.log(data[key as keyof OverView]) }) }
keyof OverView会生成联合类型的所有键:"name" | "family" | "storage",断言后TypeScript能正确识别索引的有效性。
方法二:类型守卫(严谨类型检查)
如果需要更严格的类型校验,可以用类型守卫缩小data的类型范围:
function LogKeyValuePair(data: OverView) { const keys : string[] = Object.keys(data); keys.forEach((key) => { if ("family" in data) { console.log(data[key as keyof Overview1]) } else { console.log(data[key as keyof Overview2]) } }) }
方法三:添加索引签名(不推荐)
如果不在意类型精确性,可以给接口添加字符串索引签名,但这样会丢失TypeScript的类型检查优势:
interface Overview1 { name: string; family: string; [key: string]: string; } interface Overview2 { name: string; storage: string; [key: string]: string; }
额外修正
代码中还有一处变量名错误:LogKeyValuePair(volume)应该改为LogKeyValuePair(o2),因为定义的变量是o2而非volume。
内容的提问来源于stack exchange,提问作者Md Sohail
相关产品推荐
相关产品推荐

