我想使用一个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,看来这显然不是该项目的目标。
答案 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,
}