score:1

Looks like this used to be fixed in late react-hook-form@6; along had came v7 which reintroduced the problem and seems to have been carried into v8 beta as well.

Regarding your question

"hint TypeScript that PathValue(TFormValues, typeof fieldPaths.firstName) is always going to be a string"

This will likely not work, because of what setValue has been defined to accept.

Ideally we'd push the issue to the authors and hope for a speedy fix, but in the absence of that, there are two solutions here:

  1. Either alias UnpackNestedValue and cast to it

    import { UnpackNestedValue, PathValue, Path } from "react-hook-form";
    
    type ValueArgument<f> = UnpackNestedValue<PathValue<f, Path<f>>>;
    
    setValue(fieldPaths.firstName, "David" as ValueArgument<TFormValues>);
    
  2. Extend the types all the way up to accept primitives

    import {
      UseFormReturn,
      FieldValues,
      FieldPath,
      UnpackNestedValue,
      FieldPathValue,
      SetValueConfig,
    } from "react-hook-form";
    import { FieldPaths } from "./types";
    
    type UseMyFormSetValue<TFieldValues extends FieldValues> = <
      TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
    >(
      name: TFieldName,
      value: UnpackNestedValue<FieldPathValue<TFieldValues, TFieldName>> | string,
      options?: SetValueConfig
    ) => void;
    
    interface UseMyFormReturn<TFormValues> extends UseFormReturn<TFormValues> {
      setValue: UseMyFormSetValue<TFormValues>;
    }
    
    type Props<TFormValues> = {
      methods: UseMyFormReturn<TFormValues>;
      fieldPaths: FieldPaths<TFormValues>;
    };
    
    const Person = <TFormValues>({ methods, fieldPaths }: Props<TFormValues>) => {
      const { register, setValue } = methods;
    
      const changeName = () => {
        setValue(fieldPaths.firstName, "David");
      };
    

Related Query

More Query from same tag