为 Reselect createSelector 函数分配正确的类型
2017-05-31
13442
编辑:添加了 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 个选择器和 1 个元数的组合器的重新选择器,它会通过类型检查,这让我觉得编译器没有在 Reselect 的 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"
},
1个回答
我可能错了,但从这个
这个问题
来看,它似乎是由语言如何将你的异构数组
[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))}
));
}
);
Evan Sebastian
2017-06-01