【问题标题】:Typescript `could be instantiated with a different subtype of constraint '{}'` with react-final-formTypescript`可以用约束'{}'的不同子类型和react-final-form实例化
【发布时间】:2020-07-21 13:44:28
【问题描述】:

我创建了一个可重现的example
我的问题是:如何使用react-final-form 修复此打字稿错误?
错误是:

Type '{ name: string; onBlur: (event?: FocusEvent<HTMLElement>) => void; onChange: (event: any) => void; onFocus: (event?: FocusEvent<HTMLElement>) => void; type?: string; value: T; checked?: boolean; multiple?: boolean; }' is not assignable to type 'T'.
  '{ name: string; onBlur: (event?: FocusEvent<HTMLElement>) => void; onChange: (event: any) => void; onFocus: (event?: FocusEvent<HTMLElement>) => void; type?: string; value: T; checked?: boolean; multiple?: boolean; }' is assignable to the constraint of type 'T', 
but 'T' could be instantiated with a different subtype of constraint '{}'.

点击上面的链接即可轻松查看。
我看到this 很好的答案,但我不知道如何将它应用到这个案例中。

【问题讨论】:

    标签: reactjs typescript react-final-form


    【解决方案1】:

    似乎在抱怨 ComponentType 不一定具有您尝试应用于 Component 对象的 FieldRenderProps 的属性。您需要编写类型,以便它了解您的组件将始终具有这些属性。

    import React, { ComponentType, FC } from 'react';
    import { FieldRenderProps, FieldInputProps } from 'react-final-form'
    
    type ComponentBaseProps<T> = FieldInputProps<T> & Record<string, any>
    
    const createAdapter = <T, >(Component: ComponentType<ComponentBaseProps<T>>) => {
      return ({ input, meta, ...rest }: FieldRenderProps<T>): JSX.Element => {
        return <Component {...input} {...rest} />
      }
    }
    

    上述类型将通知 typescript 您提供的组件具有您尝试分配的所有属性,构成您的所有属性:

    • 输入变量(FieldInputProps 类型)
    • rest 变量(Record 类型)

    另外需要注意的是,ComponentType 的通用参数是应用于组件的完整属性集,而 FieldRenderProps 的通用参数是表单数据的类型。对两者都直接使用 T 是导致您不匹配的原因。

    【讨论】:

    • 感谢您的回答!但似乎使用此代码由打字稿生成的类型不正确。我更新了stackblitz,请再看一次。类型是React.FunctionComponent&lt;FieldRenderProps&lt;unknown, HTMLElement&gt;&gt;,但应该是React.FunctionComponent&lt;FieldRenderProps&lt;MyComponentProps, HTMLElement&gt;&gt;,在我的例子中是React.FunctionComponent&lt;FieldRenderProps&lt;InputProps, HTMLElement&gt;&gt;
    • 抱歉,周末很忙。我认为这与 Material UI 输入的 value 属性的类型有关。如果您创建一个 TextFieldProps 或 InputProps 类型的常量,然后尝试访问其 value 属性,您会注意到该值是未知的(const test: TextFieldProps = { value: 'string' }; 然后test.value 是未知的)。
    • 我唯一可以建议的,我认为从长远来看,如果您开始使用稍微复杂的输入,无论如何您都必须这样做,那就是创建更具体的输入适配器并适当地键入它们。我会举个例子,但我知道这并不能完全解决您的问题,而是更多的选择。
    • 是的,关于复杂的适配器,你是对的。对于复杂的组件,我们需要复杂的适配器。但我相信对于简单的适配器,我们可以创建一个函数,它会生成正确的类型。我又更新了一次 stackblitz - 看看,使用什么组件,mui 或 antd 都没关系 - 类型是正确的。但我仍然不知道如何处理这个错误并获得正确的类型。无论如何,谢谢你的帮助。 stackblitz.com/edit/create-adapter?file=index.tsx
    猜你喜欢
    • 2021-10-14
    • 2021-06-26
    • 2021-12-10
    • 1970-01-01
    • 2021-02-13
    • 2020-03-27
    • 2021-11-24
    • 2019-12-13
    • 2021-08-14
    相关资源
    最近更新 更多