TypeScript中如何为联合类型成员施加类型约束?
如何在TypeScript中约束联合类型的成员符合指定模板?
要确保联合类型的每个成员都符合指定模板结构,有几种实用的TypeScript类型技巧可以实现编译时检查:
方法一:使用接口继承
如果你的类型可以用接口定义,直接通过继承Template接口来强制结构约束,不符合的定义会直接触发编译错误:
interface Template { x: string; y: { [key: string]: any }; } // 接口B继承Template,自动遵循模板结构 interface B extends Template { x: "test"; // 字符串字面量属于string的子类型,合法 y: { test2: number }; } interface C extends Template { x: "foo"; y: { bar: string }; } // 错误示例:x的类型不符合Template要求,会报错 // interface D extends Template { // x: 123; // } // 联合类型仅包含符合约束的接口 type A = B | C;
方法二:用工具类型验证类型别名
如果必须使用类型别名(而非接口),可以定义一个工具类型来验证目标类型是否符合模板,不符合则返回never触发编译错误:
type Template = { x: string; y: { [key: string]: any } }; // 工具类型:若T符合Template则返回T,否则返回never type EnsureTemplate<T> = T extends Template ? T : never; // 定义类型时通过EnsureTemplate约束 type B = EnsureTemplate<{x: "test", y: {test2: number}}>; type C = EnsureTemplate<{x: "foo", y: {bar: boolean}}>; // 错误示例:x为number不符合模板,会报错 // type D = EnsureTemplate<{x: 123, y: {}}>; type A = B | C;
方法三:直接约束联合类型整体
也可以直接对联合类型A进行约束,确保所有成员都属于Template的子类型:
type Template = { x: string; y: { [key: string]: any } }; type B = {x: "test", y: {test2: number}}; type C = {x: "foo", y: {bar: string}}; // 约束联合类型A必须是Template的子类型,不符合则报错 type A = (B | C) extends Template ? (B | C) : never;
这种方式的好处是不需要逐个约束B、C、D,直接在联合类型层面做检查,但如果联合类型中有不符合的成员,报错信息可能不够直观。
内容的提问来源于stack exchange,提问作者dude
相关产品推荐
相关产品推荐

