The expected type comes from property 'onChange' which is declared here on type 'IntrinsicAttributes & ISelectInput'

huangapple go评论124阅读模式
英文:

The expected type comes from property 'onChange' which is declared here on type 'IntrinsicAttributes & ISelectInput'

问题

I tried to pass an event to my onChange event. But I get intrinsic error all the time.

I made my selectInputInterface format this way:

interface ISelectInput {
  placeholder?: string;
  onChange: () => void;
  children: Record<string, any>[];
}

Then, my onChange function:

const handleSelectCategory = (event: any) => {
    const category = event.target.value;

    setSelectedCategory(category);
};

I implemented in my UI:

<SelectInput
   placeholder="Select input"
   onChange={handleSelectCategory}
 >
    {uniqueCategories}
</SelectInput>

But I got this typescript error:

Type '(event: any) => void' is not assignable to type '() => void'.ts(2322)
SelectInput.tsx(29, 3): The expected type comes from property 'onChange' which is declared here on type 'IntrinsicAttributes & ISelectInput'
英文:

I tried to pass an event to my onChange event. But I get intrinsic error all the time.

I made my selectInputInterface format this way:


interface ISelectInput {
  placeholder?: string;
  onChange: () =&gt; void;
  children: Record&lt;string, any&gt;[];
}

Then, my onChange function:

const handleSelectCategory = (event: any) =&gt; {
    const category = event.target.value;

    setSelectedCategory(category);
  };

I implemented in my UI:

&lt;SelectInput
   placeholder=&quot;Select input&quot;
   onChange={handleSelectCategory}
 &gt;
    {uniqueCategories}
&lt;/SelectInput&gt;

But I got this typescript error:

Type '(event: any) => void' is not assignable to type '() => void'.ts(2322)
SelectInput.tsx(29, 3): The expected type comes from property 'onChange' which is declared here on type 'IntrinsicAttributes & ISelectInput'


</details>


# 答案1
**得分**: 0

因为函数签名不同,不接受任何参数。

你可以添加一个...args来实现这个:

```typescript
interface ISelectInput {
  placeholder?: string;
  onChange: (...args: any) => void;
  children: Record<string, any>[];
}

或者将你的事件(event)作为可选参数,这样做:

interface ISelectInput {
  placeholder?: string;
  onChange: (event?: any) => void;
  children: Record<string, any>[];
}
英文:

Its because the function signature is different and does not take any params.

You can add a ...args do this

interface ISelectInput {
  placeholder?: string;
  onChange: (...args: any) =&gt; void;
  children: Record&lt;string, any&gt;[];
}

or use your event as optional and do

interface ISelectInput {
  placeholder?: string;
  onChange: (event?: any) =&gt; void;
  children: Record&lt;string, any&gt;[];
}

答案2

得分: 0

这个错误是因为IselectInput中的onChange是类型为() => void的,也就是说,它应该接收一个没有输入的函数。但是在这里,handleSelectCategory函数接收了一个(event)。

对于这个错误,你需要将handleSelectCategory函数从event: string改为event: any,因为在代码的最后,我想要将从SelectInput中选择的值(event.target.value)传递给setSelectedCategory作为选定的类别。

interface ISelectInput {
  placeholder?: string;
  onChange: (category: string) => void;
  children: Record<string, any>[];
}

const handleSelectCategory = (event: any) => {
  const category = event.target.value;
  setSelectedCategory(category);
};

<SelectInput
  placeholder="Select input"
  onChange={handleSelectCategory}
>
  {uniqueCategories}
</SelectInput>

请注意,这只是将类型从string更改为any的示例。你可能需要根据你的代码结构和需求进一步修改。

英文:

This error is because onChange in IselectInput is of type () => void, that is, it should receive a function with no input. But here, the handleSelectCategory function receives an (event).
For this error, you need to change the handleSelectCategory function from event: ‍string because at the end of the code, I want to pass a value from event.target.value (selected value from SelectInput) to setSelectedCategory as the selected category.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

interface ISelectInput {
  placeholder?: string;
  onChange: (category: string) =&gt; void;
  children: Record&lt;string, any&gt;[];
}

const handleSelectCategory = (event: any) =&gt; {
  const category = event.target.value;
  setSelectedCategory(category);
};

&lt;SelectInput
  placeholder=&quot;Select input&quot;
  onChange={handleSelectCategory}
&gt;
  {uniqueCategories}
&lt;/SelectInput&gt;

<!-- end snippet -->

答案3

得分: 0

函数相对于它们的参数是逆变的。这也包括参数个数。换句话说,你可以将 () => void 赋值给 (event: any) => void,但反过来不行。这是因为如果我将 (event: any) => void 赋给期望 () => void 的地方,该函数将被无参数调用,因此不安全。

不过,这很容易修复。只需将 onChange 定义为带有参数的:

interface ISelectInput {
    placeholder?: string;
    onChange: (event: any) => void;
    children: Record<string, any>[];
}

我还建议您不要使用 any,而是使用适当的类型,也许是 InputEvent

Playground(演示使用带有守卫子句的 InputEvent)

英文:

Functions are contravariant with respect to their parameters. This also includes arity. In other words, you can assign a () =&gt; void to (event: any) =&gt; void, but not the other way around. That's because if I assign a (event: any) =&gt; void to somewhere that expects () =&gt; void, the function will be called without an argument, and therefore it is unsound.

It is a simple fix, however. Just define onChange to take an argument:

interface ISelectInput {
    placeholder?: string;
    onChange: (event: any) =&gt; void;
    children: Record&lt;string, any&gt;[];
}

I would also suggest that instead of using any, you should use the proper type, perhaps an InputEvent.

Playground (demonstrating use of InputEvent with guard clauses)

huangapple
  • 本文由 发表于 2023年3月3日 23:38:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629103.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定