从对象推断值

AKG*_*AKG 2 typescript

我如何从这样的对象中推断所有值……

const fruits = {
  a: 'apple',
  b: 'banana'
};
Run Code Online (Sandbox Code Playgroud)

…让我明白了吗?

type fruitValues = 'apple' | 'banana';
Run Code Online (Sandbox Code Playgroud)

(我相信我正在寻找与$Values<T>Flow 相当的产品)

jca*_*alz 5

您可以从对象推断类型,但是已经推断出对象仅包含string属性。也就是说,类型"apple""banana"扩展string,如相关GitHub问题中所述,因为它们是非readonly属性。

const fruits = {
  a: 'apple',
  b: 'banana'
};

type FruitValues = (typeof fruits)[keyof typeof fruits]; // string
Run Code Online (Sandbox Code Playgroud)

所以以上FruitValues不是您想要的。如果您想靠近,则需要防止扩大。一种方法是使用冗余但自包含的类型断言

const fruits = {
  a: 'apple' as 'apple',
  b: 'banana' as 'banana'
};

type FruitValues = (typeof fruits)[keyof typeof fruits]; // "apple" | "banana"
Run Code Online (Sandbox Code Playgroud)

另一种方法是制作一个辅助函数来推断更窄的类型:

// put in a library somewhere
type Narrowable = string | number | boolean | undefined | null | void | {};
const narrowObj = <V extends Narrowable, T extends { [k: string]: V }>(t: T) => t;

const fruits = narrowObj({
  a: 'apple',
  b: 'banana'
})

type FruitValues = (typeof fruits)[keyof typeof fruits]; // "apple" | "banana"
Run Code Online (Sandbox Code Playgroud)

最后,一旦TypeScript 3.4着陆,将有const上下文可以推断出最窄的类型(包括创建readonly您可能不想要的所有属性),如下所示:

const fruits = {
  a: 'apple',
  b: 'banana'
} as const; // requires TS3.4+

type FruitValues = (typeof fruits)[keyof typeof fruits]; // "apple" | "banana"
Run Code Online (Sandbox Code Playgroud)

好的,希望对您有所帮助。祝好运!