为什么TypeScript条件对象中的never类型需要搭配问号使用
问题解答
疑问1:为什么此处必须添加问号,isDirty: never的写法基本不可用?
TypeScript 中对象类型的属性默认是必填的,该规则和属性的类型无关:只要你没有给属性加可选标识?,不管属性定义的类型是什么,实例化对象时都必须显式声明该属性并赋值。
而never是 TypeScript 的底类型,不存在任何符合never类型的有效值,如果你把属性定义为必填的isDirty: never,就意味着你必须给isDirty传一个不存在的有效值,这个要求永远无法被满足,对应类型也就无法实例化,必然会报错。
至于你测试的isDirty: never | undefined写法报错,原因也是你仍然把isDirty定义成了必填属性,哪怕允许赋值为undefined,也要求你必须显式写isDirty: undefined,不能直接省略该字段,不符合你“id为number类型时不能添加isDirty字段”的需求。
疑问2:为什么?和never搭配使用时,表现和搭配普通类型不同?
首先先明确可选属性?: T的通用规则:不管T是什么类型,?:都代表两层含义:
- 实例化时可以完全省略该属性
- 如果显式声明该属性,值的类型必须符合
T | undefined
当T是普通类型比如string时,a?: string的表现就是你可以省略a,也可以写a为字符串或undefined,和你的认知一致。
当T是never时,isDirty?: never的两层含义就变成了:
- 可以省略
isDirty属性(符合id为number时不需要该字段的要求) - 如果显式声明
isDirty,值必须是never | undefined——但never不存在有效值,你最多只能写isDirty: undefined,如果 tsconfig 开启了exactOptionalPropertyTypes配置,连undefined都不允许传,最终效果就是完全禁止显式声明isDirty字段,刚好匹配你的需求。
这就是?搭配never和普通类型的差异:普通类型的可选属性是“可省略,写了也允许合法值”,never的可选属性是“可省略,写了就没有合法值,等于禁止写”。
内容的提问来源于stack exchange,提问作者Andru
相关产品推荐
相关产品推荐

