数组元素到接口属性

时间:2019-03-13 14:49:05

标签: typescript

我想使用一个ReadonlyArray<string>并将其元素转换为interface。也就是说,从下面的示例中,我想采用props数组和 synthesize Props接口(Props属性的实际类型是无关紧要的给我)。

// Given
const props: ReadonlyArray<string> = [ 'a', 'b', 'c' ];

// Output
interface Props {
  a: number;
  b: number;
  c: number;
}

也许另一种方法是从Props接口开始,然后 get props数组开始。尽管基于TypeScript开发人员的comment,看来这显然不是该项目的目标。

1 个答案:

答案 0 :(得分:3)

为了让TypeScript理解某种 是什么,必须在编译时对其进行描述。但是,如果您从类型ReadonlyArray<string>开始,它只能知道props包含一些字符串,而其他字符串很少(它可以为空,可以有重复,等等。)编译器没有办法从ReadonlyArray<string>{ a: number, b: number, c: number },因为它很容易变成几乎其他类型。您能获得的最接近的数字是Record<string, number>,但这并不令人满足。

我建议为您的键定义一个联合类型,例如:

type PropKeys = 'a' | 'b' | 'c';
type Props = Record<PropKeys, number>;

const props: ReadonlyArray<PropKeys> = [ 'a', 'b', 'c' ];
const numbers: Props = {
  a: 1,
  b: 2,
  c: 3,
}

这是解决此问题的最简单,最自然的方法。

但是,如果由于某种原因无法使用并集,并且您绝对必须使用数组,则可以将数组键入为固定长度的元组,每个元素都是常量类型(或常量类型的并集),以便编译器可以对其进行剖析/分析,并为您提供所需的重构类型。

const props: [ 'a', 'b', 'c' ] = [ 'a', 'b', 'c' ];
// In TS 3.4 (not yet released at time of writing)
// const props = ['a', 'b', 'c'] as const;

type Props = Record<typeof props[number], number>;
const numbers: Props = {
  a: 1,
  b: 2,
  c: 3,
}