TypeScript 中 const 对象的索引类型是什么?

What is the index type of const object in TypeScript?

我想根据对象的值定义一个类型。

例如,

const foo = <const>{
  'a': ['1', '2', '3', '4'],
  'b': ['5', '6', '7', '8'],
  'c': ['9', '10', '11', '12'],
};

type RandomType = typeof foo[Readonly<string>][number]; // '1' | '2' | '3' | ... | '12'

但是如果我使用number作为索引类型,TypeScript会报如下错误

Type '{ readonly a: readonly ["1", "2", "3", "4"]; readonly b: readonly ["5", "6", "7", "8"]; readonly c: readonly ["9", "10", "11", "12"]; }' has no matching index signature for type 'string'.ts(2537)

解决方法是将 Readonly<string> 替换为 keyof typeof foo

type RandomType = typeof foo[keyof typeof foo][number];

但这会使语句变得更长且更难阅读,尤其是当我使用的对象嵌套在另一个对象中时,例如 aaa.bbb.ccc.ddd.foo


为什么 Readonly<string> 在上述情况下不起作用?

keyof typeof foo是描述'a' | 'b' | 'c'的最短形式吗?有没有什么类型可以替代它并使语句更易于阅读?

Why won't Readonly<string> works in the case above?

因为您的对象没有所有可能字符串的键。

'bar' 是一个字符串,但是当您访问 foo['bar'] 时,您得到的是 undefined,而不是字符串数组,因此您的类型没有意义。

Is keyof typeof foo the shortest form to describe 'a' | 'b' | 'c'? Is there any type to replace it and make the statement easier to read?

如果你需要在不同的地方使用它,你可以将它分配给一个中间类型:

type FooKeys = keyof typeof foo
type RandomType = typeof foo[FooKeys][number];

您可以使用 Values 实用程序类型。

const foo = {
    'a': ['1', '2', '3', '4'],
    'b': ['5', '6', '7', '8'],
    'c': ['9', '10', '11', '12'],
} as const;

type Values<T> = T[keyof T]

type RandomType = Values<typeof foo>[number];