繁体   English   中英

在 TypeScript 中使用 createSelector 创建选择器工厂

[英]Creating a selector factory with createSelector in TypeScript

像这样创建选择器:

 import { createSelector } from 'reselect'; export interface Node { nodeId: number nodeName: string } export type NodeState = { nodes: Node[]; text: string; }; const nodeListState = (state) => state.nodeList; const byKey = (key: keyof NodeState) => createSelector( nodeListState, (nodeList: NodeState) => nodeList[key], ); export const getNodes = byKey('nodes'); export const getText = byKey('text');

在其他地方,使用选择器:

 import { useSelector } from 'react-redux'; const nodes = useSelector(selectors.getNodes); nodes.map(...)

这会导致错误:

Property 'map' does not exist on type 'string | Node[]'.
  Property 'map' does not exist on type 'string'.  TS2339

变量节点实际上是一个数组。 我对这一切都错了吗? 设置在TS中通过键创建选择器的function的正确方法是什么?

这里发生的是 typescript 无法区分byKey('nodes')byKey('text') 它们都返回相同的类型,即选择文本string或节点Node[]的选择器。 因此const nodes = useSelector(selectors.getNodes)返回联合string | Node[] string | Node[]并且您收到一个错误,即string不是数组。

解决此问题的一种方法是byKey并分别创建两个选择器。

但是我们可以通过将byKey通用 function 来使其正常工作,这取决于调用它的特定键。 这样我们就知道byKey('nodes')选择了'nodes'属性。

如果你对nodeListState应用正确的类型,你实际上不需要将第二个选择器的参数指定为nodeList: NodeState因为它可以根据第一个选择器的返回类型来推断。

const nodeListState = (state: {nodeList: NodeState}) => state.nodeList;

const byKey = <K extends keyof NodeState>(key: K) => createSelector(
  nodeListState, 
  (nodeList) => nodeList[key],
);

现在getNodes选择Node[]并且getText选择string

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM