typescript 创建实用程序类型以便从两个元组创建对象

eqoofvh9  于 2023-05-01  发布在  TypeScript
关注(0)|答案(1)|浏览(158)

我有两个基本的元组:

const tuples1 = ['a', 'b', 'c'] as const;
const tuples2 = [1, 2, 3] as const;

我想创建一个将两者合并在一起的对象:

const ResultMerge = {
  'a': 1,
  'b': 2,
  'c': 3
}

我使用TypeScript,所以我想有一个实用程序类型Map类型的功能的工作。
我的解决方案的需要是根据第一次迭代的索引检索第二个元组的值。
验证码:

type TuplesToObject<T extends readonly any[], U extends readonly any[]> = {
  [K in T[number]]: U[Extract<keyof T, K>[number]]
}
type TupleToObject<T extends readonly string[], U extends readonly any[]> = Record<T[number], U[Extract<keyof T, number>]>

但是对于我的实用程序类型TuplesToObject,结果始终相同。这是这样的东西:

{
  a: 3 | 1 | 2,
  b: 3 | 1 | 2,
  c: 3 | 1 | 2
}

而我的目的就是要达到这个结果

{
  a: 1 ,
  b: 2 ,
  c: 3
}

Playground

yhived7q

yhived7q1#

您可以map over您的元组的类似数字的键,并使用键重Map将索引转换为第一个元组的键:

type TupleToObject<
  K extends readonly PropertyKey[],
  V extends Record<keyof K, any>
> = {
    [I in `${number}` & keyof K as K[I]]: V[I]
  }

我将K限制为一个类似于键的类型数组,将V限制为一个至少与K具有相同索引的对象(这样,如果VK短,它就会抱怨)。
我们不想MapK元组的 * 所有 * 属性,如I in keyof T as K[I],因为这最终将包括数组方法名称,如"slice"。我们所需要的是“类似数字”的字符串索引,如"0""1""2",对应于定位的元素。我们可以通过将keyof Tpattern template literal(参见ms/TS#40598${number}相交来得到这些:

type NumberlikeKeys = `${number}` & keyof ['a', 'b', 'c', 'd', 'e'];
// type NumberlikeKeys = "0" | "1" | "2" | "3" | "4"

好了,让我们在你的例子中测试TupleToObject<K, V>

const a = ['a', 'b', 'c'] as const;
const b = [1, 2, 3] as const;

type Test = TupleToObject<typeof a, typeof b>;
//   ^? type Test = { a: 1; b: 2; c: 3; }

看起来不错!
Playground链接到代码

相关问题