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

如何让TypeScript检测函数传入参数属性过多的错误?

TypeScript 严格类型校验:禁止传入含额外属性的参数

TypeScript 默认采用结构子类型规则:只要传入的参数包含目标类型的所有必填属性,即便有额外属性也不会触发类型错误。比如你给出的例子里,Type1 是 Type2 的超集,直接传入 foo 不会报错;用 Omit 生成的类型也存在同样问题。

要实现「严格校验,禁止额外属性」的需求,可以用以下两种方案:

方案一:自定义精确类型工具

通过 Exact 工具类型强制传入的类型与目标类型完全匹配,不允许有任何额外或缺失的属性:

interface Type1 {
  property1: string;
  property2: string;
}

interface Type2 { 
  property1: string;
};

// 精确类型工具:仅当 T 和 U 完全一致时才通过校验
type Exact<T, U> = T extends U ? U extends T ? T : never : never;

// 用泛型约束参数必须严格匹配 Type2
function myFunction<T extends Type2>(params: Exact<T, Type2>) {
  console.log(params);
}

const foo: Type1 = {
  property1: 'foo1',
  property2: 'foo2',
};

myFunction(foo); // ❌ 类型错误:Type1 包含额外属性 property2,与 Type2 不匹配

方案二:通过 never 约束禁止额外属性

给目标类型添加「所有非指定属性必须为 never」的交叉类型,直接阻断超集类型的传入:

interface Type1 {
  property1: string;
  property2: string;
}

interface Type2 { 
  property1: string;
};

// 生成严格版 Type2:禁止任何未定义的额外属性
type StrictType2 = Type2 & {
  [K in Exclude<keyof any, keyof Type2>]?: never;
};

function myFunction(params: StrictType2) {
  console.log(params);
}

const foo: Type1 = {
  property1: 'foo1',
  property2: 'foo2',
};

myFunction(foo); // ❌ 类型错误:property2 的类型 string 与 never 不兼容

针对 Omit 生成的类型

如果是用 Omit 生成的类型,同样可以套用上述方案:

interface Type1 {
  property1: string;
  property2: string;
}

// 用 Omit 生成基础类型
type Type2 = Omit<Type1, 'property2'>;
// 转为严格类型
type StrictType2 = Type2 & {
  [K in Exclude<keyof any, keyof Type2>]?: never;
};

function myFunction(params: StrictType2) {
  console.log(params);
}

const foo: Type1 = {
  property1: 'foo1',
  property2: 'foo2',
};

myFunction(foo); // ❌ 触发类型错误

原理说明

TypeScript 的结构子类型规则允许超集类型赋值给子集类型,而上述方案通过以下逻辑打破这个规则:

  1. Exact 类型通过双向约束,确保传入类型和目标类型的属性完全一致;
  2. never 约束则直接禁止任何未在目标类型中定义的属性存在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:26:37