對于物件中處理程式函式的以下代碼(請參閱Playground Link),我使用 Record 型別:
interface User {
id: string;
avatar: string;
email: string;
name: string;
role?: string;
[key: string]: any;
}
interface State {
isInitialized: boolean;
isAuthenticated: boolean;
user: User | null;
}
type InitializeAction = {
type: 'INITIALIZE';
payload: {
isAuthenticated: boolean;
user: User | null;
};
};
type LoginAction = {
type: 'LOGIN';
payload: {
user: User;
isAuthenticated: boolean;
};
};
type LogoutAction = {
type: 'LOGOUT';
};
type RegisterAction = {
type: 'REGISTER';
payload: {
user: User;
};
};
type Action =
| InitializeAction
| LoginAction
| LogoutAction
| RegisterAction;
const handlers: Record<string, (state: State, action: Action) => State> = {
INITIALIZE: (state: State, action: InitializeAction): State => {
const {
isAuthenticated,
user
} = action.payload;
return {
...state,
isAuthenticated,
isInitialized: true,
user
};
},
LOGIN: (state: State, action: LoginAction): State => {
const { user } = action.payload;
return {
...state,
isAuthenticated: true,
user
};
},
LOGOUT: (state: State): State => ({
...state,
isAuthenticated: false,
user: null
}),
REGISTER: (state: State, action: RegisterAction): State => {
const { user } = action.payload;
return {
...state,
isAuthenticated: true,
user
};
}
};
我確實收到了處理程式函式的以下錯誤:
TS2322: Type '(state: State, action: InitializeAction) => State' is not assignable to type '(state: State, action: Action) => State'.
Types of parameters 'action' and 'action' are incompatible.
Type 'Action' is not assignable to type 'InitializeAction'.
Type 'LoginAction' is not assignable to type 'InitializeAction'.
Types of property 'type' are incompatible.
Type '"LOGIN"' is not assignable to type '"INITIALIZE"'.
uj5u.com熱心網友回復:
我相信這是因為逆變。 在這里,您可以找到有關此主題的更多資訊以及它在 typescript 中的作業原理。
為了鍵入您的handler物件,您應該使用映射型別:
interface User {
id: string;
avatar: string;
email: string;
name: string;
role?: string;
[key: string]: any;
}
interface State {
isInitialized: boolean;
isAuthenticated: boolean;
user: User | null;
}
type InitializeAction = {
type: 'INITIALIZE';
payload: {
isAuthenticated: boolean;
user: User | null;
};
};
type LoginAction = {
type: 'LOGIN';
payload: {
user: User;
isAuthenticated: boolean;
};
};
type LogoutAction = {
type: 'LOGOUT';
};
type RegisterAction = {
type: 'REGISTER';
payload: {
user: User;
};
};
type Action =
| InitializeAction
| LoginAction
| LogoutAction
| RegisterAction;
// type Handlers = {
// INITIALIZE: (state: State, action: InitializeAction) => State;
// LOGIN: (state: State, action: LoginAction) => State;
// LOGOUT: (state: State, action: LogoutAction) => State;
// REGISTER: (state: State, action: RegisterAction) => State;
// }
type Handlers = {
[Type in Action['type']]: (state: State, action: Extract<Action, { type: Type }>) => State
}
const handlers: Handlers = {
INITIALIZE: (state, action) => {
const {
isAuthenticated,
user
} = action.payload;
return {
...state,
isAuthenticated,
isInitialized: true,
user
};
},
LOGIN: (state, action) => {
const { user } = action.payload;
return {
...state,
isAuthenticated: true,
user
};
},
LOGOUT: (state) => ({
...state,
isAuthenticated: false,
user: null
}),
REGISTER: (state, action) => {
const { user } = action.payload;
return {
...state,
isAuthenticated: true,
user
};
}
};
操場
在這里你可以找到相關的答案。
看這個例子:
type Reducer = (state: State, action: Action) => State;
const reducer: Reducer = (state, action) => state
type ContravariantReducer = Record<string, Reducer>
// Arrow of inheritance has changed in an opposite way
const contravariant: ContravariantReducer = {
initialize: (state: State, action: InitializeAction) => state
}
// Arrow of inheritance has changed in an opposite way
const contravariant2: Record<string, (state: State, action: InitializeAction) => State> = {
initialize: (state: State, action: Action) => state
}
PS 除了打字稿型別問題,我堅信你應該根據@Dima Parzhitsky提供的 redux 檔案輸入你的 reducer
uj5u.com熱心網友回復:
這有點臟,但它有效:
const handlers: Record<string, (state: State, action: Action) => State> = {
INITIALIZE: (state: State, action: Action): State => {
const { isAuthenticated, user } = (action as InitializeAction).payload;
return {
...state,
isAuthenticated,
isInitialized: true,
user,
};
},
LOGIN: (state: State, action: Action): State => {
const { user } = (action as LoginAction).payload;
return {
...state,
isAuthenticated: true,
user,
};
},
LOGOUT: (state: State): State => ({
...state,
isAuthenticated: false,
user: null,
}),
REGISTER: (state: State, action: Action): State => {
const { user } = (action as RegisterAction).payload;
return {
...state,
isAuthenticated: true,
user,
};
},
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/407778.html
標籤:
上一篇:RjxJs7-訂閱終結器?
