useReducer hook,如何对动作进行类型检查? [英] useReducer hook, how to typecheck the action?

查看:35
本文介绍了useReducer hook,如何对动作进行类型检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在查看有关 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆