【问题标题】:Nested ternary condition inside Typescript type extendsTypescript 类型中的嵌套三元条件扩展
【发布时间】:2019-11-11 03:10:48
【问题描述】:

我正在从 JavaScript 开发过渡到强制执行 TypeScript 输入的雇主。我为包含典型 .on(event, handler) 的模型创建了一个 Interface

我的同事想出了一些我认为可以理解的代码,但是它使用了这种嵌套的三元语句,使阅读变得混乱。

interface Model {
    ...
    on<T extends "added" | "failed" | "initialized" | "changed" | "removed"> (
        event: T,
        handler: T extends "changed" | "removed"
                 ? (T extends "changed"
                     ? (model: Model, entity: Entity, data: object) => void
                     : (model: Model, id: string) => void)
                 : (model: Model, entity: Entity) => void,
        context?: object
    ): void
}

这似乎是一种为 handler 参数提供不同签名的方法,基于 event 被传入。

它似乎有效,但我想知道是否有不同的模式来编写它,以便更容易阅读和理解。

【问题讨论】:

  • 是否有另一个 Stack Exchange 网站更适合提出这个问题?
  • 我可能会索引到映射接口,而不是在这里使用嵌套条件;如果在我使用真正的计算机之前没有人到达这里,我会发布答案。

标签: typescript interface extends


【解决方案1】:

我会考虑使用映射接口并对其进行索引,因为“将字符串文字映射到特定类型”的操作在 TypeScript 中由对象类型自然地提供给您。虽然您可以使用条件类型来做到这一点,但它确实更难阅读和维护。

作为重构的第一步,我会这样做:

// use a mapping from event name to event handler type
interface EventHandlerMap {
  added: (model: Model, entity: Entity) => void;
  failed: (model: Model, entity: Entity) => void;
  initialized: (model: Model, entity: Entity) => void;
  changed: (model: Model, entity: Entity, data: object) => void;
  removed: (model: Model, id: string) => void;
}

interface Model {
  on<T extends keyof EventHandlerMap>(
    event: T,
    handler: EventHandlerMap[T], // index into the mapping
    context?: object
  ): void;
}

您可以说服自己它的行为方式相同(或使用最后的代码链接查看)。 EventHandlerMap 接口只是一个帮助器,您实际上并未分配给任何对象。但它描述了从Model.on()event 类型的T 参数到handler 参数的映射。我们使用lookup typeshandler 类型提取为EventHandlerMap[T]

也许可以进一步重构这个......例如,所有这些都是返回void的函数,第一个参数是Model;也许你可以让EventHandlerMap 只跟踪不同事件之间的不同之处,然后使用更复杂的类型操作,但这可能比它的价值更麻烦。

好的,希望对您有所帮助;祝你好运!

Link to code

【讨论】:

  • 欣赏周到的回应。我认为您使用映射器接口和使用keyof 来链接eventhandler 方法对我来说很有意义。我喜欢它提供了灵活性,可以根据需要以其他代码熟悉的样式添加新映射。我同意进一步重构以减少一些冗余可能是矫枉过正,而这对其他重载语言来说感觉更自然。感谢您的宝贵时间和反馈。
猜你喜欢
  • 2016-06-10
  • 2023-01-10
  • 2021-12-05
  • 2020-10-30
  • 2017-09-20
  • 2020-11-09
  • 2020-08-18
  • 1970-01-01
  • 2019-02-03
相关资源
最近更新 更多