简体   繁体   English

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

[英]How to type imported redux actions in TypeScript?

I've been playing around with TypeScript recently and string literals work great with Redux actions and reducers. 我最近一直在使用TypeScript,并且字符串文字可与Redux操作和reducer一起很好地工作。 eg: 例如:

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;
  }
};

The problem I've stumbled upon is typing actions where the action name is imported from an npm module. 我偶然发现的问题是输入从npm模块导入动作名称的动作。 So without any types, code would look like: 因此,没有任何类型,代码将如下所示:

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;
  }
}

How would I define the TypesScript type for SOME_ACTION? 如何为SOME_ACTION定义TypesScript类型? The type definition file exports SOME_ACTION as a string, so I cannot create the type as: 类型定义文件将SOME_ACTION导出为字符串,因此我无法将类型创建为:

type SOME_ACTION = typeof SOME_ACTION;

In this case SOME_ACTION is a type of string rather than a string literal, so the reducer action matching doesn't work. 在这种情况下,SOME_ACTION是字符串的类型,而不是字符串文字,因此reducer操作匹配不起作用。

You can instruct the compiler to generate a definition file for your code and then provide the definition with your module. 您可以指示编译器为代码生成定义文件,然后将定义提供给模块。 Doing so when you import the module the compiler will know about the types you defined in Typescript. 这样做在导入模块时,编译器将知道您在Typescript中定义的类型。

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

More information about writing npm module in typescript you can find on this question 有关在打字稿中编写npm模块的更多信息,您可以在这个问题上找到

A very simple way of creating redux actions in Typescript is type guards. 在Typescript中创建redux动作的一种非常简单的方法是类型保护。 This package has done in a vey simple way by typing the key called "payload" of actions with a provided type. 通过使用提供的类型键入称为操作的“有效负载”的键,可以非常简单地完成此程序包

So you define your action as 因此,您将动作定义为

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

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

But for the action coming from another module you can do: 但是对于来自另一个模块的操作,您可以执行以下操作:

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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM