提问人:kael 提问时间:7/11/2023 更新时间:7/11/2023 访问量:34
Typescript 未对对象数组强制实施区分类型
Typescript not enforcing discriminated type on array of objects
问:
我创建了以下一组类型(简化):
enum Prevals {
one = 'one',
two = 'two',
three = 'three',
}
type PrevalParams = {
[Prevals.one]: {
name: string;
age: number;
};
[Prevals.two]: {
t: 'thing';
};
[Prevals.three]: undefined;
}
type PrevalConfig<Id extends Prevals> = {
id: Id;
level: 'error' | 'warning';
params: PrevalParams[Id];
};
鉴于上述类型,我希望能够将多个对象分配给一个数组,并让打字稿强制执行其参数。但是,它似乎将参数解释为所有可能的参数的并集,而不是与给定的特定 ID 关联的参数。PrevalConfig
例如,以下内容应引发错误,但不会:
const prevals: PrevalConfig<Prevals>[] = [
{
id: Prevals.one,
level: 'warning',
params: {
t: 'thing'
}
}
]
我相信这是因为该类型本质上是“PrevalConfig 对象的数组,其中参数是所有可能的 Prevals 的并集”。鉴于这种解释,从技术上讲,它键入“所有可能的参数的并集”是正确的。然而,这不是我想要的。PrevalConfig<Prevals>[]
Id
params
我该如何完成这项工作?
(这是一个预装了所有这些的游乐场)
答:
0赞
kael
7/11/2023
#1
我的一个同事刚刚帮我解决了这个问题。我一直对自己说,“我需要成为所有可能的 preval 配置的并集,而不是参数化类型”,确实有一个(有点奇怪的)打字稿结构:PrevalConfig
type PrevalConfig = {
[Id in Prevals]: {
id: Id;
level: 'error' | 'warning';
params: PrevalParams[Id];
};
}[Prevals];
基本上,您可以创建每个 preval 的映射类型,以匹配其特定类型的配置。然后,您同时告诉打字稿为您提供该映射类型的所有值的并集。因此,您:D拥有所有可能的 preval 配置的并集。
谢谢,匿名同事!
评论
0赞
jcalz
7/11/2023
这种数据结构被称为“分布式对象类型”,正如 GitHub 问题 microsoft/typescript#47109 中创造的那样(在移动设备上,现在很难添加链接,也许我稍后会把它放在这里
0赞
kael
7/12/2023
啊!@jcalz,谢谢你的参考。
评论