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

如何区分TypeScript中UserId与CustomerId两种字符串类型ID?

解决TypeScript中字符串类型ID互相兼容的问题

TypeScript的类型别名采用结构类型系统,仅基于string的类型别名会被视为完全兼容,导致不同业务含义的ID可以互相赋值。以下是几种可行的解决方案:

方案一:品牌类型(Tagged Types)

通过给类型添加唯一的虚拟“品牌”属性,让TypeScript识别为不同类型,同时不影响运行时性能。

// 定义带品牌标识的ID类型
export type CustomerId = string & { __brand: 'CustomerId' };
export type UserId = string & { __brand: 'UserId' };

// 工厂函数封装类型断言,避免手动重复编写
export const createCustomerId = (id: string): CustomerId => id as CustomerId;
export const createUserId = (id: string): UserId => id as UserId;

// Customer类定义
export class Customer {
  id: CustomerId;
  userId: UserId;

  constructor(idStr: string, userIdStr: string) {
    this.id = createCustomerId(idStr);
    this.userId = createUserId(userIdStr);
  }
}

// 测试代码
class Test {
  foo() {
    const userId = createUserId("abc123");
    // 此时编译器会抛出错误,符合预期
    this.bar(userId); // 类型错误:无法将类型“UserId”分配给类型“CustomerId”
  }

  bar(customerId: CustomerId) {}
}

方案二:类封装(运行时可区分)

用类包裹字符串值,让每个ID成为类的实例,TypeScript会自动区分类型,同时运行时也能明确识别ID类型。

export class CustomerId {
  constructor(public value: string) {}
}

export class UserId {
  constructor(public value: string) {}
}

export class Customer {
  id: CustomerId;
  userId: UserId;

  constructor(idStr: string, userIdStr: string) {
    this.id = new CustomerId(idStr);
    this.userId = new UserId(userIdStr);
  }
}

// 测试代码
class Test {
  foo() {
    const userId = new UserId("abc123");
    // 编译器报错,符合预期
    this.bar(userId); // 类型错误:无法将类型“UserId”分配给类型“CustomerId”
  }

  bar(customerId: CustomerId) {}
}

方案三:TypeScript 5.0+ 内置品牌类型

如果使用TypeScript 5.0及以上版本,可以使用官方内置的brand关键字,语法更简洁:

export type CustomerId = string & brand "CustomerId";
export type UserId = string & brand "UserId";

// 创建ID实例
const customerId = "customer-uuid-123" as CustomerId;
const userId = "user-uuid-456" as UserId;

// 测试代码
function bar(customerId: CustomerId) {}
bar(userId); // 编译器抛出类型错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:50:00