如何在带有 TypeScript 的 redux 应用程序中使用选择器?

how to use selectors in redux app with TypeScript?

我尝试在我的 Redux 应用程序中使用重新选择库中的 selectors

我的选择器文件看起来:

import { createSelector } from 'reselect'

const postsSelectors = state => state.global.posts.allPostse;

export const getPosts = createSelector(
  [ postsSelectors ],
  (posts) => posts
);

然后我尝试在我的组件中使用,如下所示:

const mapStateToProps = (state) => ({
  posts: getPosts(state),
});

当我尝试编译所有这些时,出现了这个错误:

我猜测我是如何声明道具类型的,目前看起来像这样:

interface Props{
 posts(state: any): any
 loadStories(): void;
};

请帮我解决这个问题。提前致谢。

TypeScript 不需要数组作为第一个参数。只需将您的选择器函数作为参数传递给 createSelector,如

export const getPosts = createSelector(
  postsSelectors,
  (posts) => posts
);

更多类型的例子:

  1. 描述类型
type TPostData = {
  type: string;
};

type TPostsState = TPostData[];

type TState = {
  posts: TPostsState;
};
  1. 创建选择器
// get all posts
export const selectPosts = (state: TState): TPostsState => state.posts;

// get new posts
export const selectNewPosts = createSelector<
  TState,
  TPostsState,
  TPostData[]>(
    selectPosts,
    (posts) => posts.filter(({ type }) => type === 'new'),
  );

结果:您已获得类型参数为 'new' 的所有帖子。

如果您使用 typescript@≥4.2,在 reselect@4.1.5 泛型输入签名中略有变化。所以现在需要指定为:createSelector<Selectors extends SelectorArray, Result>

<Selectors extends SelectorArray, Result>

export type Selector<
  // The state can be anything
  State = any,
  // The result will be inferred
  Result = unknown,
  // There are either 0 params, or N params
  Params extends never | readonly any[] = any[]
  // If there are 0 params, type the function as just State in, Result out.
  // Otherwise, type it as State + Params in, Result out.
> = [Params] extends [never]
  ? (state: State) => Result
  : (state: State, ...params: Params) => Result

export type SelectorArray = ReadonlyArray<Selector>

示例:

// get all posts
export const selectPosts = (state: TState): TPostsState => state.posts;

// get new posts
export const selectNewPosts = createSelector<
  [Selector<TState, TPostsState>],
  TPostData[]
>(
    selectPosts,
    (posts) => posts.filter(({ type }) => type === 'new'),
  );

但一般来说,对于较新的 TS,你现在不应该手动指定类型,因为它们将被自动推断。

如果您得到 TS4023: Exported variable 'X' has or is using the name '$CombinedState' from external module,请参考 Whosebug 的回答 或尝试在tsconfig.json 文件。