useReducer hook,如何对动作进行类型检查? [英] useReducer hook, how to typecheck the action?
问题描述
我一直在查看有关 stackoverflow 的各种资源,但还没有找到任何(还)可以解决我遇到的这个问题的内容.我对打字稿有基本的了解,所以错误限制了我.
如果我将 action: any
留在我的减速器中,错误就会消失.但是,如果我使用 Action
键入它,则会出现过载错误.我对 TS 不够聪明,还没有弄清楚如何推理或解决它,它是关于 ReducerWithoutAction
在你的 initialState
中,content.file
设置为空字符串,但它应该是 <代码>文件代码>代替
type Content = {文件:文件;...};输入初始状态 = {内容:内容;...};常量初始状态 = {内容: {文件:",},...};
可以通过初始化一个对应类型的空对象来解决
const EMPTY_FILE = Object.freeze(new File([""], "filename"));常量初始状态 = {内容: {文件:EMPTY_FILE,},...};
你的reducer也有一个小错误
switch (action.type) {案例SET_FILE":返回 { ...状态,内容:action.payload };...}
应该是这个
switch (action.type) {案例SET_FILE":return { ...state, content: { ...state.content, file: action.payload } };...}
I've been looking through various resources here on stackoverflow and haven't found anything (yet) that clears up this issue I'm having. I have a basic understanding of typescript, so the errors have limited me.
If I leave action: any
in my reducer the error goes away. However, if I type it with Action
I get an overload error. I'm not clever enough with TS yet to figure out how to reason about this or resolve it, it's going on about ReducerWithoutAction<any>
, but I have no idea how I'm supposed to fix that. Any help would be appreciated.
I'm going to keep poking around in the interim.
// state types
type MainWrapperType = {
selection: number;
};
type Word = {
word: string;
translation: string;
wordTranscription: string;
partOfSpeech: string;
description: string;
example?: string;
};
type Notification = {
format: string;
message: string;
};
type Content = {
lessonName: string;
language: string;
topics: string[];
format: string;
file: File;
};
type InitialState = {
activeStep: number;
notification: Notification;
content: Content;
newWords: Word[];
initialTranscript: string;
modifiedTranscript: string;
transcriptSentences: string[];
};
const initialState = {
activeStep: 0,
notification: {
format: "",
message: "",
},
content: {
lessonName: "",
language: "",
topics: [],
format: "",
file: "",
},
newWords: [],
initialTranscript: "",
modifiedTranscript: "",
transcriptSentences: [],
};
// action types
interface SET_FILE {
type: "SET_FILE";
payload: File;
}
interface RESET_FILE {
type: "RESET_FILE";
}
interface SET_INIT_TRANSCRIPT {
type: "SET_INIT_TRANSCRIPT";
payload: string;
}
interface SET_MODIFIED_TRANSCRIPT {
type: "SET_MODIFIED_TRANSCRIPT";
payload: string;
}
interface ADD_SENTENCE {
type: "ADD_SENTENCE";
payload: string;
}
interface SET_SENTENCE_TRANSLATIONS {
type: "SET_SENTENCE_TRANSLATIONS";
payload: string[];
}
interface ADD_NEW_WORD {
type: "ADD_NEW_WORD";
payload: Word;
}
interface UPDATE_WORD {
type: "UPDATE_WORD";
payload: Word;
}
interface INCREMENT_ACTIVE_STEP {
type: "INCREMENT_ACTIVE_STEP";
}
interface DECREMENT_ACTIVE_STEP {
type: "DECREMENT_ACTIVE_STEP";
}
interface RESET_ACTIVE_STEP {
type: "RESET_ACTIVE_STEP";
}
interface RENDER_NOTIFICATION {
type: "RENDER_NOTIFICATION";
payload: Notification;
}
type Action =
| SET_FILE
| RESET_FILE
| SET_INIT_TRANSCRIPT
| SET_MODIFIED_TRANSCRIPT
| ADD_SENTENCE
| SET_SENTENCE_TRANSLATIONS
| ADD_NEW_WORD
| UPDATE_WORD
| INCREMENT_ACTIVE_STEP
| DECREMENT_ACTIVE_STEP
| RESET_ACTIVE_STEP
| RENDER_NOTIFICATION;
const reducer = (state: InitialState, action: Action) => {
switch (action.type) {
case "SET_FILE":
return { ...state, content: action.payload };
case "RESET_FILE":
return { ...state, content: initialState.content };
case "SET_INIT_TRANSCRIPT":
return { ...state, initialTranscript: action.payload };
case "SET_MODIFIED_TRANSCRIPT":
return { ...state, modifiedTranscript: action.payload };
case "ADD_SENTENCE":
return {
...state,
transcriptSentences: [...state.transcriptSentences, action.payload],
};
case "SET_SENTENCE_TRANSLATIONS":
return {
...state,
transcriptSentences: action.payload,
};
case "ADD_NEW_WORD":
return {
...state,
newWords: [...state.newWords, action.payload],
};
case "UPDATE_WORD":
const newWordsClone = [...state.newWords];
// console.log("nwc", newWordsClone);
const seekWord = (wordObject: any) =>
wordObject.word === action.payload.word;
const wordIndex = newWordsClone.findIndex(seekWord);
// console.log("wi", wordIndex, newWordsClone[wordIndex]);
newWordsClone[wordIndex] = action.payload;
return {
...state,
newWords: newWordsClone,
};
case "INCREMENT_ACTIVE_STEP": {
return { ...state, activeStep: state.activeStep + 1 };
}
case "DECREMENT_ACTIVE_STEP": {
return { ...state, activeStep: state.activeStep - 1 };
}
case "RESET_ACTIVE_STEP": {
return { ...state, activeStep: 0 };
}
case "RENDER_NOTIFICATION":
return { ...state, notification: action.payload };
default:
throw new Error();
}
};
const UploadPage = () => {
const [state, dispatch] = useReducer(reducer, initialState); <-- Error
...
}
In your initialState
, content.file
is set to an empty string, but it should be File
instead
type Content = {
file: File;
...
};
type InitialState = {
content: Content;
...
};
const initialState = {
content: {
file: "",
},
...
};
You can fix it by initializing a null object with the corresponding type
const EMPTY_FILE = Object.freeze(new File([""], "filename"));
const initialState = {
content: {
file: EMPTY_FILE,
},
...
};
There is also a small error in your reducer
switch (action.type) {
case "SET_FILE":
return { ...state, content: action.payload };
...
}
Should be this
switch (action.type) {
case "SET_FILE":
return { ...state, content: { ...state.content, file: action.payload } };
...
}
这篇关于useReducer hook,如何对动作进行类型检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!