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

如何强制TypeScript对扩展创建的对象进行类型检查?

问题原因

TypeScript 对直接编写的对象字面量会触发「额外属性检查」,但对通过展开表达式(...)合并变量得到的对象,不会触发该检查——因为它认为你是有意合并已有变量的属性,而非误写了额外字段。这就是为什么显式添加不存在的字段会报错,但展开其他类型对象不会的原因。

解决方法

以下是几种让 TypeScript 对这种场景执行类型检查的实用方案:

方案1:先合并到变量再赋值

先将合并后的对象赋值给一个变量,让 TypeScript 推导出它的完整类型,再赋值给目标类型变量。此时会触发正常的类型兼容性检查,因为合并后的类型包含目标类型没有的属性,会直接报错:

type TypeA = {
    id: number;
}

type TypeB = {
    name: string;
}

const a: TypeA = { id: 3 };
const b: TypeB = { name: 'my' };

const merged = { ...a, ...b }; // 类型被推导为 TypeA & TypeB
const c: TypeA = merged; // 报错:类型 "TypeA & TypeB" 中属性 "name" 不在类型 "TypeA" 中

方案2:使用辅助函数强制检查

创建一个接受严格符合目标类型参数的辅助函数,传入合并后的对象时,会触发额外属性检查:

type TypeA = {
    id: number;
}

type TypeB = {
    name: string;
}

const a: TypeA = { id: 3 };
const b: TypeB = { name: 'my' };

function strictAssign<T>(obj: T): T {
  return obj;
}

const c = strictAssign<TypeA>({
  ...a,
  ...b,
}); // 报错:对象文字可以只指定已知属性,并且“name”不在类型“TypeA”中

方案3:自定义Exact类型约束

如果需要更严格的类型匹配(确保目标对象没有任何额外属性),可以自定义一个Exact工具类型,强制合并后的类型与目标类型完全一致:

type Exact<T, U> = T extends U ? (U extends T ? T : never) : never;

type TypeA = {
    id: number;
}

type TypeB = {
    name: string;
}

const a: TypeA = { id: 3 };
const b: TypeB = { name: 'my' };

const merged = { ...a, ...b };
const c: Exact<TypeA, typeof merged> = merged; // 报错:类型 "TypeA & TypeB" 不能赋值给类型 "never"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:27:27