首页 > 解决方案 > 如何使用 React TypeScript 创建通用事件处理程序

问题描述

我有一个名为的组件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。我不确定我在实施中缺少什么。

标签: reactjstypescripttsx

解决方案


在处理回调时,您可能认为的“更广泛”和“更窄”会被颠倒过来。为了将 A 分配给 B,其中 A 和 B 都是回调,A 必须接受 B 接受的所有类型。如果 A 只接受 B 所做的特定子集,则它不能分配给 B。

在这里,您有一个eventHandleChange可以处理任何HTMLElement. 您尝试分配给它的回调只接受 的更改事件HTMLInputElement,因此它是不可分配的。

解决此问题的一种可能方法是将泛型移到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>
}

打字稿游乐场链接


推荐阅读