如何在Typescript中强制只读数组具有带字符串文字的元组类型?

时间:2018-09-24 03:29:20

标签: typescript

我有一个配置对象,如下所示:

const config = { envs: ['dev', 'test', 'prod'], targets: ['> 2%'] };

当前,打字稿编译器推断该对象的类型为:

type IConfig = { envs: string[], targets: string[] };

这很有意义,因为我可能会在声明后的某个时刻对这个数组进行突变。

尽管我不会更改它,所以我希望它是

type IConfig = { envs: ['dev', 'test', 'prod'], targets: ['> 2%'] };

是否有任何方法告诉编译器将config.envs的类型推断为带有字符串文字的元组类型(无需键入)?

编辑:最好的答案是在那里的90%,但是我希望可以将一种方法应用于整个对象而不是每个属性。我在示例中添加了另一个属性,以使其更加清晰。

1 个答案:

答案 0 :(得分:2)

the standard trick to infer literal typesa trick I just learned to infer a tuple type rather than an array type组合:

function asTupleOfLiterals<T extends string, U extends [T, ...T[]]>(tuple: U): U {
    return tuple;
}
const config = { envs: asTupleOfLiterals(['dev', 'test', 'prod']) };

第二轮:应用于具有多个元组值属性的对象

奇迹般地,如果我们仅将[T, ...T[]]包装在带有索引签名的对象中,则上下文类型输入似乎起作用:

function asObjectOfTuplesOfLiterals<T extends string,
    U extends {[n: string]: [T, ...T[]]}>(obj: U): U { return obj; }

const config = asObjectOfTuplesOfLiterals(
    { envs: ['dev', 'test', 'prod'], targets: ['> 2%'] });

FTR,有an open suggestion to make it easier to infer literal typesone to make it easier to infer tuple types