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

如何定义匹配常量对象任意值的TypeScript类型?

从常量对象中提取值的字面量类型

给定如下常量:

const beatsByDuration = {
    q: 1,
    h: 2,
    w: 4,
    1: 4 / 1,
    2: 4 / 2,
    4: 4 / 4,
    8: 4 / 8,
    16: 4 / 16,
};

已知以下两种Duration类型等价:

type Duration = 'q' | 'h' | 'w' | '1' | '2' | '4' | '8' | '16';
type Duration = keyof typeof beatsByDuration

需求是定义一个可匹配该对象任意值(1 | 2 | 4 | 0.5 | 0.25)的类型,要求匹配值本身而非宽泛的类型,且对象是常量而非类型。


解决方案

要实现这个需求,核心是让TypeScript保留常量对象的字面量值类型,而非自动拓宽为number类型,具体步骤如下:

  1. 给常量添加as const断言,锁定每个值的字面量类型:
const beatsByDuration = {
    q: 1,
    h: 2,
    w: 4,
    1: 4 / 1,
    2: 4 / 2,
    4: 4 / 4,
    8: 4 / 8,
    16: 4 / 16,
} as const;
  1. 通过索引类型提取所有值的联合字面量类型:
type DurationValue = typeof beatsByDuration[keyof typeof beatsByDuration];

此时DurationValue的类型就是1 | 2 | 4 | 0.5 | 0.25,TypeScript会自动对重复值去重。

特殊情况处理

如果无法修改原常量的定义(比如是外部导入的常量),可以通过条件类型尝试提取值类型,但仅当原常量的类型未被拓宽时有效:

type DurationValue = typeof beatsByDuration extends infer T 
  ? T extends Record<string, infer V> 
    ? V 
    : never 
  : never;

若原常量定义时未加as const,TypeScript已将值类型拓宽为number,则此方式只能得到number类型,因此优先推荐给常量添加as const断言的方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 14:39:52