You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:05:17