Home > Back-end >  Passing generic type to object inside method
Passing generic type to object inside method

Time:02-05

I'd like to make my custom hook reusable as much as I can.

I'd like to pass generic type (cause for different forms I will have different errors fields) to my const errors: Y = {}; which is empty now, but can be returned as object with validation errors.

In line 4 const errors: Y = {}; I received an error:

Type '{}' is not assignable to type 'Y'. 'Y' could be instantiated with an arbitrary type which could be unrelated to '{}'.ts(2322)

CODESANDBOX DEMO: HERE

validate.ts:

export default function validate<T extends Record<string, string>, Y>(
  values: T
): Y {
  const errors: Y = {};

  if (!values.title) {
    errors.title = "Title is required";
  }

  return errors;
}

Place where I use validate method:

setErrors(validate<T, Y>(state));

function useFormState<T extends Record<string, string>, Y>(
  initialValue: T,
  initialErrors: Y
) {
  const [state, dispatch] = useReducer(
    (prevState: T, { name, value }: InputChangeEvent["target"]) => ({
      ...prevState,
      [name]: value
    }),
    initialValue
  );

  const [errors, setErrors] = useState<Y>(initialErrors);

  const handleSubmit = (evt: FormEvent) => {
    evt.preventDefault();
    setErrors(validate<T, Y>(state));
  };

  return [state, errors, handleSubmit] as const;
}

export default useFormState;

I tried to pass different type to this method const errors: ErrorValues = {}; But then I have two different issues:

  1. My method is not reusable, cause I cannot use it with different form.
  2. When I want to call setErrors(validate(state)); I received an another error:

Argument of type 'ErrorValues' is not assignable to parameter of type 'SetStateAction'. Type 'ErrorValues' is not assignable to type '(prevState: Y) => Y'. Type 'ErrorValues' provides no match for the signature '(prevState: Y): Y'.ts(2345)

CodePudding user response:

you can try this maybe ? Have past this code temporary in your sandbox, seems ok

export default function validate<
  T extends Record<string, string>,
  Y extends Record<string, unkown>
>(values: T): Y {
  let errors: Y = {} as Y;

  if (!values.title) {
    errors = {
      ...errors,
      title: "Title is required ",
    };
  }

  return errors;
}
  •  Tags:  
  • Related