如何用Flow实现Redux的类型注解?附TypeScript示例对比
对应的Flow实现方案
我来帮你把这个TypeScript的Redux类型注解方案转换成Flow版本,核心逻辑保持一致,同时适配Flow的语法规则:
// @flow const PLAY: 'PLAY' = 'PLAY'; const RUN: 'RUN' = 'RUN'; class PlayAction { type: 'PLAY' = PLAY; payload: string; constructor(payload: string) { this.payload = payload; } } class RunAction { type: 'RUN' = RUN; payload: boolean; constructor(payload: boolean) { this.payload = payload; } } type Actions = PlayAction | RunAction; function dummyReducer(state: any, action: Actions) { switch(action.type) { case PLAY: { const typeTest = action.payload; // Flow会自动推断类型为string break; } case RUN: { const typeTest = action.payload; // Flow会自动推断类型为boolean break; } } }
关键差异与说明
- 字面量类型声明:Flow需要显式标注常量的字面量类型(比如
const PLAY: 'PLAY' = 'PLAY'),这样后续通过action.type判断时才能正确收窄类型,这一点和TypeScript的隐式推断有所不同。 - 类成员注解:Flow里类的属性需要先声明类型,再在构造函数中赋值,不像TypeScript可以通过
public关键字一键完成声明+赋值。如果你的Flow配置开启了类字段语法支持,也可以用更简洁的写法,但上面的写法是最通用兼容的。 - 类型收窄逻辑:Flow和TypeScript一样支持联合类型,并且在
switch语句中通过字面量判断,会自动收窄当前action的具体类型,所以payload的类型能被正确识别。 - Flow启用标识:文件开头的
// @flow是必须的,用来告诉Flow对该文件进行类型校验。
如果你的state有具体结构,也可以把any替换成自定义的状态类型,比如type AppState = { isPlaying: boolean, currentTrack: string },让类型校验更严格。
内容的提问来源于stack exchange,提问作者Lidor Avitan
相关产品推荐
相关产品推荐

