如何移除TypeScript属性的可选性与undefined联合类型?
问题:启用exactOptionalPropertyTypes时,Required与NonNullable组合无法消除属性的undefined类型?
代码示例
type A = { b?: number | undefined; } const a: NonNullable<Required<A>> = { b: 0, }; a.b++;
触发的TSC错误
TS18048: 'a.b' is possibly 'undefined'.
详细错误信息
return new TSError(diagnosticText, diagnosticCodes, diagnostics); ^ TSError: ⨯ Unable to compile TypeScript: project/src/test.ts:9:1 - error TS2532: Object is possibly 'undefined'. 9 a.b++; ~~~
该问题仅在启用exactOptionalPropertyTypes编译选项时出现。
原本预期Required<A>会把可选属性转为必填,再结合NonNullable能确保b始终是已定义的number类型,但实际仍会触发"可能为undefined"的错误。如何实现让b类型确定为非undefined的目标?
解决方案
问题根源在于:
Required<A>仅移除属性的可选标记(?),不会修改属性的类型,所以Required<A>的类型是{ b: number | undefined };NonNullable<T>的作用是移除整个类型T的null和undefined,但不会深入处理属性内部的undefined类型。
要实现每个属性必填且非空的效果,需要自定义一个工具类型,同时处理属性的可选性和内部的null/undefined:
// 自定义工具类型:将所有属性转为必填,且移除属性类型中的null/undefined type RequiredNonNullable<T> = { [K in keyof T]-?: NonNullable<T[K]>; };
修改代码使用该类型后,错误即可消除:
type A = { b?: number | undefined; } const a: RequiredNonNullable<A> = { b: 0, }; a.b++; // 正常编译,无错误
这个工具类型通过映射类型实现:
[K in keyof T]遍历所有属性;-?移除属性的可选标记,等同于Required的功能;NonNullable<T[K]>移除属性类型中的null和undefined。
内容的提问来源于stack exchange,提问作者Rodrigo Sasaki
相关产品推荐
相关产品推荐

