简体   繁体   English

TypeScript:键入自定义表单挂钩时出现问题

[英]TypeScript: Problem typing a cusom Form hook

I know this is gonna be messy and terrible but while I have the TypeScript basics down, I'm having trouble typing the more advanced concepts, particularly typing useReducer hooks.我知道这会很混乱而且很糟糕,但是虽然我已经掌握了 TypeScript 的基础知识,但我在输入更高级的概念时遇到了麻烦,尤其是输入 useReducer 钩子。 Here's my code with what I have so far, but I understand I have probably mistyped some items.这是我到目前为止的代码,但我知道我可能打错了一些项目。

import { useCallback, useReducer } from 'react';

interface Inputs {
  id: string;
  value: string;
  inputIsValid: boolean;
}

interface FormState {
  inputs: Inputs[];
  isValid: boolean;
}

interface FormAction {
  inputs: Inputs;
  type: string;
  value: string;
  inputId: string;
  isValid: boolean;
  formIsValid: boolean;
}

const formReducer = (state: FormState, action: FormAction): FormState => {
  switch (action.type) {
    case 'INPUT_CHANGE':
      let formIsValid = true;
      for (const inputId in state.inputs) {
        if (!state.inputs[inputId]) continue;
        if (inputId === action.inputId)
          formIsValid = formIsValid && action.isValid;
        else formIsValid = formIsValid && state.inputs[inputId].inputIsValid;
      }
      return {
        ...state,
        inputs: {
          ...state.inputs,
          [action.inputId]: { value: action.value, isValid: action.isValid },
        },
        isValid: formIsValid,
      };
    case 'SET_DATA':
      return {
        inputs: action.inputs,
        isValid: action.formIsValid,
      };
    default:
      return state;
  }
};

export const useForm = (
  initialInputs: Inputs,
  initialFormValidity: boolean
) => {
  const [formState, dispatch] = useReducer(formReducer, {
    inputs: initialInputs,
    isValid: initialFormValidity,
  });
  const inputHandler = useCallback(
    (id: string, value: string, isValid: boolean) => {
      dispatch({
        type: 'INPUT_CHANGE',
        value: value,
        isValid: isValid,
        inputId: id,
      });
    },
    []
  );
  const setFormData = useCallback(
    (inputData, formValidity: boolean) => {
      dispatch({
        type: 'SET_DATA',
        inputs: inputData,
        formIsValid: formValidity,
      });
    },
    []
  );
  return [formState, inputHandler, setFormData];
};

I also have a custom Input component that uses the formHook.我还有一个使用 formHook 的自定义 Input 组件。 This is all used from following Max Schwarzmuellers MERN stack course, which is super helpful but doesn't include typing.这都是从 Max Schwarzmuellers MERN stack course 中使用的,这非常有用,但不包括打字。 I've tried following his typescript course but haven't finished it yet.我已经尝试过他的 typescript 课程,但还没有完成。 My main problems come with the useReducer functions, which are overloaded with issues.我的主要问题来自 useReducer 函数,这些函数因问题而超载。 Which look something like this:看起来像这样:

No overload matches this call.
  Overload 1 of 5, '(reducer: ReducerWithoutAction<any>, initializerArg: any, initializer?: undefined): [any, DispatchWithoutAction]', gave the following error.
    Argument of type '(state: FormState, action: FormAction) => FormState' is not assignable to parameter of type 'ReducerWithoutAction<any>'.
  Overload 2 of 5, '(reducer: (state: FormState, action: FormAction) => FormState, initialState: FormState, initializer?: undefined): [FormState, Dispatch<...>]', gave the following error.
    Type 'Inputs' is not assignable to type 'Inputs[]'.ts(2769)
form-hook.tsx(10, 3): The expected type comes from property 'inputs' which is declared here on type 'FormState'

Please help...请帮忙...

The problem is initialInputs is typed to Inputs when it should be Inputs[] .问题是initialInputs在应该是Inputs[]时被输入到Inputs So you need to re-type that arg on useForm .因此,您需要在useForm上重新键入该参数。

export const useForm = (
  initialInputs: Inputs[],
  initialFormValidity: boolean
) => {
  const [formState, dispatch] = useReducer(formReducer, {
    inputs: initialInputs,
    isValid: initialFormValidity
  });

Probably this needs changing in the action type as well?可能这也需要改变动作类型? The change probably will lead you to more changes, but the above should fix the error you were seeing and uncover the rest.更改可能会导致您进行更多更改,但以上内容应该可以解决您看到的错误并发现 rest。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM