减速机蓄能器的正确类型

时间:2020-06-25 19:37:30

标签: javascript typescript

如何为以下代码描述resultacc类型?

const arr = ['a', 'b', 'c'] as const;

const result = arr.reduce((acc, item, idx) => {
    return {
      ...acc,
    [item]: idx,
  }
}, {});

取决于迭代acc可以是:

  1. {}
  2. a:数字
  3. a:数字,b:数字
  4. a:数字,b:数字,c:数字

首先,我使用以下代码:

type MyResult = Record<typeof arr[number], number>; //  
type MyAcc = Partial<MyResult>;

但这是不正确的:

  Types of property 'a' are incompatible.
    Type 'number | undefined' is not assignable to type 'number'.
      Type 'undefined' is not assignable to type 'number'.(2322)

Playground

1 个答案:

答案 0 :(得分:1)

这是我的方法:

type ArrayItemType<A extends ReadonlyArray<any>> = A[number];

const arr = ['a', 'b', 'c'] as const;

type KeyIndexes = Record<ArrayItemType<typeof arr>, number>;

const result = arr.reduce((acc, item, idx) => {
    return {
      ...acc,
    [item]: idx,
  }
}, {} as KeyIndexes);

KeyIndexes有效:

{
  a: number,
  b: number,
  c: number
}

...如您所见at this playground

我意识到,在简化的所有阶段,从技术上来说都不是初始化类型和累加器的类型,但是TypeScript确实没有办法弄清楚部分结果将如何变成简化类型。完整的结果,因此无论如何您都需要进行投射。

更新

如果您真的关心累加器的类型与结果不同,则可以相应地调整类型,但是您必须进行一些更丑陋的转换:

type ArrayItemType<A extends ReadonlyArray<any>> = A[number];

const arr = ['a', 'b', 'c'] as const;

type KeyIndexes = Record<ArrayItemType<typeof arr>, number>;

const result = arr.reduce((acc: Partial<KeyIndexes>, item, idx) => {
    return {
      ...acc,
    [item]: idx,
  }
}, {}) as KeyIndexes;

(请参见playground