【发布时间】:2020-10-15 02:06:29
【问题描述】:
我正在尝试将 typescript 与 react-redux 一起使用,但我在使用 reducer 时遇到了一些问题。使用当前设置,我遇到了错误,但我不知道为什么会这样。如果我偏离了 redux 文档中的方法,我可以得到一些有效但重复的东西。
-- 代码:-----
我在三个单独的目录中有三个文件,类似于:
store
|_actions
| |_auth.ts
|_reducers
| |_auth.ts
|_types
|_actionTypes.ts
|_auth.ts
在actions/auth.ts 文件内:
// actions/auth.ts
import { AuthActionTypes } from '../types/auth';
import * as actionTypes from '../types/actionTypes';
export const authStart = (): AuthActionTypes => {
return {
type: actionTypes.AUTH_START
};
};
export const authSuccess = ( token: string, userId: string ): AuthActionTypes => {
return {
type: actionTypes.AUTH_SUCCESS,
idToken: token,
userId: userId
};
};
export const authFail = ( error: Error ): AuthActionTypes => {
return {
type: actionTypes.AUTH_FAIL,
error: error
};
};
reducers/auth.ts 文件:
// reducers/auth.ts
import * as actionTypes from '../types/actionTypes';
import { AuthState, AuthActionTypes } from '../types/auth';
import { updateObject } from '../utility';
const initialState: AuthState = {
token: null,
userId: null,
error: null,
loading: false,
authRedirectPath: '/'
};
const authStart = ( state: AuthState, action: AuthActionTypes ) => {
return updateObject( state, {error: null, loading: true })
};
const authSuccess = ( state: AuthState, action: AuthActionTypes ) => {
return updateObject( state, {
token: action.idToken, // ##### this is giving me an error #####
userId: action.userId, // ##### this is giving me an error #####
error: null,
loading: false
});
};
const authFail = ( state: AuthState, action: AuthActionTypes ) => {
return updateObject( state, {
error: action.error, // ##### this is giving me an error #####
loading: false
});
};
const reducer = (state = initialState, action: AuthActionTypes): AuthState => {
switch (action.type) {
case actionTypes.AUTH_START: return authStart( state, action );
case actionTypes.AUTH_SUCCESS: return authSuccess( state, action );
case actionTypes.AUTH_FAIL: return authFail( state, action );
default:
return state;
};
};
export default reducer;
types/auth.ts 文件:
// types/auth.ts
import * as actionTypes from './actionTypes';
export interface AuthState {
token: null | string
userId: null | string
error: null | Error
loading: boolean
authRedirectPath: string
}
interface AuthStart {
type: typeof actionTypes.AUTH_START
}
interface AuthSuccess {
type: typeof actionTypes.AUTH_SUCCESS;
idToken: string;
userId: string;
}
interface AuthFail {
type: typeof actionTypes.AUTH_FAIL;
error: Error;
}
export type AuthActionTypes =
| AuthStart
| AuthSuccess
| AuthFail;
为了完整性,utility.ts 文件中的updateObject 函数在reducers/auth.ts 中使用
export const updateObject = <T, U>(oldObject: T, updatedProperties: U): T => {
return {
...oldObject,
...updatedProperties
};
};
----- 问题:-----
在reducers/auth.ts 中,问题在于authSuccess 箭头函数。我收到以下错误消息:
Property 'idToken' does not exist on type 'AuthActionTypes'.
Property 'idToken' does not exist on type 'AuthStart'.
我们可以看到idToken 和userId 都在interface 中定义。我不明白为什么它会引用AuthStart 而不是AuthSuccess。如果我导出 AuthSucess 接口并将其声明为该函数的操作类型,则错误消息将消失。有什么方法可以将 action 保持为 AuthActionType 还是需要明确声明为 AuthSucess 并且对于其他设置也一样?
另外,如果我删除所有箭头函数并在错误不再存在的情况下直接定义逻辑。那就是如果我有
// reducers/auth.ts
...
const reducer = (state = initialState, action: AuthActionTypes): AuthState => {
switch (action.type) {
...
case actionTypes.AUTH_SUCCESS:
return {
...state,
token: action.idToken,
userId: action.userId,
error: null,
};
...
有没有什么方法可以保持我现在的设置而不必直接在 swtich 案例中使用上述逻辑,因为我拥有的解决方案更容易维护?
【问题讨论】:
-
清楚地告诉你,你没有像 idToken 这样的属性的接口
标签: reactjs typescript redux