【问题标题】:React TS function argument typesReact TS 函数参数类型
【发布时间】:2021-02-09 05:14:20
【问题描述】:

有一个 HOC 组件用于存储所有元素的一个状态的值作为输入,选择。输出函数接受参数({text: Component, select: Component})。输入参数时,错误显示为

TS2322: Type '({ settings }: Param) => (type: any) => any' is not assignable to type 'FC<Param>'.   Type '(type: any) => any' is missing the following properties from type 'ReactElement<any, any>': type, props, key 

app.js

const useSelectComponent = CustomFabric({
    text: Input, // component view
    select: Select, // component view
});

function App() {
  const InputField = useSelectComponent('text');
  const SelectField = useSelectComponent('select');

  return (
      <form>
        <InputField/>
        <SelectField/>
      </form>
  );
}

在接口中,我表示对象元素将包含一个函数,第二个接口描述了一个带有实体的对象。如何正确指定 HOC 函数的类型,以便我接受带有组件的对象

特设:

interface PropsTypes {
  text: () => void;
  select: () => void;
}

interface Param {
  settings: PropsTypes;
}

export const CustomFabric: React.FC<Param> = ({ settings }: Param) => {
  const elements = Object.entries(settings);
  const newSettings = elements.reduce((acc: any, item: any) => {
    const key = item[0];
    const Component = item[1];

    acc[key] = (props: any) => {
      const [value, setValue] = useState('');
      const onChange = (event: { target: { value: any } }) => {
        setValue(event.target.value);
      };
      return <Component value={value} onChange={onChange} {...props} />;
    };

    return acc;
  }, {});

  return (type: any) => {
    return newSettings[type];
  };
};

【问题讨论】:

  • 函数组件是一个函数,它接受一个参数——一个 props 对象——并返回一些 JSX 元素。您的 CustomFabric 接受道具,但它返回一个函数。所以它本质上与React.FC类型不兼容。
  • 我正试图弄清楚这段代码应该做什么,因为类型与您使用它的方式不匹配。看起来 textselect 应该是组件,但是您的界面说它们是不带参数且不返回任何内容的函数。
  • 我也根本不“明白”在状态位于无法访问的黑盒子后面的受控输入的意义。 CustomFabric 似乎无法让您访问该州。但它可能更适合作为钩子而不是函数组件。它绝对不是一个函数组件。
  • @LindaPaiste感谢您的帮助,这对我有用,如果您可以添加作为问题的答案,我会接受。

标签: reactjs typescript typescript-typings


【解决方案1】:

此代码存在许多问题,但您发布的特定错误是由于将CustomFabric 的类型声明为React.FC&lt;Param&gt; 而不是函数组件。

函数组件是一个函数,它接受一个参数——一个 props 对象——并返回一些 JSX 元素。您的 CustomFabric 接受道具,但它返回 function。所以它本质上与React.FC类型不兼容。

我正试图弄清楚这段代码应该做什么,因为你的类型与你使用它的方式不匹配。看起来 textselect 应该是组件,但是您的界面说它们是不带参数且不返回任何内容的函数。如果它们是组件,那么它们应该使用 React.ComponentType&lt;Props&gt; 类型。

我也根本不“明白”在状态位于您无法访问的黑盒子后面的受控输入的意义。 CustomFabric 似乎无法让您访问该州。所以我看不到这里正在实现什么目标。

但是我们可以更好地正确键入您在这里的内容,这是一个返回挂钩的函数。此代码通过声明以下内容解决了您的大部分问题:

  • textselect 是带有 valueonChange 属性的组件
  • CustomFabric 将使用包含文本组件的对象调用并选择
  • CustomFabric 返回一个函数,该函数接受一个名称并返回一个组件。该名称必须是'text''select',并且返回的组件不需要任何道具。

还有很大的改进空间。例如,您的代码通过额外的道具传递给输入和选择,但这些类型不允许使用除valueonChange 之外的任何道具。您的 settings 只有两个属性,因此您可以通过直接处理这些键而不是循环遍历 Object.entries 来获得更好的类型推断。

type InputComponent = React.ComponentType<{value: string, onChange: React.ChangeEventHandler}>;

interface PropsTypes {
  text: InputComponent;
  select: InputComponent;
}

export const CustomFabric = (settings: PropsTypes) => {
  const elements = Object.entries(settings) as [keyof PropsTypes, InputComponent][];
  const newSettings = elements.reduce((acc, item) => {
    const key = item[0];
    const Component = item[1];

    acc[key] = (props: any) => {
      const [value, setValue] = useState('');
      const onChange = (event: { target: { value: any } }) => {
        setValue(event.target.value);
      };
      return <Component value={value} onChange={onChange} {...props} />;
    };

    return acc;
  }, {} as Record<keyof PropsTypes, React.FC>);

  return (type: keyof PropsTypes): React.FC => {
    return newSettings[type];
  };
};

Typescript Playground Link

【讨论】:

    猜你喜欢
    • 2020-10-11
    • 2022-11-25
    • 2021-12-16
    • 1970-01-01
    • 2022-11-05
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多