reactjs React和 typescript :我可以用不同数量的泛型重载函数吗?

rlcwz9us  于 2022-12-03  发布在  React
关注(0)|答案(1)|浏览(116)

我正在使用typescript编写React函数组件。为了在提交数据之前对其进行格式化,我希望创建一个表单组件,该组件可以选择具有format函数和FormattedValue泛型类型。
但是,它不应该允许您在没有设置泛型类型的情况下使用format,否则您可能会意外地提交错误类型的表单。
我不知道如何使一个函数重载,使Form函数要么有通用的FormattedValue集和format参数,要么没有。
这是我尝试做的一个最小的例子:

import {Form} from "../components/Form"

type FormProps<Value> = {
    submit: (data: Value) => void;
}

type FormattedFormProps<Value, FormattedValue> = {
    submit: (data: FormattedValue) => void;
    format: (value: Value) => FormattedValue
}

function GenericForm<V>({submit}: FormProps<V>): ReactNode;
function GenericForm<V,F>({submit, format}: FormattedFormProps<V, F>) {
  return (
    <Form 
     //...
    onSubmit={(value) => {
        submit(format ? format(value) : value)
    }}
    >
     // ...
    </Form>
  )
}

export default GenericForm

这会产生错误:This overload signature is not compatible with its implementation signature.(2394) .
我希望避免为普通窗体和带格式的窗体创建单独的组件。

xu3bshqb

xu3bshqb1#

但是,它不应该允许您在没有设置泛型类型的情况下使用format,否则您可能会意外地提交错误类型的表单。
我不同意这种说法,因为FormattedFormProps将确保format的输出是submit的输入。

type FormProps<Value, FormattedValue> = {
    submit: (data: FormattedValue) => void;
    format?: (value: Value) => FormattedValue
}

function GenericForm<V, F>({submit, format}: FormProps<V, F>) {
  return (
    <Form 
     //...
    onSubmit={(value) => {
        submit(format ? format(value) : value)
    }}
    >
     // ...
    </Form>
  )
}

// infer FormProps<unknown, number>
const OK1 = GenericForm({submit: (data: number) => {}})

// infer FormProps<string, number>
const OK2 = GenericForm({submit: (data: number) => {}, format: (a: string) => 42})

// infer FormProps<string, number>
const ERROR = GenericForm({submit: (data: number) => {}, format: (a: string) => 'foo'})
//                                                       ~~~~~~
// Type '(a: string) => string' is not assignable to type '(value: string) => number'.
//  Type 'string' is not assignable to type 'number'.(2322)

如果出于某种原因,您希望限制必须用于在调用站点上格式化和提交的类型,则可以创建GenericForm的变体,而无需重新实现它,如下所示:

const FormStringToNumber = GenericForm<string, number>;

相关问题