gpt4 book ai didi

javascript - 流提示 reducer 中的 Action 联合类型

转载 作者:行者123 更新时间:2023-11-28 17:52:06 24 4
gpt4 key购买 nike

Flow 对每个参数(action.location、action.weatherResult 和 action.error)抛出 3 个错误(未找到属性)。我发现的唯一解决方案是不联合并只有一种操作类型,其中 3 个不同的属性作为可选属性,但这些属性不是可选的,因此它不能解决我的问题。

操作

// @flow
import actionTypes from './index';

export type FetchWeatherStartAction = {
type: string,
location: string
};

export type FetchWeatherSuccessAction = {
type: string,
weatherResult: ?string
};

export type FetchWeatherFailAction = {
type: string,
error: string | false
};

export type WeatherAction = FetchWeatherStartAction | FetchWeatherSuccessAction | FetchWeatherFailAction;

const fetchWeatherStart = (location: string): FetchWeatherStartAction => ({
type: actionTypes.WEATHER_FETCH_START,
location
});

const fetchWeatherSuccess = (weatherResult: ?string): FetchWeatherSuccessAction => ({
type: actionTypes.WEATHER_FETCH_SUCCESS,
weatherResult
});

const fetchWeatherFail = (error: string | false): FetchWeatherFailAction => ({
type: actionTypes.WEATHER_FETCH_FAIL,
error
});

export {
fetchWeatherStart,
fetchWeatherSuccess,
fetchWeatherFail
}

操作类型

// @flow
const actionTypes = {
WEATHER_FETCH_START: 'WEATHER_FETCH_START',
WEATHER_FETCH_SUCCESS: 'WEATHER_FETCH_SUCCESS',
WEATHER_FETCH_FAIL: 'WEATHER_FETCH_FAIL'
}

export default actionTypes;

reducer

// @flow
import actionTypes from './../actions';
import type { WeatherAction } from './../actions/weather';

/*export type WeatherActionType = {
type: string,
error?: boolean | string,
weatherResult?: string | null,
location?: string
};*/

export type WeatherStateType = {
location: string,
fetchedFromServer: boolean,
isFetching: boolean,
fetchError: boolean | string,
weatherResult: ?string
};

const defaultState: WeatherStateType = {
location: 'Barcelona',
fetchedFromServer: false,
isFetching: false,
fetchError: false,
weatherResult: null
};

const weather = (state: WeatherStateType = defaultState, action: WeatherAction): WeatherStateType => {

switch (action.type) {

case actionTypes.WEATHER_FETCH_START:
return {
...state,
isFetching: true,
fetchError: false,
location: action.location
};

case actionTypes.WEATHER_FETCH_SUCCESS:
return {
...state,
fetchedFromServer: true,
isFetching: false,
fetchError: false,
weatherResult: action.weatherResult
};

case actionTypes.WEATHER_FETCH_FAIL:
return {
...state,
fetchedFromServer: false,
isFetching: false,
fetchError: action.error
};

default:
return state;
}

};

export default weather;

最佳答案

您尝试依赖的类型信息实际上并未编码在您的类型中。

例如在FetchWeatherStartAction的定义中:

export type FetchWeatherStartAction = {
type: string,
location: string
};

type 被声明为 string。任何字符串。

但是稍后,在这个 switch 情况下:

switch (action.type) {    
case actionTypes.WEATHER_FETCH_START:
...
action.location
...

您希望 Flow 知道 FetchWeatherStartActionWeatherAction 枚举的唯一可能替代方案,该枚举可能具有 'WEATHER_FETCH_START' 作为其 type 属性的值。仅根据类型,任何操作的类型都可以具有任何值。我们唯一可以确定的是它是一个字符串。

解决方案是将您的操作变体定义为更具体的类型,其中包含其合法值。

export type FetchWeatherStartAction = {
type: 'WEATHER_FETCH_START',
location: string
};

export type FetchWeatherSuccessAction = {
type: 'WEATHER_FETCH_SUCCESS',
weatherResult: ?string
};

export type FetchWeatherFailAction = {
type: 'WEATHER_FETCH_FAIL',
error: string | false
};

当您检查 type === 'WEATHER_FETCH_START' 时,Flow 可以确定实际类型为 FetchWeatherStartAction。这是可能的,因为它已经知道 actionWeatherAction 并且 WeatherAction 是一个枚举,这三种可能值。

有点不幸的是,您必须重复字符串文字,而不是引用常量。我知道人们对此感到不安,但在这种情况下我认为魔术常量被认为是不好的做法的所有原因都是由 Flow 的类型检查解决的。在 Javascript 中,使用语法标识符访问字段在语义上与通过字符串名称访问字段没有什么不同。

关于javascript - 流提示 reducer 中的 Action 联合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45277091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com