为什么TypeScript未对不符合RuntimeEvent类型的入参抛出编译错误
问题原因分析
这个现象是TypeScript两个核心类型校验规则共同作用的结果:
- TypeScript默认允许对象携带类型定义中未声明的额外属性,只有触发多余属性校验时才会对额外属性做限制。
- 当目标类型为联合类型时,只要某个属性存在于联合类型的任意一个分支的定义中,TypeScript就不会将该属性判定为多余属性,不会触发多余属性校验。
我们可以拆解类型匹配逻辑验证:
- 先拆分
RuntimeEvent的两个联合分支:- 分支1:
FreeLog & UndefinedTask,该分支的必填约束只有message: string | Error,且task只能为undefined(可以省略不写),没有对type字段做任何限制。 - 分支2:
TaskEvent,三个子类型均要求type和task为必填属性。
- 分支1:
- 传入的
{ message: "bar", type: "log" }完全满足分支1的所有必填约束:有符合类型要求的message,没有task字段符合要求。 - 携带的
type字段属于联合类型分支2中声明的属性,不会被判定为多余属性,因此不会触发多余属性校验报错。 - 联合类型只要匹配任意一个分支就判定为合法,不需要同时满足所有分支的要求,因此最终不会触发编译报错。
如果要达到预期的校验效果,可以给分支1补充type?: undefined的约束,限制该分支不能出现type属性:
type RuntimeEvent = (FreeLog & UndefinedTask & { type?: undefined }) | TaskEvent;
修改后传入测试对象就会触发预期的编译错误。
内容的提问来源于stack exchange,提问作者areller
相关产品推荐
相关产品推荐

