0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TypescriptのstrictNonNullとstrictClassInitializersがなぜ大切か

Posted at

はいさい!オースティンやいびーん!

概要

TypescriptのstrictNonNullとstrictClassInitializersについて解説します。

strictNonNullとは

TypeScriptは、本来、undefinedと null を完全に違う型として認識しています。
実際、JavaScriptでも undefined !== null ですし、undefinedと null を大体同じだと勘違いして使っていると、痛い目に遭います(筆者はずっと誤解していました:sweat_smile:)。

しかし、TypeScriptの緩い設定だと、これらの違いについて文句を言わないようになっています。

strictNonNullを有効にすると、Runtimeで絶対にエラーになるようなコードに気づくことができます。

そして、undefinedの可能性がある戻り値について、厳しく指摘も入るようになります。

以下のコードをみてみましょう。

const myLetters = ['a', 'b'];
const isOneLetter = myLetters.find(v => v === 'c').length === 1

myLettersのfindの戻り値を考えましょう。何の型になるでしょうか?
'c'が配列にないので、stringではなく、undefined になりますね。
undefinedには length はないので、JavaScriptだったらここでまず転けますね。

strictNonNullが有効だと、ここでTypeScriptはそれを教えてくれるのです。

そして以下のように対応します。

const myLetters = ['a', 'b'];
const isOneLetter = myLetters.find(v => v === 'c')?.length === 1 // findの戻り値がundefinedだったら、.lengthをGetせずに、undefinedをそこで返す
// OR
const isOneLetter = myLetters.find(v => v === 'c')!.length === 1 // エラーはそれでも起こる、危ない!

!もしくは ? を使って、TSにundefinedの可能性があるコードに対してどうするべきかを教える必要があります。これらの機能はNonNullAssertionsと言います。

strictPropertyInitializationとは

上記のstrictNonNullとセットで来るのは、strictPropertyInitializationの設定です。

以下のコードを見てみましょう。

class MyComponent extends OnInit {
 items: Item[];

 ngOnInit() {
  this.items.forEach(item => item.viewed = true);
 }
}

this.itemsの Propertyはどこでも設定されていないので、ngOnInitでエラーになります。なぜなら、this.itemsは Item[] ではなく、 undefinedだからです。

なので、ここでは二つ、対策を施します。

初期値を与える場合

class MyComponent extends OnInit {
 items: Item[] = [];

 ngOnInit() {
  this.items.forEach(item => item.viewed = true);
 }
}

絶対に定義されることをわかっている場合

class MyComponent extends OnInit {
 @Input() items!: Item[];

 ngOnInit() {
  this.items.forEach(item => item.viewed = true);
 }
}

##定義されない可能性がある場合

class MyComponent extends OnInit {
 @Input() items?: Item[]; // TS上、Item[] | undefinedになるのです。

 ngOnInit() {
  this.items?.forEach(item => item.viewed = true);
 }
}

上記の対策を施すと、いろんな場面で起きるエラーを未然に防ぐことができます。

まとめ

以上、strictNullChecksとstrictPropertyInitializerについての解説ですが、さらに知りたい方は、TypeScriptの正式ドキュメントをご覧ください!

また、勉強会を開いてもいいのですが、もし勉強会が役に立ちそうなら、オースティンまでご連絡ください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?