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

TypeScript限制函数参数为特定类类型,禁止子类传入

限制TypeScript函数参数仅接受“纯”A类型实例

问题场景

我定义了如下TypeScript代码,其中函数foo接受类型为A的参数:

export function foo<T extends A>(arg: A) {
  console.log(arg.propA);
  // do something with arg
  return arg as unknown as A & B & T;
}

class A {
  propA: string;
  constructor() {
    this.propA = "A";
  }
}

class B extends A {
  propB: string;
  constructor() {
    super();
    this.propB = "B";
  }
}

class C {
  propC: string;
  constructor() {
    this.propC = "C";
  }
}

在调用foo时,我希望第二个调用能触发静态TypeScript错误:

const processedA = foo(new A()); // 正常,符合预期

foo(processedA); // 当前无错误,但需要触发错误

foo(new C()); // 已按预期报错,符合要求

我的思路是判断参数是否包含A定义之外的额外属性,但不知道如何实现。

解决方案

可以通过定义精确类型约束来实现这个需求,确保传入foo的参数类型只能是严格的A,不能包含任何额外属性或被断言为包含额外属性的类型。

修改后的代码

// 定义精确类型检查工具:确保U的属性完全匹配T,无额外键
type Exact<T, U> = U extends T 
  ? Exclude<keyof U, keyof T> extends never 
    ? U 
    : never 
  : never;

export function foo<T extends A>(arg: Exact<A, T>) {
  console.log(arg.propA);
  // do something with arg
  return arg as unknown as A & B & T;
}

class A {
  propA: string;
  constructor() {
    this.propA = "A";
  }
}

class B extends A {
  propB: string;
  constructor() {
    super();
    this.propB = "B";
  }
}

class C {
  propC: string;
  constructor() {
    this.propC = "C";
  }
}

效果验证

const processedA = foo(new A()); // 正常,符合预期

foo(processedA); // 触发TypeScript错误:类型"A & B & A"的参数不能赋给类型"never"的参数

foo(new C()); // 触发TypeScript错误:类型"C"的参数不能赋给类型"never"的参数

原理说明

  • Exact<T, U>类型会先检查U是否继承自T,再判断U是否包含T之外的额外属性:
    1. 如果U不是T的子类型,直接返回never,参数类型不匹配报错;
    2. 如果U是T的子类型,但包含T之外的键,同样返回never,触发错误;
    3. 只有当U的属性完全和T一致时,才返回U,允许正常调用。

这样就实现了仅接受“纯”A类型实例的需求,同时保留对C类型的原有错误校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:45:18