TypeScript联合类型判别未触发报错问题咨询
TypeScript联合类型未强制关联字段的问题解决
问题根源
你当前的联合类型定义存在漏洞:TypeScript的结构类型系统中,只要对象满足联合类型中某一个成员的所有必填属性,就会被判定为符合该联合类型。{testAttribute: "test", flag: 2}虽然包含flag字段,但它完全满足InputBase的要求(仅需testAttribute),因此TypeScript认为它属于Input类型,不会触发报错。而in操作符是运行时检查,当检测到flag存在时,TypeScript会将类型收窄为InputWithFlag,但实际对象缺少flagInfo,导致运行时输出undefined。
解决方案
修改InputBase类型,明确禁止flag属性(使用never类型),确保只要存在flag,就必须匹配InputWithFlag类型,从而强制要求同时设置flagInfo:
type InputBase = { testAttribute: string; // 禁止flag属性,确保有flag的对象只能归属InputWithFlag flag?: never; }; type InputWithFlag = InputBase & { flag: 2; flagInfo: string }; type Input = InputBase | InputWithFlag; // 此时会触发预期报错:类型 "{ testAttribute: string; flag: 2; }" 中缺少属性 "flagInfo" const testInput: Input = { testAttribute: "test", flag: 2, }; const test = (input: Input) => { if ("flag" in input) { console.log(input.flagInfo); // 类型安全,input此时必然包含flagInfo } };
原理说明
通过给InputBase添加flag?: never,我们告诉TypeScript:InputBase类型的对象不能拥有flag属性(或者说flag只能是undefined且不能显式设置)。当你创建包含flag:2的对象时,它无法匹配InputBase,只能匹配InputWithFlag,而InputWithFlag要求必须存在flagInfo,因此TypeScript会强制你填写该字段,同时in操作符的类型收窄也会准确对应到包含flagInfo的类型。
内容的提问来源于stack exchange,提问作者MWHmann
相关产品推荐
相关产品推荐

