TypeScript 4.2のリリースまとめ

こんにちは,@hulsc2esです.

2021年2月23日に,TypeScript4.2がリリースされました. 本記事では,4.2にて追加された機能についてまとめました.

本記事は,主にTypeScript公式のリリース記事から得た情報を元にしています.

それでは,早速中身に入ります.

Smarter Type Alias Preservation

ユニオン型および交差型の型エイリアスの保存性(Preservation)が向上しました. 保存性(Preservation)とは,簡単に言えば,不意に型が変化されず,定義された型を保ち続けることと解釈しています.

4.2以前では,定義したユニオン型や交差型が,ある型の一部となると,型が分解されていました.

4.2では,ユニオン型および交差型の推論が強化され,型の保存性が向上しています.

export type BasicPrimitive = number | string | boolean;

// 4.2以前が返す型 → number | string | boolean | undefined
// 4.2以降が返す型 → BasicPrimitive | undefined
export function doStuff(value: BasicPrimitive) {
     if (Math.random() < 0.5) {
         return undefined;
     }

     return value;
 }

こちらの初期PRも参考になるかと思います.

ユニオン型や交差型はよく利用するため,ありがたい発展です.

Leading/Middle Rest Elements in Tuple Types

タプル型が強化されました.

...rest要素が,タプル型の最後列ではなく,(少しの制限はあるものの)どこでも使えるようになりました.

let foo: [...string[], number];

foo = [123];
foo = ["hello", 123];
foo = ["hello!", "hello!", "hello!", 123];

let bar: [boolean, ...string[], boolean];

bar = [true, false];
bar = [true, "some text", false];
bar = [true, "some", "separated", "text", false];

制限とは,下記のようなものです. - 一つのタプル型につき,一つのrest要素のみが利用できる - rest要素のあとにoptional要素をつけることはできない

interface Clown { /*...*/ }
interface Joker { /*...*/ }

let StealersWheel: [...Clown[], "me", ...Joker[]];
//                                    ~~~~~~~~~~ Error!
// A rest element cannot follow another rest element.

let StringsAndMaybeBoolean: [...string[], boolean?];
//                                        ~~~~~~~~ Error!
// An optional element cannot follow a rest element.

使いこなせるとより柔軟で硬い型定義ができそうです.

Stricter Checks For The in Operator

プリミティブな型がin演算子の対象となったときに,すぐにエラーを出す変更です. JS側のエラーをTS側で先にキャッチしたいというイシューの解決とのことです.

// 42でエラー
"foo" in 42

--noPropertyAccessFromIndexSignature

--noPropertyAccessFromIndexSignatureというモードが追加されました.

TypeScriptでは,以前オブジェクトのプロパティにopts.valの形式でアクセスできる変更が追加されました.この変更は,利便性が向上されると同時に,タイポによるミスを招きやすいという問題がありました.--noPropertyAccessFromIndexSignatureモードでは,opts.valの形式でアクセスできないように強制します(=opts["val"]のみを許す).

こちらは,strictには含まれていません.

The --explainFiles

TypeScriptがincludesしているファイルについての説明を得るフラグ--explainFilesが追加されました.

tsc --explainFiles > explanation.txt 上記のように使うと,lib.d.ts,ローカルファイル,node_moduleファイルなどを含んでいる理由をリストアップしてくれます.

Improved Uncalled Function Checks in Logical Expressions

TypeScript のコールされていない関数チェックが, && および || 式内で適用されるようになりました.

function shouldDisplayElement(element: Element) {
    // ...
    return true;
}

function getVisibleItems(elements: Element[]) {
    return elements.filter(e => shouldDisplayElement && e.children.length)
    //                          ~~~~~~~~~~~~~~~~~~~~
    // This condition will always return true since the function is always defined.
    // Did you mean to call it instead.
}

Destructured Variables Can Be Explicitly Marked as Unused

変数名の前にアンダースコアを付けることで,未使用の変数としてマークできるようになりました. 4.2以前では,_変数名としてもnoUnusedLocalsにてエラーが起きていました. 4.2以降では,_変数名とすることで,未使用であることを明示できるようになったとのことです.

const [val, _setVal] = React.useState<number>(0)

地味ですが,ありがたいですね. 例はuseStateですが,カスタムフックを利用する際に便利そうです.

Relaxed Rules Between Optional Properties and String Index Signatures

オプショナルプロパティを文字列インデックスシグネチャにasssignできるようになりました.

Declare Missing Helper Function

未定義の関数が利用された場合に,not implementedを明示する関数を作成するquick fixが追加されました.

devblogs.microsoft.com

quick fix,開発中助かるのでありがたいです.

Breaking Changes

  • lib.d.tsのアップデート
  • 型定義のない yieldがエラーとなる
  • 型定義されたjsファイルをパースした結果が変更される
  • in演算子の右側に,Primitive Typesを置けなくなる
  • スプレッドのためのタプル型のサイズ制限

参考文献