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

TypeScript中如何限制函数参数为非类实例及非Function类型

解决TypeScript限制函数参数禁止类实例和Function的问题

你的现有代码仅能排除Function类型,但类实例(比如new A())的类型不会匹配Function,因此无法触发编译错误。要同时禁止类实例和Function,可以通过以下两种方式实现:

方案1:精确排除类实例与Function

通过判断类型是否为Function,或是否为某个构造函数的实例(即类实例),来限制参数:

// 定义不允许的类型:Function 或 类实例(构造函数的实例)
type Disallowed = 
  Function | 
  { constructor: new (...args: any[]) => any };

// 输入类型:仅允许非Disallowed的类型
type Input<T> = T extends Disallowed ? never : T;

function saveData<T>(data: Input<T>) {
  // 函数逻辑
}

// 测试用例
class A {}
let foo = new A();
saveData(foo); // ❌ 编译错误:类实例被禁止
saveData(() => {}); // ❌ 编译错误:Function被禁止
saveData({ name: "test", age: 20 }); // ✅ 允许普通对象
saveData([1, 2, "hello"]); // ✅ 允许数组

注意:这个方案会排除所有类实例(包括内置类如Date、RegExp的实例),如果需要允许部分内置类实例,可以在Disallowed中针对性调整排除逻辑。

方案2:限制为JSON可序列化类型

如果你的函数需要处理的是可被JSON序列化的数据(如数字、字符串、普通对象、数组等),直接使用JSON可序列化类型更符合需求,同时自然排除了Function和类实例:

// 定义JSON可序列化类型(递归包含所有合法JSON类型)
type JSONSerializable =
  | string
  | number
  | boolean
  | null
  | undefined
  | JSONSerializable[]
  | { [key: string]: JSONSerializable };

// 输入类型:仅允许JSON可序列化类型
type Input<T> = T extends JSONSerializable ? T : never;

function saveData<T>(data: Input<T>) {
  // 函数逻辑
}

// 测试用例
class A {}
let foo = new A();
saveData(foo); // ❌ 编译错误:类实例不可序列化
saveData(() => {}); // ❌ 编译错误:Function不可序列化
saveData({ name: "test", tags: ["ts", "javascript"] }); // ✅ 允许
saveData(new Date()); // ❌ 编译错误:Date实例不可直接JSON序列化

这个方案更贴合“允许json object等合法数据”的需求,同时从根源上避免了传入会导致函数崩溃的类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:15:39