为何用Exclude实现TypeScript的Required工具类型无法生效?
为什么通过Exclude移除undefined实现Required工具类型不生效?
我们知道TypeScript内置的Required工具类型是通过-?移除可选标记实现的,代码如下:
type Required<T> = { [K in keyof T]-?: T[K] }
因为可选属性的类型实际为类型 | undefined——比如定义接口interface Foo { name?: string }时,Foo['name']的类型是string | undefined,所以自然会想到用Exclude移除undefined来实现自定义的Required,代码如下:
type MyRequired<T> = { [K in keyof T]: Exclude<T[K], undefined> }
但实际这个方案完全不生效,输出类型和原类型T一致,核心原因是可选属性的「可选标记(?)」与属性类型包含undefined是两个独立的概念:
- 当你给属性加上
?时,TypeScript会同时做两件事:- 给属性添加「可选标记」,表示该属性可以不存在于对象实例中
- 在
strictNullChecks开启的前提下,自动把属性类型联合上undefined
- 仅通过
Exclude<T[K], undefined>移除类型里的undefined,只会修改属性的类型约束,但不会移除「可选标记」——属性依然是可选的,所以最终生成的类型和原类型表现完全一致。
举个实际例子验证:
interface Foo { name?: string } type MyRequiredFoo = MyRequired<Foo> // MyRequiredFoo 的类型依然是 { name?: string },可选标记未被移除 type BuiltInRequiredFoo = Required<Foo> // BuiltInRequiredFoo 的类型是 { name: string },-? 直接移除了可选标记
要实现和内置Required完全一致的效果,必须通过-?语法移除属性的可选标记,而不是仅处理类型中的undefined。
内容的提问来源于stack exchange,提问作者z0gSh1u
相关产品推荐
相关产品推荐

