Don*_*Don 8 typescript reactjs
interface PageProps {
foo?: Function;
bar: number;
}
export class PageComponent extends React.Component<PageProps, {}> {
public static defaultProps: Partial<PageProps> = {
foo: () => alert('Did foo')
};
private doFoo() {
this.props.foo(); // Typescript Error: Object is possibly 'undefined'
}
public render(): JSX.Element {
return (
<div>
<span>Hello, world! The number is {this.props.bar}</span>
<button onClick={() => this.doFoo()}>Do the Foo</button>
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法告诉 Typescriptprops.foo总是被定义?
有一个非常好的SO 问答,讨论了如何正确定义组件上 props 的类型。它甚至讨论了如何让 TS 了解无状态defaultProps组件。
然而,Typescript 仍然会在常规组件定义中抱怨你的 props 可能未定义(如我上面的示例所示)。
您可以使用 bang ( this.props.foo!()) 来调用它,这可以防止 TS 引发错误,但它也可以防止对您传入的任何内容进行任何类型的检查。在上面的示例中,这没什么大不了的。在更复杂的代码中,它已经咬住了我。
所以我目前正在实施这样的事情:
private doFoo() {
if (this.props.foo) this.props.foo();
}
Run Code Online (Sandbox Code Playgroud)
这有一个缺点,我认为这个缺点相当重要:它使我的代码有点混乱。实际上,我总是想调用this.props.foo(),但似乎在不更仔细地研究该类的情况下,在某些情况下该doFoo方法内部不会发生任何事情。(是的,我可以添加一条注释,解释这if只是为了让 Typescript 感到高兴,但我宁愿我的代码在可以的情况下自己说话。)
当我实际上需要从this.props.foo().
我目前正在使用 @types/react 作为我的类型定义。
因此,编译器说该对象可能是undefined. 你更清楚事实并非如此,所以你只想写this.props.foo()。正确的方法是使用空断言类型运算符
this.props.foo!()
Run Code Online (Sandbox Code Playgroud)
如果你说这之前已经困扰过你,那么那是你自己没有检查它的错:),这意味着编译器是正确的,该对象本来可以是undefined。如果有可能undefined,您应该始终检查它。也许您喜欢该声明的更简短版本if?少了一个字符:
private doFoo() {
this.props.foo && this.props.foo();
}
Run Code Online (Sandbox Code Playgroud)
或使用 typescript >= 3.8:
private doFoo() {
this.props.foo?.();
}
Run Code Online (Sandbox Code Playgroud)
另一方面,您可以创建一个额外的接口,extends其中PageProps. 为了好玩,我们称它为PagePropsFilled:
interface PagePropsFilled extends PageProps {
foo: Function;
}
Run Code Online (Sandbox Code Playgroud)
您现在可以将您的设置this.props为PagePropsFilled,它不会再向您显示错误
| 归档时间: |
|
| 查看次数: |
5062 次 |
| 最近记录: |