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

Javascript 在TypeScript中使用createSelector创建选择器工厂,javascript,typescript-typings,reselect,react-typescript,Javascript,Typescript Typings,Reselect,React Typescript,创建如下选择器: 从“重新选择”导入{createSelector}; 导出接口节点{ nodeId:number nodeName:string } 导出类型NodeState={ 节点:节点[]; 文本:字符串; }; const nodeListState=(state)=>state.nodeList; constbykey=(key:keyof NodeState)=>createSelector( nodeListState,(nodeList:NodeState)=>nodeLi

创建如下选择器:

从“重新选择”导入{createSelector};
导出接口节点{
nodeId:number
nodeName:string
}
导出类型NodeState={
节点:节点[];
文本:字符串;
};
const nodeListState=(state)=>state.nodeList;
constbykey=(key:keyof NodeState)=>createSelector(
nodeListState,(nodeList:NodeState)=>nodeList[key],
);
export const getNodes=byKey('nodes');

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

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

但是我们可以使
byKey
正常工作,方法是使它成为一个通用函数,这取决于调用它时使用的特定键。这样我们就知道
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],
);
constnodeliststate=(state:{nodeList:NodeState})=>state.nodeList;
constbykey=(key:K)=>createSelector(
nodeListState,
(节点列表)=>节点列表[键],
);

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

什么是
nodeListState
?AFAIK
createSelector()
接受一个或多个函数。请尝试删除
nodeListState,
(如果它不是函数),您可以尝试将const getNodes=(按键('nodes')导出为(nodeList:NodeState)=>Node[])
作为旁注;您可以根据需要为选择器命名任何名称,但约定是名称以
select
开头,因此
selectNodes
将是选择器的更好名称。
nodeListState
只选择状态的一部分。