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

TypeScript中如何判断Settings类型为BasicAuth还是UserToken?

解决TypeScript联合类型的类型判断问题

针对你的需求,要区分Settings联合类型的三种配置形式,TypeScript提供了多种类型收窄的方式,以下是几种实用方案:

1. 利用in操作符+typeof直接判断

这是最简单的实现方式,无需额外定义函数,直接在构造函数中通过属性存在性和类型判断来收窄类型:

// 明确三种配置的子类型
type UserTokenSettings = {
  userToken: string;
};

type StringAuthSettings = {
  auth: string;
};

type ObjectAuthSettings = {
  auth: {
    username: string;
    password: string;
  };
};

type Settings = UserTokenSettings | StringAuthSettings | ObjectAuthSettings;

class MyWebService {
  constructor(settings: Settings) {
    // 判断是否为带userToken的配置
    if ('userToken' in settings) {
      // 此时TypeScript自动将settings收窄为UserTokenSettings类型
      this.handleUserTokenAuth(settings.userToken);
    } 
    // 判断是否为字符串类型的auth配置
    else if (typeof settings.auth === 'string') {
      // 此时settings被收窄为StringAuthSettings类型
      this.handleStringAuth(settings.auth);
    } 
    // 剩余情况即为对象类型的auth配置
    else {
      // 此时settings被收窄为ObjectAuthSettings类型
      this.handleObjectAuth(settings.auth.username, settings.auth.password);
    }
  }

  private handleUserTokenAuth(token: string) {
    // 处理userToken认证逻辑
  }

  private handleStringAuth(authStr: string) {
    // 处理字符串auth认证逻辑
  }

  private handleObjectAuth(username: string, password: string) {
    // 处理对象auth认证逻辑
  }
}

2. 自定义类型谓词函数

如果需要在多个地方复用类型判断逻辑,可以编写类型谓词函数,明确告知TypeScript当前值所属的子类型:

type UserTokenSettings = { userToken: string };
type StringAuthSettings = { auth: string };
type ObjectAuthSettings = { auth: { username: string; password: string } };
type Settings = UserTokenSettings | StringAuthSettings | ObjectAuthSettings;

// 判断是否为UserTokenSettings类型
function isUserTokenSettings(setting: Settings): setting is UserTokenSettings {
  return 'userToken' in setting;
}

// 判断是否为StringAuthSettings类型
function isStringAuthSettings(setting: Settings): setting is StringAuthSettings {
  return 'auth' in setting && typeof (setting as StringAuthSettings).auth === 'string';
}

// 判断是否为ObjectAuthSettings类型
function isObjectAuthSettings(setting: Settings): setting is ObjectAuthSettings {
  return 'auth' in setting 
    && typeof (setting as ObjectAuthSettings).auth === 'object' 
    && (setting as ObjectAuthSettings).auth !== null;
}

class MyWebService {
  constructor(settings: Settings) {
    if (isUserTokenSettings(settings)) {
      this.handleUserTokenAuth(settings.userToken);
    } else if (isStringAuthSettings(settings)) {
      this.handleStringAuth(settings.auth);
    } else if (isObjectAuthSettings(settings)) {
      this.handleObjectAuth(settings.auth.username, settings.auth.password);
    }
  }

  // 省略处理方法...
}

3. 添加区分属性(最推荐)

给每个子类型添加一个唯一的标识属性(比如type),通过switch-case判断。这种方式可读性最高,类型收窄最明确,尤其适合复杂的联合类型:

// 每个子类型添加type字段作为区分标识
type UserTokenSettings = {
  type: 'userToken';
  userToken: string;
};

type StringAuthSettings = {
  type: 'stringAuth';
  auth: string;
};

type ObjectAuthSettings = {
  type: 'objectAuth';
  auth: {
    username: string;
    password: string;
  };
};

type Settings = UserTokenSettings | StringAuthSettings | ObjectAuthSettings;

class MyWebService {
  constructor(settings: Settings) {
    switch (settings.type) {
      case 'userToken':
        this.handleUserTokenAuth(settings.userToken);
        break;
      case 'stringAuth':
        this.handleStringAuth(settings.auth);
        break;
      case 'objectAuth':
        this.handleObjectAuth(settings.auth.username, settings.auth.password);
        break;
      // TypeScript会自动检查是否覆盖所有联合类型分支,避免遗漏
    }
  }

  // 省略处理方法...
}

这种方式的优势在于,后续新增配置类型时,只需添加对应的子类型和switch分支,TypeScript会自动提示是否有遗漏,类型安全性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 03:42:32