使用对象的值创建类型

Web*_*man 6 typescript

像这样的物体

const USER_EVENT = {
    pageview: 'Visit',
    order: 'Order'
}
Run Code Online (Sandbox Code Playgroud)

如果我想得到一个所有键并集的类型

type UserEventKey = 'pageview' | 'order'
Run Code Online (Sandbox Code Playgroud)

我可以做到这一点

type UserEventKey = keyof typeof USER_EVENT
Run Code Online (Sandbox Code Playgroud)

...但是是否可以通过所有值的并集来获得这种类型?

type UserEventName = 'Visit' | 'Order'


type UserEventName = ???? is it possibile?
Run Code Online (Sandbox Code Playgroud)

jca*_*alz 8

您不能按USER_EVENT书面方式使用您的对象。编译器使用一些启发式方法来推断未注释的变量的类型。一般来说,编译器将字符串属性值视为类型string

const OOPS_USER_EVENT = {
    pageview: 'Visit',
    order: 'Order'
}
/* const OOPS_USER_EVENT: {
    pageview: string;
    order: string;
} */
Run Code Online (Sandbox Code Playgroud)

所以编译器已经忘记了具体的"Visit""Order"值,你所做的任何事情都typeof USER_EVENT不会恢复它们。

相反,您需要以USER_EVENT不同的方式定义。最简单的方法是使用const断言来暗示您的对象根本不会改变,并要求编译器推断它可以推断出的最具体的类型:

const USER_EVENT = {
    pageview: 'Visit',
    order: 'Order'
} as const;
/* const USER_EVENT: {
    readonly pageview: "Visit";
    readonly order: "Order";
} */
Run Code Online (Sandbox Code Playgroud)

现在USER_EVENT具有string文字类型 "Visit""Order"; 您关心的信息仍然存在。


此时,您需要采用对象类型T,例如获取属性值类型的并集而不是键。请参阅此问题以获取此问题及其答案的更规范版本。

您可以使用表单的索引访问类型T[K]获取 type 的键处的属性值类型K。如果您想要所有密钥,则T[keyof T]可以:

type ValueOf<T> = T[keyof T];


type UserEventName = ValueOf<typeof USER_EVENT>;
// type UserEventName = "Visit" | "Order"
Run Code Online (Sandbox Code Playgroud)

Playground 代码链接


Ale*_*yne 5

只需通过其自己的键对类型进行索引即可获取值的并集。

const USER_EVENT = {
    pageview: 'Visit',
    order: 'Order'
} as const

type UserEventName = typeof USER_EVENT[keyof typeof USER_EVENT] // "Visit" | "Order"
Run Code Online (Sandbox Code Playgroud)

注意as const那里。这是强制类型被推断为特定字符串所必需的,而不仅仅是string.

操场