0

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

例如,

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'吗?是否有任何类型可以替换它并使语句更易于阅读?

4

2 回答 2

1

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

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

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

keyof typeof foo 是描述“a”的最短形式吗?'b' | 'C'?是否有任何类型可以替换它并使语句更易于阅读?

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

type FooKeys = keyof typeof foo
type RandomType = typeof foo[FooKeys][number];
于 2021-04-27T09:03:26.363 回答
1

您可以使用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];
于 2021-04-27T09:29:54.650 回答