【发布时间】:2022-02-05 09:49:20
【问题描述】:
问题陈述
我想声明 mapper1 以便它的值只能是 Type1 和 mapper2 以便它的值只能是 Type2。在不声明密钥类型的情况下如何做到这一点?
背景
在 TypeScript 中,我有:
import Bar1 from './bar1'; // Type1
import Bar2 from './bar2'; // Type1
import Bar3 from './bar3'; // Type2
import Bar4 from './bar4'; // Type2
const mapper1 = {
foo1: bar1,
foo2: bar2,
} as const;
const mapper2 = {
foo3: bar3,
foo4: bar4,
} as const;
export type MapperKeys = keyof typeof mapper1 | keyof typeof mapper2;
bar1 和 bar2 具有相同的类型 (Type1)。 bar3 和 bar4 具有相同的类型 (Type2)。 Type1 与 Type2 不同。
MapperKeys 是 mapper1 和 mapper2 ('foo1' | 'foo2' | 'foo3' | 'foo4') 的键的并集。
我尝试了什么
方法一:
const mapper1: Record<string, Type1> = {
foo1: bar1,
foo2: bar2,
} as const;
const mapper2: Record<string, Type2> = {
foo3: bar3,
foo4: bar4,
} as const;
但现在MapperKeys 是'string'。我希望它是 mapper1 和 mapper2 ('foo1' | 'foo2' | 'foo3' | 'foo4') 的键的联合
方法二:
const mapper1: Record<'foo1' | 'foo2', Type1> = {
foo1: bar1,
foo2: bar2,
} as const;
const mapper2: Record<'foo3' | 'foo4', Type2> = {
foo3: bar3,
foo4: bar4,
} as const;
这可行,但不是DRY。
【问题讨论】:
-
请提供minimal reproducible example,清楚地表明您面临的问题。理想情况下,有人可以将代码粘贴到像 The TypeScript Playground (link here!) 这样的独立 IDE 中,然后立即着手解决问题,而无需首先重新创建它。所以不应该有伪代码、拼写错误、不相关的错误或未声明的类型或值。
-
this approach 是否满足您的需求?如果你用对象类型注释一个变量,你告诉编译器它不应该尝试推断任何更具体的东西(例如,如果你注释为
Record<string, Type1>,这意味着你以后可以写mapper1.someOtherKey = bar1,所以编译器不能说mapper1的类型只有键"foo1"和"foo2"。)如果你想要推理和约束检查,你可以编写一个通用的帮助函数来做到这一点,如我上面的链接所示。如果这是有道理的,我可以写一个答案;如果没有,我错过了什么? -
@jcalz 这种方法看起来不错。您能否将其发布为答案以便可以接受?但是,我不明白您的解释,请您详细说明并提供相关文档的链接?
标签: typescript types