gpt4 book ai didi

javascript - TypeScript 是否可以从动态对象推断键?

转载 作者:搜寻专家 更新时间:2023-10-30 21:17:10 26 4
gpt4 key购买 nike

我在这里试图实现的是对从数组生成的对象的智能感知/自动完成 - 类似于 Redux 的 Action Creator,一个字符串数组 (string[])可以简化为形状为 { [string]: string } 的对象。

例如:

const a = ['ONE', 'TWO', 'THREE'];

const b = a.reduce((acc, type) => ({ ...acc, [type]: type }), {});

console.log(b);
// Output: b = { ONE: 'ONE', TWO: 'TWO', THREE: 'THREE' };

我已经设法让 TypeScript 理解这么多,使用下面的方法。 TypeScript 知道键是字符串,但不知道它们是什么。

interface ITypesReturnObject { [s: string]: string }

有没有人想出办法通知 TypeScript 对象上的键等于数组中的字符串?

如有任何帮助,我们将不胜感激。

最佳答案

(假设您在下面使用 TS3.0 或更高版本)

TypeScript 支持 string literal types 的概念以及tuple types ,因此也可以让您的值 a 具有 type ['ONE', 'TWO', 'THREE']作为 ['ONE', 'TWO', 'THREE'],像这样:

const a: ['ONE', 'TWO', 'THREE'] = ['ONE', 'TWO', 'THREE'];

(实现这一点的冗余方式将在稍后出现):

然后您可以使用 mapped typeb 的预期类型表示为从键到与键完全匹配的值的映射。 :

type SameValueAsKeys<KS extends string[]> = { [K in KS[number]]: K };

可以这样使用:

const b: SameValueAsKeys<typeof a> = a.reduce((acc, type) => ({ ...acc, [type]: type }), {} as any);
b.ONE; // property type is "ONE"
b.TWO; // property type is "TWO"
b.THREE; // property type is "THREE"

请注意编译器是如何知道 b 具有三个键的,“ONE”“TWO”“THREE” ,并且值与键相同。


所以 TypeScript 当然支持这种类型的动态类型。不幸的是,正如我在上面展示的那样,使用起来有点乏味。一种减少烦人的方法是添加一些辅助函数,使编译器能够推断出正确的类型,或者至少将类型断言隐藏在开发人员不必担心的库中。

首先,对于a...,编译器不会推断元组类型,而且它还倾向于将字符串文字扩展为string 类型,certain instances 除外。 .让我们引入一个名为 stringTuple() 的辅助函数:

function stringTuple<T extends string[]>(...args: T) { return args; }

这推断出一个 tuple type from rest arguments .现在我们可以使用它来制作 a 而无需输入多余的字符串值:

const a = stringTuple("ONE", "TWO", "THREE");

接下来,让我们介绍一个函数,它接受一个字符串列表并返回一个对象,该对象的键是这些字符串并且其值与字符串匹配:

function keyArrayToSameValueAsKeys<T extends string[]>(keys: T): SameValueAsKeys<T>;
function keyArrayToSameValueAsKeys(keys: string[]): { [k: string]: string } {
return keys.reduce((acc, type) => ({ ...acc, [type]: type }), {});
}

这里我们使用与 reduce 相同的代码,但我们将它隐藏在它自己的函数中并使用单个 overload call signature来表示预期的输出类型。现在,我们可以这样得到 b:

const b = keyArrayToSameValueAsKeys(a);
b.ONE; // property type is "ONE"
b.TWO; // property type is "TWO"
b.THREE; // property type is "THREE"

如果将 stringTuple()keyArrayToSameValueAsKeys() 放在一个库中,用户就可以毫不费力地使用它们:

const otherObject = keyArrayToSameValueAsKeys(stringTuple("x", "y", "z"));
// const otherObject: {X: "X", Y: "Y", Z: "Z"}

或者您可以像这样将它们合并在一起:

function keysToSameValueAsKeys<T extends string[]>(...keys: T): { [K in T[number]]: K };
function keysToSameValueAsKeys(keys: string[]): { [k: string]: string } {
return keys.reduce((acc, type) => ({ ...acc, [type]: type }), {});
}

然后在一次调用中获取输出,如下所示:

const lastOne = keysToSameValueAsKeys("tic", "tac", "toe");
// const lastOne: {tic: "tic", tac: "tac", toe: "toe"};

好的,希望对您有所帮助。祝你好运!

关于javascript - TypeScript 是否可以从动态对象推断键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53007041/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com