如何在TypeScript中键入导入的redux操作?

时间:2017-08-26 06:30:21

标签: typescript redux

我最近一直在使用TypeScript,而字符串文字在Redux操作和Reducer方面效果很好。 e.g:

const INCREMENT = "INCREMENT";
type INCREMENT = typeof INCREMENT;

const DECREMENT = "DECREMENT";
type DECREMENT = typeof DECREMENT;

interface IncrementAction {
  type: INCREMENT;
}
interface DecrementAction {
  type: DECREMENT;
}

type Actions = IncrementAction | DecrementAction;

const reducer = (state = 0, action: Actions) => {
  switch (action.type) {
    case INCREMENT:
      return state + 1;
    case DECREMENT:
      return state + 1;
    default:
      return state;
  }
};

我偶然发现的问题是键入动作,其中动作名称是从npm模块导入的。所以没有任何类型,代码看起来像:

import { SOME_ACTION } from 'npm-packaged-with-actions';

const reducer = (state = null, action) => {
  switch (action.type) {
    case SOME_ACTION:
      return state + 1;
    default:
      return state;
  }
}

如何为SOME_ACTION定义TypesScript类型?类型定义文件将SOME_ACTION导出为字符串,因此我无法将类型创建为:

type SOME_ACTION = typeof SOME_ACTION;

在这种情况下,SOME_ACTION是一种字符串而不是字符串文字,因此reducer操作匹配不起作用。

2 个答案:

答案 0 :(得分:0)

您可以指示编译器为您的代码生成定义文件,然后为您的模块提供定义。在导入模块时这样做,编译器将知道您在Typescript中定义的类型。

"compilerOptions": {
    "module": "commonjs",
    "declaration": true
}

有关在this问题

中找到的打字稿中编写npm模块的更多信息

答案 1 :(得分:0)

在Typescript中创建redux动作的一种非常简单的方法是类型保护。 This package通过输入带有提供类型的操作的“有效负载”键,以一种简单的方式完成。

所以你将行动定义为

export const ActionA = defineAction<{ url: string }>('Action A');

// And you can dispatch the action as
dispatch(ActionA.get({ url: 'http://www.googlel.com' });

但是对于来自另一个模块的行动,您可以这样做:

import { SOME_ACTION } from 'npm-packaged-with-actions';

// And you'll have an action based on the provided types
export const ActionOfModule = defineAction</* your desire type here */string>(SOME_ACTION);

// But again to this is an action creator, so to get the action you need to call "get" or "strictGet" from it
dispatch(ActionOfModule.strictGet('This is the payload of this action');