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

TypeScript如何让类型依赖字段值?实现关联类型校验

实现TypeScript中method_type与details的类型关联约束

要让method_type和details的类型严格对应,你可以通过联合类型+交叉类型的方式实现,核心思路是将每种支付方式的专属字段与公共字段绑定,避免类型不匹配的情况。

步骤1:提取公共字段

先把所有支付方式共享的字段抽成一个基础类型:

type BasePaymentMethod = {
  id: string;
  provider: Provider;
  holder_name: string;
  // 这里添加其他公共字段
};

type CardDetails = {
  brand: string;
  last_digits: string;
};

type SepaDetails = {
  last_digits?: string;
};

步骤2:定义绑定专属字段的具体类型

为每种支付方式创建独立类型,将基础类型与对应的method_type、details交叉:

type CardPaymentMethod = BasePaymentMethod & {
  method_type: "card";
  details: CardDetails;
};

type SepaPaymentMethod = BasePaymentMethod & {
  method_type: "sepa";
  details: SepaDetails;
};

步骤3:联合成最终的PaymentMethod类型

将两个具体类型联合,得到最终的约束类型:

type PaymentMethod = CardPaymentMethod | SepaPaymentMethod;

效果验证

此时TypeScript会严格约束method_type和details的对应关系:

  • 当method_type为"card"时,details必须符合CardDetails结构
  • 当method_type为"sepa"时,details必须符合SepaDetails结构

示例:

// 合法:card类型对应正确的details
const validCard: PaymentMethod = {
  id: "card_123",
  provider: "paypal",
  holder_name: "Alice Smith",
  method_type: "card",
  details: {
    brand: "Mastercard",
    last_digits: "5555"
  }
};

// 非法:card类型却使用sepa的details,TypeScript会报错
const invalidPayment: PaymentMethod = {
  id: "sepa_456",
  provider: "stripe",
  holder_name: "Bob Brown",
  method_type: "card",
  details: { // 错误:缺少brand字段
    last_digits: "1234"
  }
};

此外,当你通过条件判断窄化method_type时,details的类型会自动推断为对应类型,无需手动断言:

function processPayment(method: PaymentMethod) {
  if (method.method_type === "card") {
    // 这里method.details自动推断为CardDetails,可以直接访问brand
    console.log(`Card brand: ${method.details.brand}`);
  } else {
    // 这里method.details自动推断为SepaDetails
    console.log(`SEPA last digits: ${method.details.last_digits}`);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:01:07