问题描述
我有一个名为Button
的组件,它接受onChange
道具。现在onChange: event: React.ChangeEvent<HTMLInputElement>
的类型可以正常工作。我想创建一个期望以下两种类型的union type
。我想做这样的事情,使之成为onChange
泛型类型。
import React from 'react';
type handleChange = (value: string,checked: boolean,name: string) => void
type eventHandleChange = <T extends HTMLElement>(
event: React.ChangeEvent<T>
) => void;
type Change = handleChange | eventHandleChange;
type buttonProps ={
onChange?: Change
}
export const Button =(Props:buttonProps) =>{
//code here
}
但是当我试图将函数传递给像这样的道具时,这给了我一个错误
import React from 'react';
import Button from '../button';
export const FooComponent=()=>{
const changHandler = (event: React.ChangEvent<HTMLInputElement>)=>{
setSelectedValue(event.targe.value)
}
return (
<Button onChange={changeHandler} />
)
}
错误
'(event: React.ChangeEvent<HTMLInputElement>) => void' is not assignable to type 'eventHandleChange | handleChange | undefined'.
Type '(event: React.ChangeEvent<HTMLInputElement>) => void' is not assignable to type 'eventHandleChange'.
Types of parameters 'event' and 'event' are incompatible.
Type 'ChangeEvent<T>' is not assignable to type 'ChangeEvent<HTMLInputElement>'.
Type 'T' is not assignable to type 'HTMLInputElement'.
Type 'HTMLElement' is missing the following properties from type 'HTMLInputElement': accept,align,alt,autocomplete,and 49 more.
由于HTMLInputElement
是从HTMLElement
扩展到T
的,因此此处对所有HTMLElement
都是通用的。我不确定在实现上缺少什么。
解决方法
在处理回调时,您可能会认为“更广泛”和“更狭窄”的含义会颠倒。为了将A分配给B(其中A和B都是回调),A必须接受B接受的所有类型。如果A仅接受B的特定子集,则它不能分配给B。
在这里,您有一个eventHandleChange
类型,可以处理任何HTMLElement
上的更改。您尝试分配给它的回调仅接受HTMLInputElement
的change事件,因此它是不可分配的。
解决此问题的一种可能方法是将通用T
移到更高的位置,这样我们可以说buttonProps
可以进行非常特定的回调。
type handleChange = (value: string,checked: boolean,name: string) => void
type eventHandleChange<T extends HTMLElement> = (
event: React.ChangeEvent<T>
) => void;
type Change<T extends HTMLElement> = handleChange | eventHandleChange<T>;
type buttonProps = {
onChange?: Change<HTMLInputElement>
}