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

如何让TypeScript识别合法参数必然能在不可变二维数组中找到结果?

问题:让TypeScript自动识别合法参数必然匹配数组项,无需处理undefined

首先是原代码实现:

class Constants {
    static readonly STATES_AND_ACRONYMS = [
        ["AA", "NAME_A"],
        ["BB", "NAME_B"],
        ["CC", "NAME_C"],
        ["DD", "NAME_D"],
        ["EE", "NAME_E"],
        ["FF", "NAME_F"],
    ] as const;
}

type Acronym = typeof Constants.STATES_AND_ACRONYMS[number][0];
type State = typeof Constants.STATES_AND_ACRONYMS[number][1];

function getStateByAcronym(acronym : Acronym) : State{
    let entry = Constants.STATES_AND_ACRONYMS.find((entry) => entry[0]==acronym)
    if(entry == undefined){
        //impossible
        return Constants.STATES_AND_ACRONYMS[0][1];
    }

    return entry[1];
}

function getAcronymByState(state : State) : Acronym{
    let entry = Constants.STATES_AND_ACRONYMS.find((entry) => entry[1]==state)
    if(entry == undefined){
        //impossible
        return Constants.STATES_AND_ACRONYMS[0][0];
    }
    return entry[0];
}

我定义了存储州名及其唯一缩写的不可变二维数组,基于该数组生成了Acronym和State类型。实现的两个函数分别通过缩写获取州名、通过州名获取缩写——因为参数是基于数组生成的合法类型,完全可以保证对应项一定存在,但TypeScript的find方法仍会返回可能的undefined,必须额外处理。我希望编写代码让TypeScript自动识别合法参数必然能找到匹配项,无需处理undefined,而且不想用类型断言或自定义循环来规避这个问题。


解决方案:预先生成只读映射对象

核心思路是基于原数组创建对应的只读映射对象,让TypeScript直接推断出键与值的必然对应关系,避免find方法带来的undefined问题。

class Constants {
    static readonly STATES_AND_ACRONYMS = [
        ["AA", "NAME_A"],
        ["BB", "NAME_B"],
        ["CC", "NAME_C"],
        ["DD", "NAME_D"],
        ["EE", "NAME_E"],
        ["FF", "NAME_F"],
    ] as const;

    // 生成缩写到州名的只读映射
    static readonly ACRONYM_TO_STATE = Object.fromEntries(
        Constants.STATES_AND_ACRONYMS
    ) as Readonly<{
        [K in typeof Constants.STATES_AND_ACRONYMS[number][0]]: typeof Constants.STATES_AND_ACRONYMS[number][1]
    }>;

    // 生成州名到缩写的只读映射
    static readonly STATE_TO_ACRONYM = Object.fromEntries(
        Constants.STATES_AND_ACRONYMS.map(([acronym, state]) => [state, acronym])
    ) as Readonly<{
        [K in typeof Constants.STATES_AND_ACRONYMS[number][1]]: typeof Constants.STATES_AND_ACRONYMS[number][0]
    }>;
}

// 直接从映射对象的键类型生成,更直观
type Acronym = keyof typeof Constants.ACRONYM_TO_STATE;
type State = keyof typeof Constants.STATE_TO_ACRONYM;

function getStateByAcronym(acronym: Acronym): State {
    // TypeScript可直接推断该键必然存在,无undefined风险
    return Constants.ACRONYM_TO_STATE[acronym];
}

function getAcronymByState(state: State): Acronym {
    return Constants.STATE_TO_ACRONYM[state];
}

方案说明

  1. 映射对象的安全性:Object.fromEntries基于原不可变数组生成映射,配合类型断言明确键值对应关系——这个断言是完全安全的,因为原数组的缩写和州名是一一对应的唯一关系。
  2. TypeScript类型推断:通过对象属性访问时,TypeScript能识别到Acronym类型的参数必然是ACRONYM_TO_STATE的合法键,因此直接返回对应值,不会出现undefined。
  3. 保持不可变性:用Readonly包裹映射对象,和原数组的只读特性保持一致,避免意外修改。

内容的提问来源于stack exchange,提问作者Rafael Santiago Altoé

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 21:35:02