Typescript 和 React defaultProps 仍被视为可能未定义
Posted
技术标签:
【中文标题】Typescript 和 React defaultProps 仍被视为可能未定义【英文标题】:Typescript and React defaultProps are still being treated as possibly undefined 【发布时间】:2018-02-02 16:30:05 【问题描述】: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>
);
有没有办法告诉 Typescript props.foo
将总是被定义?
有一个很好的SO question and answer 讨论了如何正确定义组件上的道具类型。它甚至讨论了如何让 TS 知道 stateless 组件上的 defaultProps
。
但是,Typescript 仍然会在常规组件定义中抱怨您的 props 可能未定义(如我上面的示例所示)。
您可以使用 bang (this.props.foo!()
) 调用它,这可以防止 TS 抛出错误,但它也可以防止对您传入的任何内容进行任何类型的检查。在上面的示例中,没什么大不了的.在更复杂的代码中,它已经咬了我。
所以我目前正在实施这样的事情:
private doFoo()
if (this.props.foo) this.props.foo();
这有一个缺点,我认为这很重要:它使我的代码有点混乱。实际上,我总是想调用this.props.foo()
,但似乎,如果不更仔细地研究类,在doFoo
方法中什么都不会发生的情况。 (是的,我可以添加一条评论,解释 if
只是为了让 Typescript 高兴,但我宁愿我的代码在可能的时候自己说话。)
当我实际上需要从 this.props.foo()
返回某些内容时,我的代码变得更加复杂。
我目前正在使用 @types/react 进行类型定义。
【问题讨论】:
【参考方案1】:所以,编译器说对象可能是undefined
。你更清楚它不是,所以你只想写this.props.foo()
。正确的做法是使用空断言类型运算符
this.props.foo!()
如果你说这之前已经咬过你,那是你自己没有检查它的错 :),这意味着编译器 - 正确 - 对象可能是 undefined
。如果有可能是undefined
,你应该经常检查它。也许您喜欢if
语句的更短版本?少了一个字符:
private doFoo()
this.props.foo && this.props.foo();
或使用打字稿 >= 3.8:
private doFoo()
this.props.foo?.();
另一方面,您可以创建一个额外的接口,即extends
PageProps
。为了好玩,我们就叫它PagePropsFilled
:
interface PagePropsFilled extends PageProps
foo: Function;
您现在可以将this.props
设置为PagePropsFilled
,它不会再显示错误了
【讨论】:
今天你是我的英雄,让我免于为默认道具和道具做两个界面... hmmm 但是当我们需要输入interface
时,道具怎么可能是undefined
?如果你通过undefined
Typescript 应该抱怨它想要 Function,如果我们什么都不通过,它应该得到默认值。这令人困惑
@apieceofbart 如果接口属性写成foo?: Function
,这意味着任何实现该接口的类都可以选择是否实现foo
方法。如果它没有实现它,它将返回undefined
。在接口中你不能有默认值
@PierreDuc 谢谢,我现在明白了。我的想法可能需要对 Typescript 进行一些更改才能使用 react defaultProps。我仍然认为这是一种耻辱,因为我们需要编写检查(if (this.props.foo)..
代码将永远为真
好吧,阅读我给出的答案。如果你确定它永远是真的,你可以使用null assertion type operator
,像这样:this.props.foo!()
以上是关于Typescript 和 React defaultProps 仍被视为可能未定义的主要内容,如果未能解决你的问题,请参考以下文章
带有 React、TypeScript 和 Webpack 的空白页面
react-router 和 typescript 抛出“无法解析 'react-router-dom'”错误