TypeScript2からのReactとnon-null assertion
TypeScript2からコンパイルオプションの strictNullChecks
で、nullability をチェックできるようになった。
最近になってこのオプションを有効にしたら意外と修正するところが多かったのでメモ。
TypeScript1系の時は↓の様に書いてました。
import * as React from 'react' import * as ReactDom from 'react-dom' interface IAProps { } interface IAState { hoge?: string; fuga?: number; } class A extends React.Component<IAProps, IAState> { constructor(props: IAProps) { super(props); this.state = { hoge: '', fuga: 0 } } render() { return( <B hoge={this.state.hoge} fuga={this.state.fuga} /> ); } } interface IBProps { hoge: string; fuga: number; } interface IBState { } class B extends React.Component<IBProps, IBState> { constructor(props: IBProps) { super(props); this.state = { } } render() { return( <div> {this.props.hoge} <br /> {this.props.fuga} </div> ); } }
TypeScriptでstate管理するときは、毎回全部のパラメータを更新したいわけではないので
interface IAState { hoge?: string; fuga?: number; }
という感じに?
を付けてオプショナルにしていました。
そうすると、stateで管理しているhoge
fuga
の型が
hoge: string | undefined fuga: number | undefined
と、それぞれ undefined
になる可能性があるということになる。
Component B に値を渡すとき、Component B側では
interface IBProps { hoge: string; fuga: number; }
というようにundefined
は許容されないので、
render() { return( <B hoge={this.state.hoge!} fuga={this.state.fuga!} /> );
と!
を付けて、non-nullであることを明示してあげないといけない。
最終的にソースコードはこうなりました。
import * as React from 'react' import * as ReactDom from 'react-dom' interface IAProps { } interface IAState { hoge?: string; fuga?: number; } class A extends React.Component<IAProps, IAState> { constructor(props: IAProps) { super(props); this.state = { hoge: '', fuga: 0 } } render() { return( <B hoge={this.state.hoge!} fuga={this.state.fuga!} /> ); } } interface IBProps { hoge: string; fuga: number; } interface IBState { } class B extends React.Component<IBProps, IBState> { constructor(props: IBProps) { super(props); this.state = { } } render() { return( <div> {this.props.hoge} <br /> {this.props.fuga} </div> ); } }