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

为何TypeScript映射类型未报错?排除字段仍可赋值

问题原因分析

核心原因是你定义的JsonType<Test>最终等价于空对象类型{},而TypeScript中的{}并非“完全没有任何属性的对象”,它表示“非null/undefined的任意对象”——只要对象不是null或undefined,无论它带有多少额外属性,都符合{}的类型要求。

具体拆解:

  • 你的Test类型仅包含salt和hash两个键,经过Exclude<keyof T, "salt" | "hash">处理后,得到的是空联合类型,因此映射生成的JsonType<Test>就是没有任何属性的{}类型。
  • 在TypeScript的结构类型系统中,{}类型不限制对象拥有额外属性,所以你给testObject赋值包含salt和hash的对象时,不会触发报错。
解决方法:严格禁止额外属性

如果你的目标是彻底禁止对象包含salt和hash字段,可以修改JsonType的定义,添加索引签名来限制额外属性:

type JsonType<T> = Omit<T, "salt" | "hash"> & {
  [key: string]: never;
};

type Test = {
  salt: string;
  hash: string;
};

const testObject: JsonType<Test> = {
  hash: "...", // 触发报错:类型“string”的属性“hash”不能赋给类型“never”的索引签名属性
  salt: "...",
};

这里的{ [key: string]: never }表示:对象不能有任何字符串类型的额外属性,否则会因为属性值类型(比如string)与索引签名要求的never类型不匹配而报错。

补充说明

如果你的Test类型包含其他属性,比如:

type Test = {
  salt: string;
  hash: string;
  username: string;
};

此时JsonType<Test>会是{ username: string },这时候给它赋值包含salt的对象时,TypeScript会触发额外属性检查并报错——只有当目标类型是{}这种无属性定义的空类型时,额外属性才不会被拦截。

内容的提问来源于stack exchange,提问作者Susbakun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:41:11