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

TypeScript模板字面量映射类型:如何排除温度同单位转换?

解决TypeScript模板字面量映射类型中排除同单位转换的问题

你当前的类型定义问题在于,使用[U in ${T}to${T}]时,U是完整的转换键字符串(比如celsius_to_celsius),而非单独的温度单位。这时候用Exclude<T, U>根本不匹配类型,因为U是组合后的字符串,和T的单位类型不属于同一集合,所以无法排除同单位的情况。

正确的类型定义方案

利用TypeScript 4.1+支持的映射类型as子句,分别遍历源单位和目标单位,确保源单位与目标单位不同:

// 补全基础类型(如果未定义)
type TemperatureUnit = 'celsius' | 'farenheit' | 'kelvin';
type ConversionCategoryType = 'temperature';
type ConversionItem<T> = { key: T };

// 修改后的ConversionsOptions类型
type ConversionsOptions<T extends string> = {
  key: ConversionCategoryType;
  items: Array<ConversionItem<T>>;
  formulas: {
    // 遍历每个源单位S,再为每个S生成排除自身后的目标单位D的转换键
    [S in T as `${S}_to_${Exclude<T, S>}`]: (n: number) => number;
  };
};

验证效果

当你使用这个类型定义温度转换对象时:

const temperatureCategory: ConversionsOptions<TemperatureUnit> = {
  key: 'temperature',
  items: [
    { key: 'celsius' },
    { key: 'kelvin' },
    { key: 'farenheit' },
  ],
  formulas: {
    celsius_to_kelvin: (n) => n + 273.15,
    celsius_to_farenheit: (n) => n * (9 / 5) + 32,
    kelvin_to_farenheit: (n) => (n - 273.15) * (9 / 5) + 32,
    kelvin_to_celsius: (n) => n - 273.15,
    farenheit_to_kelvin: (n) => (n - 32) * (5 / 9) + 273.15,
    farenheit_to_celsius: (n) => (n - 32) * (5 / 9),
  },
};
  • TypeScript会自动校验formulas必须包含所有跨单位的转换键,不允许出现同单位的转换键(比如celsius_to_celsius会被类型检查报错)。
  • 如果遗漏任何一个跨单位转换键,TypeScript也会提示类型不匹配,确保转换公式的完整性。

原理说明

这里的核心是拆分了源单位和目标单位的遍历逻辑:

  1. 先遍历每个源单位S(比如celsius);
  2. 对每个S,用Exclude<T, S>排除自身,得到所有可转换的目标单位D;
  3. 通过as ${S}to${D}``将源和目标单位组合成最终的转换键,从而精准生成所有跨单位的转换类型。

内容的提问来源于stack exchange,提问作者Louis Loiseau-Billon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:00:37