打字稿:使用对象值作为新类型的键

时间:2021-02-18 18:38:00

标签: typescript object types

我有一个对象:

export const CODES = {
   ALPHA: 'alpha',
   OMEGA: 'omega',
}

我想要一个新的类型,它应该是这样的:

export type CODES_OBJECTS = {
 alpha: {},
 omega: {}
}

但很明显,由于将来可以更改 CODES 并获得更多键值对,因此我想创建一个通用类型,它会自动获取 CODES 中的所有值作为键。 我找到了这个 Types from both keys and values of object in Typescript,但该解决方案不适用于我的情况。

如果更简单的 CODES 也可以枚举。

1 个答案:

答案 0 :(得分:1)

您可以将索引访问类型与 keyof 结合使用以获得所需的内容。

代码

type ValuesAsKeys<T extends Record<any, PropertyKey>, NewValue> = Record<T[keyof T], NewValue>

export const CODES = {
   ALPHA: 'alpha',
   OMEGA: 'omega',
} as const;

export type CODES_OBJECTS = ValuesAsKeys<typeof CODES, {}>
/* resolves to type CODES_OBJECTS = {
    alpha: {};
    omega: {};
} */

Playground Link

说明

类型 ValuesAsKeys 有两个泛型——T 是我们想要使用其值作为键的对象(你的 CODES const)和 NewValue 是值我们想分配给这些键(这里是一个空对象 {},但您可能想要更好的东西)。

为了使用 T 的值作为键,我们必须坚持 T 的值是可以用作键的东西。我们通过使用内置类型 T extends Record<any, PropertyKey>PropertyKey 做到这一点。

我们可以访问 T 的所有值与 T[keyof T] 的并集,Record 是一种索引访问类型。我们想要创建一个 Record<T[keyof T], NewValue>,其中这些是新键。所以我们得到 alpha

为了让 typescript 将 omegastring 视为它们的文字值而不仅仅是 as const,我们在创建 CODES 时使用了 CODES

typeof CODES 是一个值而不是一个类型,所以我们使用 T 作为 enum

枚举版本

如果使用 as const,打字稿几乎相同。唯一的区别是您不需要添加 type ValuesAsKeys<T extends Record<any, PropertyKey>, NewValue> = Record<T[keyof T], NewValue> enum CODES { ALPHA = 'alpha', OMEGA = 'omega', } export type CODES_OBJECTS = ValuesAsKeys<typeof CODES, {}>

df <- tibble(x = c("a", "b"), y = c(1, 1), z = c(-1, 1))
# Find all rows where EVERY numeric variable is greater than zero
df %>% filter(across(where(is.numeric), ~ .x > 0))
#> # A tibble: 1 x 3
#>   x         y     z
#>   <chr> <dbl> <dbl>
#> 1 b         1     1

Playground Link