typescript 如何使用React的useState钩子设置泛型类型的arg?

8cdiaqws  于 2023-11-20  发布在  TypeScript
关注(0)|答案(1)|浏览(147)

我正在构建一个表单组件,它接受一个接受泛型类型的arg的回调,但是当我试图更新表单中的arg时,我遇到了一些困难:
下面是我调用表单组件的方式:

// FormPage.tsx

type MyConfirmationOptions = {
  isFoo?: boolean;
};

<MyForm<MyConfirmationOptions>
  onConfirm={({ isFoo }) => {
    api.postData(isFoo)
  }}
/>

字符串
这是我遇到问题的表格:

// MyForm.tsx

interface MyFormProps<T> {
  onConfirm: (confirmationOptions: T) => void;
}

export function MyForm<T>(
  props: PropsWithChildren<MyFormProps<T>>,
){
  const [confirmationOptions, setConfirmationOptions] = useState<T>({} as T);

  const onSubmit = (event: FormEvent) => {
    event.preventDefault();
    onConfirm(confirmationOptions);
  };

  return (
    ...
    <Checkbox
      ...
      onChange={async () => {
        setConfirmationOptions(confirmationOptions => {
          ...confirmationOptions,
          isFoo: !confirmationOptions.isFoo
        })
      }}
      checked={confirmationOptions.isFoo}
    />
  )  
}


我得到的第一个错误是在onChange中,当我试图扩展confirmationOptions时:* 类型'T'必须有一个返回迭代器的'Symbol.iterator'方法 *
第二个错误是在checked prop中:Property 'isFoo' does not exist on type 'T'
最后,我不喜欢将初始值useState转换为T
我检查了我的tsconfig,我有以下内容:

"lib": ["dom", "dom.iterable", "esnext"],

js4nwp54

js4nwp541#

我得到的第一个错误是在onChange中,当我尝试扩展confirmationOptions:类型'T'必须有一个'Symbol.iterator'方法返回迭代器
如果T太通用,你不能假设它是可扩展的。
第二个错误是在检查的prop中:类型'T'上不存在属性'isFoo'
如果T太通用,你不能假设它有isFoo属性。
如果你需要在表单中引用isFoo属性,你必须像这样缩小条件:

type HasFoo = {
  isFoo?: boolean;
}

type MyConfirmationOptions = { other stuff... } & HasFoo;

interface MyFormProps<T> {
  onConfirm: (confirmationOptions: T) => void;
}

function MyForm<T extends HasFoo>({ onConfirm }: PropsWithChildren<MyFormProps<T>>){
  const [confirmationOptions, setConfirmationOptions] = useState<T>({ isFoo: false } as T);

  const onSubmit = (event: FormEvent) => {
    event.preventDefault();
    onConfirm(confirmationOptions);
  };

  return (
    <div
      onChange={async () => {
        setConfirmationOptions(
           confirmationOptions => ({
             ...confirmationOptions,
             isFoo: !confirmationOptions.isFoo
           })
        )
      }}
    />
  )  
}

字符串

相关问题