TypeScript开启strictNullChecks后Required<T>未移除属性的| undefined问题
问题:Required未移除属性类型中的undefined
我开启了strictNullChecks模式,根据TypeScript文档,同态映射类型移除属性的?修饰符时会同时移除类型中的undefined,因此我认为Required<T>会自动去掉所有属性类型里的| undefined。但实际测试发现,Required<T>仅移除了属性的?修饰符,并没有剔除类型中的undefined。
示例复现
interface Entity1 { optionalVal?: string | undefined; } type CompleteEntity1 = Required<Entity1>
VSCode提示的CompleteEntity1类型为:
type CompleteEntity1 = { optionalVal: string | undefined; }
因此以下代码不会触发错误:
const testCompleteEntity1: CompleteEntity1 = { optionalVal: undefined // 无错误提示 }
原因解析
TypeScript内置的Required<T>实现仅通过-?语法移除属性的可选修饰符,并不会主动处理属性类型中显式声明的| undefined。虽然在strictNullChecks模式下,可选属性会隐式带上| undefined,但如果属性类型里手动写了| undefined,Required<T>不会剔除这部分——它只负责修改属性的可选状态,不修改属性的显式类型定义。
解决方案:自定义RequiredAndDefined
可以通过结合Exclude工具类型,实现同时移除可选修饰符和类型中的null/undefined:
type RequiredAndDefined<T> = { [P in keyof T]-?: Exclude<T[P], null | undefined> }
使用示例
interface Entity2 { optionalVal?: string | undefined | null; } type CompleteEntity2 = RequiredAndDefined<Entity2> // 符合预期:原可选属性可赋值undefined const testEntity2: Entity2 = { optionalVal: undefined } // 符合预期:转换后的必填属性不能赋值undefined或null,触发报错 const testCompleteEntity2: CompleteEntity2 = { optionalVal: undefined // 此处报错 }
当前tsconfig.json配置
{ "extends": "@tsconfig/node16-strictest/tsconfig.json", "compilerOptions": { "outDir": "./dist/", "lib": ["es2022"], "noPropertyAccessFromIndexSignature": false, "resolveJsonModule": true, "strictNullChecks": true } }
内容的提问来源于stack exchange,提问作者andymel
相关产品推荐
相关产品推荐

