首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从类型记录中的数组值中创建对象键

如何从类型记录中的数组值中创建对象键
EN

Stack Overflow用户
提问于 2022-09-03 10:45:39
回答 1查看 83关注 0票数 0

如何在打字稿中输入跟随功能,使我获得自动完成和错误预防。

使用打字本4.7.4

代码语言:javascript
运行
复制
// reference fn
function doSomething(list) {

    const data = {};

    list.map(item => {
        data[item] = 'value type string|number|bool|null'   
    });

    return data;
}

// calling it like
const data = doSomething([
    'phone_number',
    'customer_email'
]);

// get IDE autocomplete here (for only properties inside data)
console.log(data.phone_number);
console.log(data.customer_email);

// typescript yell when try to access invalid properties
console.log(data.phone_numbersss);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-03 10:58:48

如果所使用的数组实际上是函数调用点处的编译时常量(因此TypeScript知道它的值是什么),您就可以这样做。否则,TypeScript不知道数组内容是什么,因此必须假定任何字符串。至少有两种方法可以满足约束:

  1. 通过将常量断言应用于数组,可以直接说数组是常量: const = "phone_number","customer_email“作为const;//
  2. 您可以在调用点使用数组文本,并对参数的类型使用多元元组类型 (更多信息)。

一旦我们知道数组的内容是TypeScript的编译时常量,就可以使用映射类型将扩展string[]的数组映射到以数组元素作为键和所需的属性类型的对象:

代码语言:javascript
运行
复制
type DoSomethingResult<T extends readonly string[]> = {
    [Key in T[number]]: string | number | boolean | null;
};

实现该函数需要创建对象(而不是数组)并赋予属性一些值;我选择了null

代码语言:javascript
运行
复制
function doSomething<T extends readonly string[]>(list: [...T]): DoSomethingResult<T> {
    // Variadic tuple type −−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^
    return Object.fromEntries(list.map((key) => [key, null])) as DoSomethingResult<T>;
}

这里有个电话:

代码语言:javascript
运行
复制
const data = doSomething([
    "phone_number",
    "customer_email"
]);

然后,所有给定的测试用例都能工作。

操场链接

注意,数组必须是数组文本;这是行不通的:

代码语言:javascript
运行
复制
// WON'T WORK AS DESIRED
const names = [
    "phone_number",
    "customer_email"
];
const data = doSomething(names);

TypeScript推断数组的类型为string[],而不是["phone_number", "customer_email"]。(如果您在数组中添加了一个as const,它就可以工作了。)

如果您必须支持不具有多种元组类型(在V4.0中引入)的TypeScript版本,则可以使用as const版本:

代码语言:javascript
运行
复制
function doSomething<T extends readonly string[]>(list: T): DoSomethingResult<T> {
    // Using `T` directly as the type −−−−−−−−−−−−−−−−−−^
    return Object.fromEntries(list.map((key) => [key, null])) as DoSomethingResult<T>;
}
// ...
const data = doSomething([
    "phone_number",
    "customer_email"
] as const);
//^^^^^^^^

使用v3.9.7的操场链接

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73591609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档