【发布时间】:2019-05-07 22:08:07
【问题描述】:
我很难为使用 lodash 方法通过选择器连接到 redux 存储的 React 组件编写正确的类型。
在this article's conventions 之后,我的组件的简化版本如下所示
reducers/index.ts
interface ApiState {
api: {
entities: {
subscriptions: {
[pk: number]: {
imageUrl: string;
pk: number;
slug: string;
title: string;
};
};
};
result: {
subscriptions: never[];
};
};
…
};
export type RootState =
| (ApiState &
FirebaseState & {
router: Reducer<RouterState, LocationChangeAction>;
})
| {};
src/components/MyComponent.tsx
import React, {PureComponent} from "react";
import {connect} from "react-redux";
import {RootState} from "~/reducers";
interface OwnProps {
label: "host" | "experience";
score: number;
subscriptionPk: number;
}
interface StateProps {
subscription?: {
pk: number;
title: string;
};
}
const selectSubscriptions = state => state.api.entities.subscriptions;
const mapStateToProps = (state: RootState, ownProps: OwnProps): StateProps => ({
subscription: _.find(selectSubscriptions(state), {
pk: ownProps.subscriptionPk,
}) as any,
});
type Props = StateProps & OwnProps;
export default connect<StateProps, {}, OwnProps>(mapStateToProps)(
class extends PureComponent<Props> {
render() {
const {label, score, subscription} = this.props;
return (
<div>
{label} {score} {subscription.title}
</div>
);
}
},
);
src/typings.d.ts
// lodash global typing - begin
declare namespace _ {} // eslint-disable-line no-unused-vars
// lodash global typing - end
上面的代码在 lodash find 方法被转换为 any 之前工作:subscription: _.find() as any, in mapStateToProp。
如果我删除 as any,我会收到以下错误:
$ tsc --project tsconfig.json
src/components/MyComponent.tsx:37:3 - error TS2322: Type '{ pk: { toString: ...; toFixed: ...; toExponential: ...; toPrecision: ...; valueOf: ...; toLocaleString: ...; [Symbol.iterator]: ...; }; } | undefined' is not assignable to type '{ pk: number; slug: string; title: string; } | undefined'.
Type '{ pk: { toString: ...; toFixed: ...; toExponential: ...; toPrecision: ...; valueOf: ...; toLocaleString: ...; [Symbol.iterator]: ...; }; }' is missing the following properties from type '{ pk: number; slug: string; title: string; }': slug, title
37 subscription: _.find(selectSubscriptions(state), {
~~~~~~~~~~~~
src/components/MyComponent.tsx:26:3
26 subscription?: {
~~~~~~~~~~~~
The expected type comes from property 'subscription' which is declared here on type 'StateProps'
Found 1 error.
为什么 lodash 不能正确识别类型?我宁愿不必将所有 lodash 调用都转换为 any...
使用的版本:
- 反应 16.6.3
- redux 4.0.1
- react-redux 5.1.1
- lodash-webpack-plugin 0.11.5(本身使用 lodash ^4.17.4)
- @types/lodash 4.14.119
【问题讨论】:
标签: typescript redux react-redux lodash typescript-typings