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

TypeScript中如何指定函数接收并返回特定字符串?代码疑问解析

解析你的TypeScript语言码转换代码

现有代码的工作原理拆解

逐行解析代码逻辑:

  • const Locales = { en_gb: 'en-gb', en_us: 'en-us' } as const
    加as const后,TypeScript会将这个对象锁定为只读字面量类型,不会把属性值宽泛推断为string,而是保留具体的字符串值('en-gb'、'en-us'),同时属性键也固定为'en_gb'、'en_us'。

  • type ApiLocales = typeof Locales[keyof typeof Locales]
    keyof typeof Locales 获取Locales的所有键(联合类型 'en_gb' | 'en_us'),再用这个键索引typeof Locales,得到对应的值类型——也就是API端使用的语言码:'en-gb' | 'en-us'。

  • type DatabaseLocales = keyof typeof Locales
    直接取Locales的键类型,即数据库端接受的语言码:'en_gb' | 'en_us'。

  • 函数定义的问题
    你写的返回类型DatabaseLocales[ApiLocales]是错误的:DatabaseLocales是联合类型,不能用另一个联合类型去索引它,TypeScript会直接报错。虽然函数内部的对象映射逻辑在运行时可行,但类型注解不合法,无法起到类型校验作用。

修正后的可行代码

通过创建反向映射对象并推导类型,让类型注解和逻辑统一:

const Locales = {
  en_gb: 'en-gb',
  en_us: 'en-us',
} as const;

// API语言码类型
type ApiLocales = typeof Locales[keyof typeof Locales];
// 数据库语言码类型
type DatabaseLocales = keyof typeof Locales;

// 创建反向映射对象,让TypeScript自动推导其类型
const ApiToDbMap = {
  'en-gb': 'en_gb',
  'en-us': 'en_us',
} as const;

// 参数和返回类型精准对应,编译时自动校验
function databaseLanguageCodeFromString(languageString: ApiLocales): typeof ApiToDbMap[ApiLocales] {
  return ApiToDbMap[languageString];
}

编译时+运行时双重校验(提前拦截问题)

为了在数据提交到数据库前提前发现问题,可做两层校验:

1. 编译时校验

上面的代码已通过TypeScript类型系统确保:

  • 函数只能接收ApiLocales范围内的字符串(传'zh-cn'这类非法值会直接编译报错)
  • 返回值必然是DatabaseLocales范围内的字符串,不会出现数据库不接受的值

2. 运行时兜底校验

如果有非预期的运行时输入(比如API返回未定义的语言码),可加兜底逻辑抛出错误:

function databaseLanguageCodeFromString(languageString: string): DatabaseLocales {
  const dbCode = ApiToDbMap[languageString as ApiLocales];
  if (!dbCode) {
    throw new Error(`无效的API语言码:${languageString},无法转换为数据库支持的格式`);
  }
  return dbCode;
}

额外优化:避免重复定义映射

直接从Locales对象生成反向映射,后续新增语言码只需修改Locales,减少重复代码和出错概率:

const Locales = {
  en_gb: 'en-gb',
  en_us: 'en-us',
} as const;

type ApiLocales = typeof Locales[keyof typeof Locales];
type DatabaseLocales = keyof typeof Locales;

// 从Locales自动生成反向映射
const ApiToDbMap = Object.fromEntries(
  Object.entries(Locales).map(([dbCode, apiCode]) => [apiCode, dbCode])
) as { [K in ApiLocales]: DatabaseLocales };

function databaseLanguageCodeFromString(languageString: ApiLocales): DatabaseLocales {
  return ApiToDbMap[languageString];
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:05:39