首页 > 解决方案 > 如何使用 React JSX 在 Typescript 中将通用箭头函数实现为接口属性

问题描述

我正在尝试创建一个

interface PromptInput {
  key: string,
  title: string,
  customInput?: <T>(value: T, onChange: (newValue: T) => void) => React.ReactNode;
}

我希望 和 的类型value相同newValue,但它们可以是任何东西。

我有一个InputPromptDialog有道具的组件inputs: PromptInput[]

但是当我尝试传递参数时,我得到一个错误:

<InputPromptDialog
  inputs={[
    { key: 'fullName', title: 'Full Name' },
    { key: 'email', title: 'Email' },
    { key: 'role', title: 'Role', customInput: (value, onChange) => <RoleSelector onChange={(selectedRoleId: string) => onChange(selectedRoleId)} /> },
  ]}
/>

错误在于selectedRole我传递给的值onChange,并说

Argument of type 'string' is not assignable to parameter of type 'T'.
  'T' could be instantiated with an arbitrary type which could be unrelated to 'string'.ts(2345)

为什么没有推断出 T 的值?我怎样才能强制执行valuenewValue成为同一类型,但仍然是任何类型?

标签: reactjstypescriptgenericstype-inference

解决方案


好的,我似乎找到了解决方法:

通过创建一个

type PromptInputCustomInput<T> = (value: T, onChange: (newValue: T) => void) => React.ReactNode;  

并将界面更改为:

interface PromptInput {
  key: string,
  title: string,
  customInput?: PromptInputCustomInput<any>;
}

并更改我将参数传递给的位置:

<InputPromptDialog
  inputs={[
    { key: 'fullName', title: 'Full Name' },
    { key: 'email', title: 'Email' },
    { key: 'role', title: 'Role', customInput: ((value, onChange) => <RoleSelector onChange={(selectedRoleId: string) => onChange(selectedRoleId)} />) as PromptInputCustomInput<string> },
  ]}
/>

这会产生我正在寻找的预期结果。但是我仍然很想知道是否有一种方法可以做到这一点而不必总是投射我传递的值as PromptInputCustomInput<DESIRED_TYPE>


推荐阅读