【问题标题】:Assign correct types to Reselect createSelector function为 Reselect createSelector 函数分配正确的类型
【发布时间】:2017-11-01 12:51:35
【问题描述】:

编辑:添加 package.json 摘录

我正在尝试在现有的 React 项目中实现 typescript,但我在使用 Reselect 库时遇到了困难。 Typescript 编译器坚持导入 createSelector 函数的第一个定义,但未能识别出我的函数的签名对应于另一个定义。

它导入的定义:

export function createSelector<S, R1, T>(
  selector: Selector<S, R1>,
  combiner: (res: R1) => T,
): OutputSelector<S, T, (res: R1) => T>;

我想用的那个:

export function createSelector<S, R1, R2, T>(
  selectors: [Selector<S, R1>,
              Selector<S, R2>],
  combiner: (res1: R1, res2: R2) => T,
): OutputSelector<S, T, (res1: R1, res2: R2) => T>;

这是我的实际代码:

// groups.selectors.tsx

import { Selector, createSelector } from 'Reselect';
import { IGroup, IQuestionnaire, IGroupReselect, IState } from '../interfaces';

const getGroups:Selector<IState, IGroup[]> = state => state.groups;
const getQuestionnaires:Selector<IState, IQuestionnaire[]> = state => state.questionnaires;

export const groups = createSelector<IState, IGroup[], IQuestionnaire[], IGroupReselect>(
  [getGroups, getQuestionnaires],
  (g, q) => {

    return g.map(group => Object.assign(
      {},
      group,
      {questionnaires: group.questionnairesIds.map(id => q.find(q => q.id === id))}
    ));
  }
);

如果对我有任何帮助,这里是我的 ts.config:

{
  "compilerOptions": {
    "module": "es6",
    "target": "es6",
    "outDir": ".temp",
    "allowSyntheticDefaultImports": true,
    "baseUrl": "src",
    "noImplicitAny": false,
    "sourceMap": false,
    "jsx": "preserve",
    "strict": true,
    "moduleResolution": "node"
  },
  "exclude": [
    "node_modules"
  ],
  "files": [
    "typings.d.ts"
  ]
}

我对 TypeScript 并不完全满意,所以我的实现肯定有问题。让我烦恼的是,如果我编写最简单的重新选择器,即只有 1 个选择器和 arity 1 的组合器,它会通过类型检查,这给我的印象是编译器没有在重载函数中正确选择正确的定义重新选择index.d.ts

这是我的 package.json 的相关部分:

"dependencies": {
    "react": "^15.5.4",
    "react-dom": "^15.5.4",
    "react-redux": "^5.0.5",
    "react-router": "^4.1.1",
    "react-router-dom": "^4.1.1",
    "redux": "^3.6.0",
    "redux-devtools-extension": "^2.13.2",
    "redux-thunk": "^2.2.0",
    "reselect": "^3.0.1"
  },
  "devDependencies": {
    "@types/react": "^15.0.25",
    "@types/react-router-dom": "^4.0.4",
    "@types/redux-thunk": "^2.1.0",
    "typescript": "^2.3.3"
  },

【问题讨论】:

  • 我会首先检查您是否拥有链接到的 Reselect 的 index.d.ts 版本。直到最近才添加对选择器数组的支持(我认为是 3.0 版)。您可以完全省略数组;重新选择不需要它(尽管大多数示例都使用它。)
  • 我的依赖版本可能确实有问题。至于数组选择器,我正在运行 reselect 3.0.1,所以它应该不是问题。

标签: reactjs typescript redux typescript2.0 reselect


【解决方案1】:

我可能是错的,但从这里 this issue,这似乎是由于语言如何将您的异构数组 [getGroups, getQuestionnaires] 推断为数组而不是元组。

强制第一个参数为元组类型会使其工作,但会导致不必要的样板

const getGroups:Selector<IState, IGroup[]> = state => state.groups;
const getQuestionnaires:Selector<IState, IQuestionnaire[]> = state => 
  state.questionnaires;

const selectors: [Selector<IState, IGroup[]>, Selector<IState, IQuestionnaire[]>] = [getGroups, getQuestionnaires]

export const groups = createSelector<IState, IGroup[], IQuestionnaire[], IGroupReselect>(
  selectors,
  (g, q) => {

    return g.map(group => Object.assign(
      {},
      group,
      {questionnaires: group.questionnairesIds.map(id => q.find(q => q.id === id))}
    ));
  }
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多