与问题TS 品牌字符串作为对象的键类似,我想使用品牌字符串作为我的字典的键,但然后更进一步。在我的用例中,键的品牌类型与保存在该键下的对象有关。
type HandlerA = { type: "A" };
type HandlerB = { type: "B" };
type HandlerVariant = HandlerA | HandlerB
type Id<T extends HandlerVariant> = string & { __type: T["type"] };
type HandlerDictionary = {
[id: string]: HandlerVariant;
}
通过使用Map
类型,我可以强制使用我的品牌Id
类型作为字典的键,如下所示
type HandlerMap<T extends HandlerVariant> = Map<Id<T>, T>;
不幸的是,这意味着整个映射必须是处理程序类型之一或联合HandlerVariant
类型,这与仅使用第一个示例中的字典具有几乎相同的效果。
我希望能够做的是取决于品牌,像这样推断它下面的处理程序的正确类型
const dict = {} as HandlerDictionary;
const key = "" as Id<HandlerA>;
const handler = dict[key];
由于key
带有HandlerA
type 标记,因此在该键下应该是 type 的对象,HandlerA
但 typescript 可悲地推断handler
为 type HandlerVariant
。
有没有办法键入这个字典,以便索引访问知道关键的品牌/价值关系?我知道有一些方法可以通过实现 getter 方法来做到这一点,但在我的情况下,这意味着需要进行实质性的重构工作。
// Invalid TS code example of the relationship
type BrandedHandlerDictionary = {
<T extends HandlerVariant>[id: Id<T>]: T;
}