Мне трудно написать правильные типы для компонента React, подключенного к хранилищу с помощью селектора с помощью метода lodash.
Следуя соглашениям этой статьи , упрощенныйверсия моего компонента будет выглядеть так:
redurs / 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 как любой: subscription: _.find() as any,
в 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 как любые ...
используемые версии:
- реагировать 16.6.3
- избыточно 4.0.1
- реагироватьredux 5.1.1
- lodash-webpack-plugin 0.11.5 (сам использует lodash ^ 4.17.4)
- @ types / lodash 4.14.119