【问题标题】:Typescript JSX : Understanding Ant Design ProForm syntaxTypescript JSX:了解 Ant Design ProForm 语法
【发布时间】:2021-10-16 19:25:03
【问题描述】:

我正在尝试按照此处的文档使用 Ant Design Pro Form:https://procomponents.ant.design/en-US/components/modal-form/

但是,在尝试重现他们的示例时,我不断收到语法错误。 导致问题的原因是这种特殊的语法:

<DrawerForm<{
   name: string;
   company: string;
}>
  title="..."
  ...
>

我最初认为它是特定于 Ant Design Pro 的自定义语法,直到我意识到它可能是 Typescript JSX。但是我完全无法在反应文档(也不是打字稿文档)中找到这样的语法。

我知道DrawerForm&lt;{name: string; company: string;}&gt; 可能是一种模板类型,{name: string; company: string;} 是一种应该表示表单模型的数据结构,但没有什么清楚解释。 这可以省略吗?这里有什么意义(这个结构甚至与表单字段不匹配)。

否则,我在此页面 (https://procomponents.ant.design/en-US/components/form) 上的示例代码中遇到了困难:

// Set overall default values
<ProForm initialValues={obj} />

// Set the individual control's
<ProForm
 onValuesChange={(changeValues) => console.log(changeValues)}
>
  <ProFormText initialValue="prop"/>
</ProForm>.

// Interdependent component linkage
<ProForm
  <ProForm.Item noStyle shouldUpdate>
    {(form) => {
      return (
        <ProFormSelect
          options={[
            {
              value: "chapter",
              label: "Effective when stamped",
            },
          ]}
          width="md"
          name="useMode"
          label={`with${form.getFieldValue("name")}contract agreement effective mode`}
        />
      );
    }}
  </ProForm.Item>.
</ProForm>;


// Using custom components
<ProForm
  <ProForm.Item name="switch" label="Switch" valuePropName="checked">
    <Switch />
  </ProForm.Item
</ProForm

这似乎是不稳定的,标签是未封闭的。你能确认不只是我错过了什么吗?

【问题讨论】:

    标签: reactjs typescript jsx antd ant-design-pro


    【解决方案1】:

    这只是一个简单的泛型类型。你可以写一个泛型函数

    declare function reverseArray<T>(array: T[]): T[]
    

    然后通过在函数名称后的尖括号中添加类型来使用它

    const array: number[] = [1, 2, 3]
    const reversed = reverseArray<number>(array) 
    

    那你为什么不创建一个通用的反应组件

    const ArrayView = <T extends any>({
      array,
      renderItem,
    }: {
      array: T[],
      renderItem: (item: T) => ReactNode,
    }) => ({
      <div>
        {array.map(item => renderItem(item))}
      </div>
    })
    

    然后通过在函数(=组件)名称后的尖括号中添加类型来使用它

    const array: number[] = [1, 2, 3]
    
    <ArrayView<number>
      array={array}
      renderItem={(item) => <span>{item + 1}</span>}
    />
    

    除了你的情况,类型参数不是number而是{name: string, company: string}。

    当然,在普通函数和反应组件示例中,您可以省略 &lt;number&gt; 部分并让 typescript 自行推断类型,但重点仍然存在,这是普通的通用函数语法,只是在 TSX 中看起来有点奇怪。另请注意,在第二个示例中,如果您使用箭头函数定义组件,则必须添加此 extends any 东西,因为如果您只写 &lt;T&gt;,打字稿会认为它是一个开放的 TSX 标记并混淆自己。

    实际上,即使组件是通用的,99.99% 的情况下 typescript 都能够从某些 prop 类型中正确推断出所有内容,这可能就是您以前从未见过这种语法的原因。但有时你必须使用它,如果推理本身不起作用。

    而且 AFAIK 这种语法相对较新,因此您可能需要更新编译器或其他东西才能使其正常工作。或者完全避免它,因为您实际上可以通过在其他地方指定此类型来让 TS 推断所有内容,例如

    <DrawerForm
      onFinish={async (values: {name: string, company: string}) => {
        // ...
      }}
      // ...
    />
    

    说到未封闭的标签,它可能只是一堆错别字。如果你查看这个页面的中文版,你会看到

    <ProForm>
      <Form.Item name="switch" label="Switch" valuePropName="checked">
        <Switch />
      </Form.Item>
    </ProForm>
    

    这可能不会提出任何问题

    【讨论】:

    猜你喜欢
    • 2018-05-14
    • 2020-12-01
    • 2022-07-16
    • 2020-03-11
    • 1970-01-01
    • 2020-07-06
    • 2018-08-30
    • 2020-09-25
    • 2019-03-13
    相关资源
    最近更新 更多