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

React useState对交叉判别联合类型的类型检查不严格问题

问题:React useState中交叉联合类型的类型检查不严格问题

类型定义

我们定义了一个由两个判别联合类型交叉得到的Errors类型:

type Errors = ({
  err1: false;
} | {
  err1: true;
  msg1: string;
}) & ({
  err2: false;
} | {
  err2: true;
  msg2: string;
})

纯TypeScript环境下的正常表现

在直接声明变量并赋值时,TypeScript会严格检查多余属性,添加不属于Errors的属性会触发IDE错误:

const customError: Errors = {
  err1: false,
  err2: false,
  attributeThatShouldntBeAllowed: 1 // 此处会触发IDE错误
}

React useState中的异常表现

当把Errors作为useState的泛型参数使用时,初始化是正常的:

const [errors, setErrors] = useState<Errors>({
  err1: false,
  err2: false
}) // 初始化符合类型要求,无问题

但调用setErrors时,通过回调返回带有多余属性的对象,却不会触发任何类型错误:

setErrors(prevState => ({
  ...prevState,
  attributeThatShouldntBeAllowed: "lol",
  anotherAttribute: 1
})) // 此处未触发类型错误

相关tsconfig配置

测试沙箱的tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

项目的tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "jsx": "react",
    "allowSyntheticDefaultImports": true,
    "baseUrl": ".",
    "paths": {
      "@domain/*": ["./src/domain/*"],
      "@infra/*": ["./src/infra/*"],
      "@types/*": ["./src/types/*"],
      "@controllers/*": ["./src/controllers/*"]
    }
  },
  "include": ["src", "node_modules"],
}

原因分析

这个现象的核心是TypeScript的多余属性检查规则的适用场景限制:

  1. 直接赋值场景触发严格检查:当你把对象字面量直接赋值给一个显式声明了类型的变量时(比如const customError: Errors = {...}),TypeScript会启动「多余属性检查」,严格禁止添加类型定义中不存在的属性,这是为了帮开发者排查拼写错误或冗余属性。
  2. 函数返回值仅做结构兼容性检查:而setErrors的回调函数返回的对象,属于函数返回值场景,TypeScript只会做结构类型兼容性验证——只要返回的对象包含Errors类型要求的所有必填属性,且属性类型匹配,就认为该对象可以赋值给Errors类型,不会额外检查多余属性。
  3. 交叉联合类型的兼容性特性:你的Errors类型是两个联合类型的交叉,展开后所有可能的成员都只要求err1/err2相关属性,带有多余属性的对象完全满足这些成员的结构要求,因此在结构兼容性检查中会被判定为合法。

简单来说,「多余属性检查」是TypeScript给直接赋值场景加的额外严格校验,而函数返回值走的是常规的结构类型兼容逻辑,不会触发这个额外校验。

内容的提问来源于stack exchange,提问作者Pedro Faria Fernandes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 11:15:37