TypeScript:如何根据接口内布尔值控制属性可选性?
实现基于
checkedIn状态的条件必填属性 这个需求刚好可以用TypeScript的**可辨识联合(Discriminated Union)**来完美解决,核心思路是把乘客的两种状态(已登机/未登机)拆分成两个独立的接口,再通过联合类型组合起来:
// 已登机的乘客:checkedIn固定为true,checkedInDate必填 export interface CheckedInPassenger { id: number; name: string; checkedIn: true; checkedInDate: Date; } // 未登机的乘客:checkedIn固定为false,checkedInDate可选 export interface UncheckedInPassenger { id: number; name: string; checkedIn: false; checkedInDate?: Date; } // 最终的Passenger类型是两种状态的联合 export type Passenger = CheckedInPassenger | UncheckedInPassenger;
为什么这个方案可行?
TypeScript会通过checkedIn这个可辨识属性(这里是字面量类型true/false)自动做类型收窄:
- 当你把
checkedIn设为true时,TypeScript会认定这个对象属于CheckedInPassenger类型,此时必须提供checkedInDate,否则会直接报错 - 当你把
checkedIn设为false时,TypeScript会认定这个对象属于UncheckedInPassenger类型,checkedInDate可以省略或者提供
用法示例
// ✅ 合法:已登机状态,提供了必填的checkedInDate const alice: Passenger = { id: 1, name: "Alice Smith", checkedIn: true, checkedInDate: new Date("2024-05-20") }; // ✅ 合法:未登机状态,省略checkedInDate const bob: Passenger = { id: 2, name: "Bob Johnson", checkedIn: false }; // ❌ 不合法:已登机状态但未提供checkedInDate,TypeScript会抛出类型错误 const charlie: Passenger = { id: 3, name: "Charlie Brown", checkedIn: true // 报错:Property 'checkedInDate' is missing in type... };
这种方式既满足了你的业务约束,又能让TypeScript在编译阶段就帮你排查不符合规则的代码,比单一接口的可选属性更严谨。
内容的提问来源于stack exchange,提问作者Nasser Alghamid
相关产品推荐
相关产品推荐

