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

TypeScript如何一步实现接收字符串数组返回对应类型映射?

直接传入数组字面量实现类型安全的映射生成

问题背景

我有一个接收字符串数组作为参数的函数,返回以数组每个元素为键的映射,希望返回类型能准确体现这些键。当前实现如下:

function register<T extends string>(name: string, events: readonly T[]): { [S in T]: string } {
  const r = events.reduce((p, el) => {
    p[el] = `${name}:${el}`;
    return p;
  }, {} as { [S in T]: string });
  return r;
}

const colors = ["blue", "green", "red", "yellow"] as const;
const x = register<typeof colors[number]>('foo', colors)
console.log(x.blue, x)

现在希望省去提前定义带as const断言的数组变量这一步,直接传入数组字面量完成调用,即实现:

const x = register<...?...>('foo', ["blue", "green", "red", "yellow"])

解决方案

有两种方式可以实现需求:

方式一:给数组字面量直接添加as const断言

无需修改函数,直接在传入的数组字面量后添加as const,让TypeScript捕获每个元素的具体字面量类型:

function register<T extends string>(name: string, events: readonly T[]): { [S in T]: string } {
  const r = events.reduce((p, el) => {
    p[el] = `${name}:${el}`;
    return p;
  }, {} as { [S in T]: string });
  return r;
}

// 直接传入带as const的数组字面量
const x = register('foo', ["blue", "green", "red", "yellow"] as const);
console.log(x.blue, x.green); // 类型提示正常,x的键严格对应数组元素

方式二:修改函数泛型,自动推断字面量元组

调整函数的泛型约束,让TypeScript默认将数组字面量推断为字面量元组,无需手动加as const:

function register<T extends readonly string[]>(name: string, events: T): { [S in T[number]]: string } {
  const r = events.reduce((p, el) => {
    p[el] = `${name}:${el}`;
    return p;
  }, {} as { [S in T[number]]: string });
  return r;
}

// 直接传入数组字面量,自动推断类型
const x = register('foo', ["blue", "green", "red", "yellow"]);
console.log(x.blue, x.red); // 类型提示正常

说明

  • 方式一的核心是as const断言,它会把数组标记为只读的字面量元组,让泛型T捕获每个元素的具体字符串值,从而生成准确的返回类型。
  • 方式二通过将泛型参数改为约束readonly string[],利用TypeScript的类型推断规则,自动把数组字面量推断为字面量元组,而非宽泛的string[],进而生成正确的映射类型。

内容的提问来源于stack exchange,提问作者max.ott

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:12:41