我试图弄清楚如何创建基于对象的类型,该类型的键是固定的,并映射到类型的特定属性。值应使用与属性对应的类型。
请考虑以下类型:
interface CooldownError {
message: 'cooldown'
minutes: Number
}
interface AbortError {
message: 'error'
description: string
}
基于message
属性,我想要一种具有以下签名的类型:
type ErrorCollection = {
cooldown: (e: CooldownError) => void;
error: (e: AbortError) => void;
}
到目前为止我尝试过的事情:
type GQLErrors = CooldownError | AbortError;
type ErrorCollection = { [key in GQLErrors['message']]: (e: GQLErrors) => void };
虽然这适用于键,但所有值均设置为联合。我没有找到以某种方式解构工会的方法。这有可能吗?
答案 0 :(得分:1)
假设您已经承诺要使用类似GQLErrors
的联合类型(并且您需要这样做,因为否则无法知道要进行的迭代),您可以调整{ {1}}像这样:
ErrorCollection
在这里,我们使用内置实用程序类型Extract<T, U>
,该类型采用联合类型type ErrorCollection = {
[K in GQLErrors['message']]: (e: Extract<GQLErrors, { message: K }>) => void
};
,并且仅返回与T
匹配的T
成员的联合。因此,当U
为Extract<GQLErrors, { message: K }>
时CooldownError
会变成K
,而当"cooldown"
为AbortError
时K
会变成"error"
。您可以验证编译器将ErrorCollection
视为:
/*
type ErrorCollection = {
cooldown: (e: CooldownError) => void;
error: (e: AbortError) => void;
}
*/
这就是您想要的。希望能有所帮助;祝你好运!
答案 1 :(得分:0)
您可以使用中间界面,如下所示:
interface CooldownError {
message: 'cooldown'
minutes: Number
}
interface AbortError {
message: 'abort' // changed from 'error'
description: string
}
interface Intermediate {
cooldown: CooldownError
abort: AbortError
}
type ErrorCollection = {[K in keyof Intermediate]: (e: Intermediate[K]) => void}
请注意,您有责任使Intermidate
接口键与错误的message
键相同。