TS接口如何实现仅特定场景下字段必填:以订单接口为例
实现方案
你可以通过 TypeScript 的可辨识联合类型满足需求,具体实现如下:
步骤说明
- 抽离所有订单通用的公共字段,避免重复定义
- 分别定义两类订单的类型,将
product字段设为固定字面量类型作为类型辨识标识 - 其他类型订单额外声明
title?: never,确保该场景下不能出现title字段 - 用联合类型(
|)合并两类订单,不要用接口继承(extends会强制合并所有属性,不符合需求)
完整代码
type productType = "book" | "pen" | "notebook" // 抽离所有订单通用的公共字段 interface IBaseOrder { amount: number, productCode: number, description: string } // 图书订单:product固定为book,title必填 interface IBookOrder extends IBaseOrder { product: "book", title: string } // 其他订单:product为排除book的枚举值,不允许出现title字段 interface IOtherOrder extends IBaseOrder { product: Exclude<productType, "book">, title?: never } // 用联合类型合并得到通用订单类型 type IOrderValues = IBookOrder | IOtherOrder // 测试1:pen订单传title会触发TS报错 const penOrder: IOrderValues = { product: "pen", amount: 5, description: "ink pen", productCode: 123, title: "This should not be allowed" // 报错:不能将类型“string”分配给类型“undefined” } // 测试2:book订单必须传title,否则报错 const bookOrder: IOrderValues = { product: "book", amount: 15, description: "Awesome TS book", productCode: 321, title: "Typescript 101" // 合法 }
校验逻辑说明
- 当
product值为"book"时,TS会自动匹配到IBookOrder类型,强制要求传入title字段 - 当
product值为"pen"/"notebook"时,TS匹配到IOtherOrder类型,只要传入title就会触发类型错误,完全符合需求
内容的提问来源于stack exchange,提问作者ankitm
相关产品推荐
相关产品推荐

