Typescript React:基于泛型的回调事件处理程序作为组件的道具



我在创建一个基于泛型的回调事件处理程序函数时遇到了问题,我想将该函数作为道具传递给我的组件。

我的目标:允许用户传递一个自定义回调函数,该函数:

  1. 总是接受同一个参数
    • 事件(不是react/dom事件处理程序事件,它来自库(
  2. 可以返回不同的返回类型
    • 对于我的用例,该组件在不同的上下文中使用,因此在一个地方,用户将返回某个值而不是另一个值

我尝试了什么

  1. 我的onNodeClick函数是用泛型定义的&当我单独使用它时,它是有效的
// ✅ Simple example of calling a generic function
const onNodeClick = <T,> (event:any) => {
return null as unknown as T;
} 
const string_result = onNodeClick<string>(event_from_somewhere)

然而,当我试图将此方法作为道具传递给我的组件时,我会遇到错误。我不确定如何解决

Live Typescript Code Playground

import React from 'react';
type NodeComponentProps = {
onNodeClick: <T>(event: any) => T;
};
export const NodeComponent = ({onNodeClick}: NodeComponentProps) => {
return null;
}

const Homepage = () => {
const handleNodeClick = <T,>(event: any): T => {
return null as unknown as T;
};
return (
<NodeComponent 
onNodeClick={(event): string => {
const string_result = handleNodeClick<string>(event); // ✅ correct type
return string_result; // ❌ onNodeClick is throwing type error; see error message a few lines below
}} 
/>
)
}
/*
Type '<T>(event: any) => string' is not assignable to type '<T>(event: any) => T'.
Type 'string' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'string
*/

我认为您希望类型是泛型的,而不是函数。如果函数是泛型的,那么它应该可以用尖括号调用,并且可以正常工作。例如,标识函数适用于任何类型,因此它应该通过您的通用函数定义:

const Homepage = () => {
const onNodeClick = <T>(x: T): T => {
return x;
};
return (
<NodeComponent 
onNodeClick={onNodeClick} 
/>
)
}

但是,您使用的函数将始终返回一个字符串。如果您尝试用<number>调用它,它将失败。因此,不是通用函数。

相比之下,如果您将类型设为泛型,则应该能够指定您正在将其与字符串一起使用:

这是一个游乐场链接

type NodeComponentProps<T> = {
onNodeClick: (event: any) => T;
};
export const NodeComponent = <T,>({onNodeClick}: NodeComponentProps<T>) => {
return null;
}

最新更新