TypeScript联合类型函数参数类型定义问题:访问非共有属性报错
TypeScript联合类型访问非共有属性的解决方法
当使用B | A作为函数参数类型时,TypeScript仅允许访问两个接口共有的profile属性——因为它无法确定传入对象的具体类型是A还是B,直接访问name或title会触发类型错误。以下是几种可行的解决方式:
1. 使用in操作符做类型收窄
直接在函数内通过in操作符判断属性是否存在,TypeScript会自动收窄类型:
interface A { profile: string; name: string; c: number; d: number; } interface B { title: string; profile: string; a: number; b: number; } function abFunc(obj: A | B) { return 'name' in obj ? obj.name : obj.title; }
2. 自定义类型守卫函数
如果需要在多个地方复用类型判断,可以定义类型守卫函数,明确告知TypeScript对象的具体类型:
interface A { profile: string; name: string; c: number; d: number; } interface B { title: string; profile: string; a: number; b: number; } function isA(obj: A | B): obj is A { return 'name' in obj; } function abFunc(obj: A | B) { if (isA(obj)) { return obj.name; } return obj.title; }
3. 类型断言(谨慎使用)
如果你能100%确定传入对象的类型,可以用类型断言绕过TypeScript的类型检查,但这种方式不安全,可能导致运行时错误:
interface A { profile: string; name: string; c: number; d: number; } interface B { title: string; profile: string; a: number; b: number; } function abFunc(obj: A | B) { return (obj as A).name || (obj as B).title; }
4. 判别式联合(修改接口场景)
如果可以修改原有接口,给两个接口添加一个唯一的判别属性,TypeScript会根据该属性自动收窄类型,这是最严谨的方式:
interface A { type: 'A'; // 判别属性,值为唯一字符串 profile: string; name: string; c: number; d: number; } interface B { type: 'B'; // 判别属性,值为唯一字符串 title: string; profile: string; a: number; b: number; } function abFunc(obj: A | B) { switch (obj.type) { case 'A': return obj.name; case 'B': return obj.title; } }
内容的提问来源于stack exchange,提问作者pvp11
相关产品推荐
相关产品推荐

