TypeScript:针对联合类型抑制 "Property does not exist on type"

标签 typescript

interface AddressBookingStop {
    street: string
    placeName: string
    city: string
    province: string
    postalCode: string
}

interface ShowBookingStop {
    id: number;
    city: string;
    postal_code: string;
    place_name: string;
    province: string;
    street: string;
    segment_id: number;
    order: number;
}

function formatAddress(stop: AddressBookingStop|ShowBookingStop): 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;
}

playground

TypeScript 正在提示:

enter image description here

但是我有 stop.placeName || stop.place_name 在那里,所以这两个属性之一保证存在。

有什么办法让TS明白这一点吗?

最佳答案

TypeScript 不允许您访问不是 100% 存在的值的属性。

如果您只想抑制该行上的所有警告,可以使用 //@ts-ignore 注释 introduced in TS 2.6 .

如果您想要一种不那么暴力的方法来使编译器沉默,您可以通过转换为相应的类型来假装拥有您并不真正拥有的信息:

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;
}

如果你想让编译器 super 快乐而不作弊(但遗憾的是以一些运行时逻辑为代价),你可以使用像这样的手动类型保护器:


function isShowBookingStop(stop: AddressBookingStop|ShowBookingStop): stop is ShowBookingStop {
    return Boolean((stop as ShowBookingStop).id);
}

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

stop 的返回值是 ShowBookingStop 告诉编译器,如果返回值为 true,则输入的类型为 ShowBookingStop。然后,您可以在 formatAddress 函数中使用该信息来确定要使用哪个属性。请注意,三元运算符的 falsy 分支中也会有自动完成功能,因为编译器会理解,如果停靠点不是 ShowBookingStop,则它必须是 AddressBookingStop >.

您使用哪些选项完全取决于您!

关于TypeScript:针对联合类型抑制 "Property does not exist on type",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69059418/

相关文章:

javascript - 使用扩展运算符更新包含对象的数组

javascript - 如何在 FormControl 中使用 mat-slide-toggle?

typescript - async/await 语法在 TypeScript 中如何工作?

typescript - "name ' 大小 ' does not exist in the current scope"即使我 've referenced it and it isn' t 突出显示?

html - 具有相同颜色但具有不同不透明度的对象

javascript - 在 PrimeNg 表中同时使用复选框选择和行选择

typescript - 排除/覆盖 npm 提供的类型

typescript - 在 typescript 中导入函数

javascript - 使用Google protobuf时,如何调用 “System.register()”模块中捕获的javascript函数(由 typescript 生成)?

TypeScript:输入具有不同返回类型的 httprequest