TypeScript:如何在类型层面将字符串数组转为对象属性名
实现带IntelliSense自动补全的数组转对象函数
问题描述
我需要实现一个TypeScript函数,将输入的字符串数组转换为键为数组元素、值为对应索引的对象,同时要求VSCode的IntelliSense能准确提示返回对象的可用属性。例如调用invert(['foo', 'bar', 'baz'])后,访问返回值时能自动补全foo、bar、baz这些属性。
现有初始函数如下,但之前尝试的类型断言方式无法触发自动补全:
function invert(arr: string[]) { let result = {}; arr.forEach((x, i) => { result[x] = i; }) return result; // 此处曾尝试类型断言但无效 }
解决方案
核心是通过泛型结合字面量类型推导,让TypeScript记住数组的具体元素值(而非宽泛的string[]类型),从而让IntelliSense识别返回对象的具体属性:
1. 编写泛型函数
将函数声明为泛型函数,约束泛型T为只读字符串数组,确保TypeScript能推导输入数组的具体字面量类型:
function invert<T extends readonly string[]>(arr: T): { [K in T[number]]: number } { // 用类型断言初始化结果对象,解决空对象与目标类型不兼容的问题 const result = {} as { [K in T[number]]: number }; arr.forEach((x, i) => { result[x] = i; }); return result; }
2. 验证自动补全效果
调用函数时传入字面量数组,TypeScript会自动推导返回对象的具体属性,IntelliSense就能正常提示:
const example = invert(['foo', 'bar', 'baz']); example.foo; // 输入example.时,VSCode会自动提示foo、bar、baz
关键说明
- 泛型
T extends readonly string[]:让TypeScript将输入数组推导为包含具体元素的元组类型(比如readonly ['foo', 'bar', 'baz']),而非宽泛的string[],这是触发自动补全的核心前提。 - 返回类型
{ [K in T[number]]: number }:遍历元组的元素类型作为对象的键,值类型固定为索引的number类型,明确告知TypeScript返回对象的所有可用属性。 - 类型断言
as { [K in T[number]]: number }:初始空对象{}的类型为{},无法直接赋值为目标类型,通过断言解决类型不兼容问题。
内容的提问来源于stack exchange,提问作者Electric Coffee
相关产品推荐
相关产品推荐

