gpt4 book ai didi

reactjs - 如何在 Typescript 中为 React useReducer Hook 操作创建类型定义?

转载 作者:行者123 更新时间:2023-12-03 20:26:22 35 4
gpt4 key购买 nike

假设我们有 userReducer定义如下:

function userReducer(state: string, action: UserAction): string {
switch (action.type) {
case "LOGIN":
return action.username;
case "LOGOUT":
return "";
default:
throw new Error("Unknown 'user' action");
}
}

定义 UserAction 的最佳方式是什么?输入以便可以调用 dispatch两者都有 username有效载荷并且没有:

dispatch({ type: "LOGIN", username: "Joe"}});
/* ... */
dispatch({ type: "LOGOUT" });

如果类型是这样定义的:

type UserActionWithPayload = {
type: string;
username: string;
};

type UserActionWithoutPayload = {
type: string;
};

export type UserAction = UserActionWithPayload | UserActionWithoutPayload;

在 "LOGIN"情况下,编译器在 reducer 中抛出错误: TS2339: Property 'username' does not exist on type 'UserAction'.   Property 'username' does not exist on type 'UserActionWithoutPayload'.
如果使用可选成员定义类型:

export type UserAction = {
type: string;
username?: string;
}

然后编译器显示此错误: TS2322: Type 'string | undefined' is not assignable to type 'string'.   Type 'undefined' is not assignable to type 'string'.
这里缺少什么?也许整个方法是错误的?

项目使用 TypeScript 3.8.3 和 React.js 16.13.0。

最佳答案

经过数小时的挖掘和试验,通过 Typescript enum 找到了一个非常优雅的解决方案和联合类型的行动:

enum UserActionType {
LOGIN = "LOGIN",
LOGOUT = "LOGOUT"
}

type UserState = string;

type UserAction =
| { type: UserActionType.LOGIN; username: string }
| { type: UserActionType.LOGOUT }

function userReducer(state: UserState, action: UserAction): string {
switch (action.type) {
case UserActionType.LOGIN:
return action.username;
case UserActionType.LOGOUT:
return "";
default:
throw new Error();
}
}

function App() {
const [user, userDispatch] = useReducer(userReducer, "");

function handleLogin() {
userDispatch({ type: UserActionType.LOGIN, username: "Joe" });
}

function handleLogout() {
userDispatch({ type: UserActionType.LOGOUT });
}

/* ... */
}

使用上述方法没有错误或警告,此外还有一个非常严格的操作使用契约(Contract)。

关于reactjs - 如何在 Typescript 中为 React useReducer Hook 操作创建类型定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60513057/

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