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

TypeScript中如何类型安全处理含多类型Route的Quote实体?

解决方案:安全处理联合类型的Quote实体

1. 用自定义类型守卫区分路线类型

要安全处理RailRoute和CarRoute的联合类型,最可靠的方式是自定义类型守卫,通过类型谓词让TypeScript自动推断类型,无需手动断言。

先明确基础类型定义:

interface RailRoute {
  type: 'rail';
  trainNumber: string;
  departureStation: string;
}

interface CarRoute {
  type: 'car';
  licensePlate: string;
  driverName: string;
}

type Quote = {
  id: string;
  price: number;
  route: RailRoute | CarRoute;
};

编写类型守卫函数:

// 判断是否为铁路路线
function isRailRoute(route: RailRoute | CarRoute): route is RailRoute {
  return route.type === 'rail';
}

// 判断是否为汽车路线
function isCarRoute(route: RailRoute | CarRoute): route is CarRoute {
  return route.type === 'car';
}

在handleQuote中使用类型守卫:

function handleQuote(quote: Quote) {
  console.log(`报价ID: ${quote.id}, 价格: ${quote.price}`);

  if (isRailRoute(quote.route)) {
    // TypeScript自动推断quote.route为RailRoute,可直接访问专属字段
    console.log(`铁路车次: ${quote.route.trainNumber}, 出发站: ${quote.route.departureStation}`);
  } else if (isCarRoute(quote.route)) {
    // 自动推断为CarRoute,安全访问车牌、司机字段
    console.log(`汽车车牌: ${quote.route.licensePlate}, 司机: ${quote.route.driverName}`);
  } else {
    // 兜底处理,避免未来新增路线类型时出现未覆盖逻辑
    throw new Error(`未知路线类型: ${JSON.stringify(quote.route)}`);
  }
}

2. 优化代码结构:拆分类型处理逻辑

如果handleQuote内逻辑复杂,可将不同路线的处理逻辑拆分为独立函数,提升代码可读性和可维护性:

// 单独处理铁路路线逻辑
function handleRailRoute(route: RailRoute) {
  console.log(`铁路车次: ${route.trainNumber}, 出发站: ${route.departureStation}`);
  // 可添加更多铁路专属业务逻辑
}

// 单独处理汽车路线逻辑
function handleCarRoute(route: CarRoute) {
  console.log(`汽车车牌: ${route.licensePlate}, 司机: ${route.driverName}`);
  // 可添加更多汽车专属业务逻辑
}

function handleQuote(quote: Quote) {
  console.log(`报价ID: ${quote.id}, 价格: ${quote.price}`);

  if (isRailRoute(quote.route)) {
    handleRailRoute(quote.route);
  } else if (isCarRoute(quote.route)) {
    handleCarRoute(quote.route);
  } else {
    throw new Error(`未知路线类型: ${JSON.stringify(quote.route)}`);
  }
}

3. API数据类型安全:无需断言的校验逻辑

从API获取数据时,不能直接通过类型断言强转,需结合运行时校验确保数据符合类型定义,同时让TypeScript自动推断类型。

编写完整的Quote校验函数:

function isValidQuote(data: unknown): data is Quote {
  // 先校验基础结构
  if (typeof data !== 'object' || data === null) return false;
  const quote = data as Quote;
  
  // 校验Quote的基础字段
  if (typeof quote.id !== 'string' || typeof quote.price !== 'number') return false;
  
  // 校验route字段的结构和类型
  const route = quote.route;
  if (typeof route !== 'object' || route === null || !('type' in route)) return false;
  
  // 根据type字段校验对应类型的专属属性
  switch (route.type) {
    case 'rail':
      return typeof route.trainNumber === 'string' && typeof route.departureStation === 'string';
    case 'car':
      return typeof route.licensePlate === 'string' && typeof route.driverName === 'string';
    default:
      return false;
  }
}

在API请求中使用校验:

async function fetchQuote(id: string): Promise<Quote> {
  const response = await fetch(`/api/quotes/${id}`);
  const rawData = await response.json();
  
  if (!isValidQuote(rawData)) {
    throw new Error('API返回的报价数据格式不符合要求');
  }
  
  // 此时rawData已被自动推断为Quote类型,无需任何断言
  return rawData;
}

后续调用fetchQuote后,可直接将结果传入handleQuote,全程无需手动断言类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 10:33:46