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

TypeScript 联合类型访问属性报不存在错误,如何让TS正确识别?

报错原因

TypeScript 对联合类型默认只允许访问所有类型成员共有的属性,placeName、postalCode 是 AddressBookingStop 独有的属性,place_name、postal_code 是 ShowBookingStop 独有的属性,所以直接访问会触发类型错误,和运行时的兼容逻辑无关。

解决方案

以下是几种常用的修复方案:

  • 方案1:使用in运算符做类型收窄(推荐)
    TS 原生支持识别in运算符的判断逻辑,自动收窄联合类型,无额外运行时代码,类型安全:

    function formatAddress(stop: AddressBookingStop|ShowBookingStop): string {
        const place = 'placeName' in stop ? stop.placeName : stop.place_name;
        let address = [stop.street || place, stop.city, stop.province].filter(s => s).join(', ');
        const postalCode = 'postalCode' in stop ? stop.postalCode : stop.postal_code;
        if (postalCode) {
            address += ` ${postalCode}`;
        }
        return address;
    }
    
  • 方案2:自定义类型守卫
    如果多处需要判断这两个类型,可以抽成可复用的类型守卫函数:

    function isAddressBookingStop(stop: AddressBookingStop|ShowBookingStop): stop is AddressBookingStop {
        return 'placeName' in stop;
    }
    
    function formatAddress(stop: AddressBookingStop|ShowBookingStop): string {
        const place = isAddressBookingStop(stop) ? stop.placeName : stop.place_name;
        let address = [stop.street || place, stop.city, stop.province].filter(s => s).join(', ');
        const postalCode = isAddressBookingStop(stop) ? stop.postalCode : stop.postal_code;
        if (postalCode) {
            address += ` ${postalCode}`;
        }
        return address;
    }
    
  • 方案3:类型断言(快速修复)
    如果你确认逻辑没有问题,可以用类型断言绕过校验,改造成本最低:

    function formatAddress(stop: AddressBookingStop|ShowBookingStop): string {
        let address = [stop.street || (stop as AddressBookingStop).placeName || (stop as ShowBookingStop).place_name, stop.city, stop.province].filter(s => s).join(', ');
        const postalCode = (stop as AddressBookingStop).postalCode || (stop as ShowBookingStop).postal_code;
        if (postalCode) {
            address += ` ${postalCode}`;
        }
        return address;
    }
    
  • 方案4:定义统一兼容类型
    如果多个函数都需要处理这两种类型,可以预先定义包含所有可能属性的类型,原有逻辑不用修改:

    type UnifiedBookingStop = (AddressBookingStop | ShowBookingStop) & {
        placeName?: string;
        place_name?: string;
        postalCode?: string;
        postal_code?: string;
    }
    
    function formatAddress(stop: UnifiedBookingStop): string {
        let address = [stop.street || stop.placeName || stop.place_name, stop.city, stop.province].filter(s => s).join(', ');
        const postalCode = stop.postalCode || stop.postal_code;
        if (postalCode) {
            address += ` ${postalCode}`;
        }
        return address;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:18:02