我刚刚开始使用 React 的打字稿。我尝试将其与 React useReducer 钩子一起使用,但由于一个奇怪的错误而卡住了。
这是我的代码:
export interface ContractObj {
company: string;
negotiationRenewalDate: string;
periodEnd: string;
periodStart: string;
scheduleForRenewal: boolean;
contractId: string;
}
type State = {
loading: boolean;
error: boolean;
contractsData: ContractObj[];
};
type Action =
| { type: 'FETCH_SUCCESS'; payload: ContractObj[] }
| { type: 'FETCH_ERROR'; payload: null };
const initialState: State = {
loading: true,
error: false,
contractsData: []
};
const reducer = (state: State, action: Action) => {
switch (action.type) {
case 'FETCH_SUCCESS':
return {
loading: false,
error: false,
contractsData: action.payload
};
case 'FETCH_ERROR':
return {
loading: false,
error: true
};
default: {
return state;
}
}
};
export const Contracts: React.FC<Props> = () => {
const [state, dispatch] = useReducer(reducer, initialState);
当我将鼠标悬停在initialState
上时,它会给我一个错误,即类型"State"的参数不能分配给类型为"从不"的参数
确保在reducer
函数中始终返回相同的State
类型。如果将鼠标悬停在reducer
上,您会看到它当前具有以下签名:
const reducer: (state: State, action: Action) => State | {loading: boolean; error: boolean;}
也就是说,因为在case 'FETCH_ERROR'
中,contractsData
被省略了,这在State
中被定义为必需属性。可以通过向函数添加显式返回类型来轻松修复reducer
:
const reducer = (state: State, action: Action): State => { ... }
并且您得到(在这种情况下令人满意!)编译错误,抱怨缺少属性。最后,您可以在'FETCH_ERROR'
的情况下添加一个空的contractsData
数组,也可以在State
类型中将属性定义为可选。
解决方案 1:
switch (action.type) {
case 'FETCH_ERROR':
return {
loading: false,
error: true,
contractsData: []
}
}
解决方案 2:
type State = {
loading: boolean;
error: boolean;
contractsData?: ContractObj[];
};
操场