reactjs - React w/Typescript: useReducer, Action Interface w/ Union Type
问题描述
所以我试图使用钩子创建一个减速器,该useReducer
钩子使用一个名为 Action 的接口,该接口具有一个可以是 astring
或 a的属性number
:
type Actions = 'update_foo' | 'update_bar';
interface Action {
type: Actions;
value?: number | string;
}
我还为初始状态和const
设置默认状态定义了一个接口:
interface InitialState {
foo: number;
bar: string;
}
const defaultState: InitialState = {
foo: 1,
bar: 'bar'
}
然后是我的减速器功能:
const fooBarReducer: React.Reducer<InitialState, Action> = (state: InitialState, action: Action) => {
switch(action.type) {
case 'update_foo':
return { ...state, foo: action.value };
case 'update_bar':
return { ...state, bar: action.value };
default:
return defaultState;
}
}
我遇到的这个问题是 Typescript 似乎不喜欢联合类型 def 并引发以下错误:
Type '(state: InitialState, action: Action) => { foo: string | number | undefined; bar: string | number; }' is not assignable to type 'Reducer<InitialState, Action>'.
Call signature return types '{ foo: string | number | undefined; bar: string | number; }' and 'InitialState' are incompatible. The types of 'foo' are incompatible between these types.
Type 'string | number | undefined' is not assignable to type 'string | number'.
Type 'undefined' is not assignable to type 'string | number'.
我之前使用过联合类型,但没有使用 ReactsuseReducer
钩子。这可以通过在接口foo
中单独使用属性来解决,但如果可能的话,我想使用联合类型。bar
Action
非常感激任何的帮助!!
解决方案
问题似乎是您在字段级别使用类型联合。这意味着任何字段都可以是任何类型(例如:type
可能是update_foo
并且value
可能"str"
是无效的)。如果将Action
interface
其更新为动作的联合(而不是每个字段都是联合),则可以实现您正在寻找的类型安全。
现在,当type
is时update_foo
,TypeScript 会知道value
必须是number
. TypeScript 什么时候type
会update_bar
知道value
必须是string
.
我还假设在这种update_bar
情况下,那应该bar
代替foo
?
type Action =
| { type: "update_foo"; value: number }
| { type: "update_bar"; value: string };
interface InitialState {
foo: number;
bar: string;
}
const defaultState: InitialState = {
foo: 1,
bar: "bar"
};
const fooBarReducer: React.Reducer<InitialState, Action> = (
state: InitialState,
action: Action
) => {
switch (action.type) {
case "update_foo":
return { ...state, foo: action.value };
case "update_bar":
return { ...state, bar: action.value };
default:
return defaultState;
}
};
有关更多详细信息,您可能正在寻找的模式是受歧视的 unions。
推荐阅读
- prometheus - 如何解决 Prometheus 配置错误:文件服务发现配置必须包含至少一个路径名
- swift - 以 JSON 格式获取 socket.io 数据
- excel - 将数据行复制到新位置时,数据被正确复制,但在数据行之间插入了空白行
- excel - RefreshAll 后 VBA 未按正确顺序计算
- haskell - Haskell:Desugaring State do notation
- ios - 将 UITbale 视图连接到 firebase 实时数据库的解包错误
- ionic-framework - 在屏幕外标签中初始化传单地图(当前不可见的离子幻灯片)
- javascript - 如何在实时搜索中使整行可点击
- c - 调用函数时元素消失 - LZW 压缩
- javascript - 如何正确显示我的 Knockout 应用程序的模板元素?