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

如何定义支持typeof与instanceof混合的多类型Type Guard函数?

实现结合typeof与instanceof的多类型守卫函数

要实现同时支持原始类型(通过typeof字符串)和对象类型(通过构造函数)的多类型检查守卫,需要结合类型映射、实例类型提取和函数重载来完成,具体实现如下:

1. 定义核心类型映射与工具类型

首先创建类型映射表,将typeof返回的字符串类型对应到TypeScript的实际类型;同时定义工具类型提取构造函数的实例类型:

// 映射typeof字符串到对应TypeScript类型
type PrimitiveTypeMap = {
  string: string;
  number: number;
  boolean: boolean;
  symbol: symbol;
  undefined: undefined;
  function: Function;
  object: object;
};

// 提取构造函数的实例类型
type InstanceType<T> = T extends new (...args: any[]) => infer R ? R : never;

2. 实现函数重载与逻辑

通过函数重载分别处理单个类型、多个类型的情况,确保TypeScript能正确推断类型:

// 重载1:检查单个原始类型(传入typeof字符串)
function isType<T extends keyof PrimitiveTypeMap>(obj: any, type: T): obj is PrimitiveTypeMap[T];
// 重载2:检查单个对象类型(传入构造函数)
function isType<T extends new (...args: any[]) => any>(obj: any, type: T): obj is InstanceType<T>;
// 重载3:检查多个类型(支持混合原始类型和对象类型)
function isType<T extends (keyof PrimitiveTypeMap | new (...args: any[]) => any)[]>(
  obj: any,
  ...types: T
): obj is T[number] extends keyof PrimitiveTypeMap 
  ? PrimitiveTypeMap[T[number]] 
  : InstanceType<T[number]>;

// 函数实现
function isType(obj: any, ...types: any[]): boolean {
  for (const type of types) {
    // 处理原始类型检查
    if (typeof type === 'string') {
      if (typeof obj === type) return true;
    } 
    // 处理对象类型的instanceof检查
    else if (typeof type === 'function') {
      if (obj instanceof type) return true;
    }
  }
  return false;
}

3. 使用示例

完全匹配你需求的使用场景:

function doSomething(value: any) {
  let str: string = "";
  let num: number = 0;
  let date: Date | null = null;

  // 检查单个原始类型
  if (isType(value, "string")) {
    str = value; // TypeScript自动推断value为string
  }
  if (isType(value, "number")) {
    num = value; // 自动推断为number
  }

  // 检查对象类型
  if (isType(value, Date)) {
    date = value; // 自动推断为Date
  }

  // 多类型联合检查
  if (isType(value, "number", Date)) {
    // 这里value的类型被推断为number | Date
    if (isType(value, "number")) {
      date = new Date(date!.getTime() + value);
    } else {
      date = value;
    }
  }
}

为什么之前的泛型实现不生效?

你之前尝试的function typeof<K>(obj: any, type: K): obj is K存在问题:当传入Date时,K会被推断为构造函数类型DateConstructor,而不是实例类型Date。通过InstanceType工具类型可以从构造函数中提取出实际的实例类型,解决这个类型推断偏差的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:10:33