我的一个功能组件中有一个onClick
事件:
import * as React from 'react';
const BreadCrumbs: React.SFC<{level: Array<string>, changeLevel: Function}> = ({level, changeLevel}) => {
return (
<div>
{
level.map(function(elem, i) {
return <span key={i} onClick={changeLevel}>{elem}</span>
})
}
</div>
)
}
export default BreadCrumbs;
在父组件中,我为<BreadCrumbs>
组件提供了数组的 props 和函数引用:
<BreadCrumbs level={this.state.levels} changeLevel={this.changeLevel}/>
这不起作用,因为在<BreadCrumbs>
组件中,Typescript 编译器失败并显示错误(return <span>
行):
[ts]
Type '{ key: number; onClick: Function; children: string; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>'.
Type '{ key: number; onClick: Function; children: string; }' is not assignable to type 'HTMLAttributes<HTMLSpanElement>'.
Types of property 'onClick' are incompatible.
Type 'Function' is not assignable to type '((event: MouseEvent<HTMLSpanElement>) => void) | undefined'.
Type 'Function' is not assignable to type '(event: MouseEvent<HTMLSpanElement>) => void'.
Type 'Function' provides no match for the signature '(event: MouseEvent<HTMLSpanElement>): void'.
(JSX attribute) onClick: Function
但是,如果我将我的代码修改为这样:
const BreadCrumbs: React.SFC<{level: Array<string>, changeLevel: Function}> = ({level, changeLevel}) => {
function something(i: number) {
changeLevel(i);
}
return (
<div>
{
level.map(function(elem, i) {
return <span key={i} onClick={something.bind(this, i)}>{elem}</span>
})
}
</div>
)
}
export default BreadCrumbs;
一切正常。 为什么第一个版本不起作用?
在 TypeScript 中,它使用强类型方式对函数执行类型检查,这会考虑函数的参数和返回值。因此,对于参数(React 组件 prop)changeLevel
,其类型应该声明为(event: React.MouseEvent<HTMLSpanElement>) => void
或兼容类型(如(e: React.MouseEvent<Element>) => void
、() => void
或() => any
)。Function
类型不用于函数类型声明,而是用于键入任何函数对象的全局构造函数,缺少有关函数对象的信息,在键入函数时应避免使用。
您可以将代码更改为以下版本以通过 TypeScript 的检查。
const BreadCrumbs: React.SFC<{level: Array<string>, changeLevel: () => void}> = ({level, changeLevel}) => {
return (
<div>
{
level.map(function(elem, i) {
return <span key={i} onClick={changeLevel}>{elem}</span>
})
}
</div>
)
}
实际上,在第二个版本中,bind
函数的返回类型是any
,可以分配给TypeScript中任何类型的变量。TypeScript 在该版本中不执行类型检查。