如何在 TypeScript v2.x 中公开来自自定义 React 组件的 'generic' 事件
How to expose a 'generic' event from a custom React component in TypeScript v2.x
当我们还在使用 Typescript 1.8.x 结合当时 React 的 (Definitely Typed) 类型描述文件时,我们使用 'Event' 类型来声明一个 'generic' React 组件属性中的事件。然后,我们可以将 属性(存在和事件处理函数)的值附加到例如 HtmlInputElement 的 'onChange' 属性。
interface IIcoonProps {
onClick?: Event;
}
interface IIcoonDetails {
cssClass: string;
standaardTooltip: string;
}
class Icoon extends React.Component<IIcoonProps, {}> {
public render(): JSX.Element {
return (<span className={klassenamen}
title={nieuweTooltip}
onClick={this.props.onClick} />);
}
}
我们最近更新到 TypeScript 2.2.2,还更新了我们正在使用的类型定义。现在我们不能再使用泛型 'Event' 类型了,因为它会导致像 "Type 'Event' is not assignable to type 'EventHandler>'".
这样的异常
当然,当我将自定义组件属性界面中的属性类型改为'React.MouseEvent'时,问题就解决了。但是.....我不想让这个组件的父组件知道底层类型(在这个例子中是 HtmlInputElement),因为它是我自己组件的属性中提到的事件。我只需要将事件传递给父组件,因为我希望父组件能够使用事件的 'PreventDefault' 之类的方法。我在 IComponentProps 接口中使用不同的属性和方法来发布例如文本输入的更改值。
下面的代码可以工作,但并不理想。
interface IIcoonProps {
onClick?: React.EventHandler<React.MouseEvent<HTMLSpanElement>>;
}
interface IIcoonDetails {
cssClass: string;
standaardTooltip: string;
}
class Icoon extends React.Component<IIcoonProps, {}> {
public render(): JSX.Element {
return (<span className={klassenamen}
title={nieuweTooltip}
onClick={this.props.onClick} />);
}
}
有谁知道如何在使用 TypeScript 和 React 时像我们之前使用 'Event' 类型时那样为事件使用泛型类型,而不使用泛型(如 MouseEvent)。
更新:添加了代码示例
我觉得你的代码没问题,但如果你不想具体说明目标元素的类型,那么你可以使用 HTMLElement:
interface IIcoonProps {
onClick?: React.EventHandler<React.MouseEvent<HTMLElement>>;
}
这将适用于未来可能的更改(假设从 HTMLSpanElement
到 HTMLDivElement
)。
此外,您可以改用此签名:
interface IIcoonProps {
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
}
编辑
如果您想要使用非通用接口,那么您可以创建自己的接口然后使用它:
type MouseEvent = React.MouseEvent<HTMLElement>;
interface IIcoonProps {
onClick?: (event: MouseEvent) => void;
}
当我们还在使用 Typescript 1.8.x 结合当时 React 的 (Definitely Typed) 类型描述文件时,我们使用 'Event' 类型来声明一个 'generic' React 组件属性中的事件。然后,我们可以将 属性(存在和事件处理函数)的值附加到例如 HtmlInputElement 的 'onChange' 属性。
interface IIcoonProps {
onClick?: Event;
}
interface IIcoonDetails {
cssClass: string;
standaardTooltip: string;
}
class Icoon extends React.Component<IIcoonProps, {}> {
public render(): JSX.Element {
return (<span className={klassenamen}
title={nieuweTooltip}
onClick={this.props.onClick} />);
}
}
我们最近更新到 TypeScript 2.2.2,还更新了我们正在使用的类型定义。现在我们不能再使用泛型 'Event' 类型了,因为它会导致像 "Type 'Event' is not assignable to type 'EventHandler>'".
这样的异常当然,当我将自定义组件属性界面中的属性类型改为'React.MouseEvent'时,问题就解决了。但是.....我不想让这个组件的父组件知道底层类型(在这个例子中是 HtmlInputElement),因为它是我自己组件的属性中提到的事件。我只需要将事件传递给父组件,因为我希望父组件能够使用事件的 'PreventDefault' 之类的方法。我在 IComponentProps 接口中使用不同的属性和方法来发布例如文本输入的更改值。
下面的代码可以工作,但并不理想。
interface IIcoonProps {
onClick?: React.EventHandler<React.MouseEvent<HTMLSpanElement>>;
}
interface IIcoonDetails {
cssClass: string;
standaardTooltip: string;
}
class Icoon extends React.Component<IIcoonProps, {}> {
public render(): JSX.Element {
return (<span className={klassenamen}
title={nieuweTooltip}
onClick={this.props.onClick} />);
}
}
有谁知道如何在使用 TypeScript 和 React 时像我们之前使用 'Event' 类型时那样为事件使用泛型类型,而不使用泛型(如 MouseEvent)。
更新:添加了代码示例
我觉得你的代码没问题,但如果你不想具体说明目标元素的类型,那么你可以使用 HTMLElement:
interface IIcoonProps {
onClick?: React.EventHandler<React.MouseEvent<HTMLElement>>;
}
这将适用于未来可能的更改(假设从 HTMLSpanElement
到 HTMLDivElement
)。
此外,您可以改用此签名:
interface IIcoonProps {
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
}
编辑
如果您想要使用非通用接口,那么您可以创建自己的接口然后使用它:
type MouseEvent = React.MouseEvent<HTMLElement>;
interface IIcoonProps {
onClick?: (event: MouseEvent) => void;
}