【问题标题】:Optional peer dependency only for TypeScript typings?仅适用于 TypeScript 类型的可选对等依赖项?
【发布时间】:2020-01-06 12:54:05
【问题描述】:

我有一个实现 React 组件的 TypeScript 库。可选功能之一是您可以将 Redux 存储的实例作为 prop 传递给组件以进行 Redux 集成。

<Component reduxStore={store}></Component>

这是一个可选属性,库只从 Redux 包中导入 Store 类型来强制类型。我的库的不使用 Redux 的使用者永远不需要这个依赖项,也不应该将它捆绑在他们的最终构建中。

目前我将 Redux 包包含为 dependency,这会导致一些问题。在 Redux 中,类型包含在包中,但 Store 类型在最近版本的 Redux 库中发生了变化。这意味着使用我的库和 TypeScript 并安装了自己的 Redux 版本作为依赖项的人可能会在我的库中安装的类型信息与其库中安装的相同类型之间遇到类型不匹配。

这似乎是将依赖项列为对等依赖项的好案例,但它是一个可选功能,如果库的使用者不打算使用集成功能,则不应要求他们安装 Redux。

有没有更好的方法来处理库的类型信息,以便依赖版本之间的类型的微小变化不会为我的库的使用者引发类型不匹配错误?

我能想到的两种可能的解决方案可能是:

  1. reduxStore 可选属性设置为any,在使用dispatch 方法之前,应该在Store 上执行空引用检查。这可能有效,但会降低在构建时捕获错误的能力。
  2. 也许有一种方法可以创建我自己的自定义 Store 接口,它只强制执行我计划使用的一小部分方法。
  3. 为那些想要与 Redux 集成的人创建一个单独的包来封装核心组件...这在架构上可能是一个非常令人头疼的问题。

【问题讨论】:

  • optionalDependencies 看起来很有希望
  • Npm 通常将这类依赖称为“对等依赖”,唯一的问题是如果它们不存在,typescript 如何看到它们
  • @Ferrybig,完全正确。因为如果消费者没有包它会抛出错误。但是,如果消费者甚至不使用 TypeScript,为什么他们必须安装他们从未打算使用的 Redux 库,只是为了获得他们永远不需要的类型?
  • 我的 tl;dr;我不认为你应该这样做。输入困难可能是过度控制实体做太多的潜在问题的结果。如果你的库的消费者想要使用 redux,他们应该有责任实现它并围绕你的库的组件创建包装器来实现它。您也将它们归类为使用 redux。如果他们想使用上下文 API 怎么办?如果他们想使用它,你可以在你的 README 中添加一个关于如何合并 redux 的小教程
  • 我明白你的意思。在我的情况下,该库已经是一个复杂库的包装器,我基本上创建了一系列包装器来将 complex library 与 Redux、Context API 和其他模式集成以使其更易于集成。听起来你在建议更接近我在问题中提到的Solution 3 的东西。我认为你所说的过度控制实体的说法有很多道理。

标签: reactjs typescript npm redux react-redux


【解决方案1】:

我的建议是提供一个接受泛型的可选 HOC。您的用户可以用它来包装您的组件。您关心的是不同的类型版本和绑定的依赖项。这意味着您别无选择,只能让用户决定他们使用什么类型。

const useStore:<Store = any> = (store: Store) => WrappedComponent => {
   return (props) => <WrappedComponent {...props} store={store} />
}

它在组件中的实现如下所示:

import {Store} from 'react-redux';
useStore<Store>(store)(Component)

【讨论】:

  • 感谢您的反馈。我认为删除 Redux 实现的类型是我现在要做的。为这个场景提供一个特定的 HOC 是一个可靠的想法,它将 redux 逻辑与我的组件的核心功能分离。 useStore 会与 React 钩子命名约定冲突,所以像 withStore 这样的东西是理想的。谢谢!
  • @AndrewCraswell 是的,这就是我的思考过程。如果您为要使用的每个通量实现都有单独的 HOC,则管理类型会更容易。如果你让用户有意识地选择合并 redux,你就不必检查 undefined 值(一个巨大的痛苦)。
猜你喜欢
  • 2019-06-20
  • 2020-09-14
  • 2018-10-25
  • 2023-01-25
  • 2019-10-18
  • 2020-09-21
  • 2018-04-22
  • 2019-10-03
相关资源
最近更新 更多