如何基于对象值创建窄类型

时间:2019-03-22 18:20:49

标签: typescript

我正在从流程过渡到打字稿的过程中,遇到了无法解决的问题。在流程中,我有以下内容:

const color = Object.freeze({
  white: '#ffffff',
  black: '#000000',
})

type PossibleColorValues = $Values<typeof color>

在这种情况下,PossibleColorValues'#ffffff' | '#000000'

打字稿中有与此等效的内容吗?我尝试了以下方法:

type PossibleColorValues = typeof color[keyof typeof color]

但是在这种情况下,PossibleColorValues只是string

1 个答案:

答案 0 :(得分:1)

您对如何获取对象中所有可能值的并集有正确的想法。 typeof color[keyof typeof color]应该可以解决问题。

问题在于color不能保留当前定义的原始类型。您需要说服编译器保留最初在对象文字中分配的字符串文字类型。

在3.4(尚未发布)中,您可以使用as const来让编译器知道您需要文字类型和只读对象。因此,这将按3.4中的预期进行工作(再次可能在本月发布3.4版):

const color = Object.freeze({
  white: '#ffffff',
  black: '#000000',
} as const)

type PossibleColorValues = typeof color[keyof typeof color]

同时,您可以使用一个函数来使编译器推断文字类型:

declare function withLiterals<
    T extends Record<string, V>, 
    V extends string | boolean | number | symbol | null | undefined | Record<string, V>
>(input: T ): T;

const color = Object.freeze(withLiterals({
    white: '#ffffff',
    black: '#000000',
}));

type PossibleColorValues = typeof color[keyof typeof color]