🤨

【TypeScript】Assertion Functionではarrow functionsを使わないほうがいい

2023/01/04に公開

Assertions require every name in the call target to be declared with an explicit type annotation.

検証TypeScriptバージョンは4.8.2。

アサーション関数(Assertion Functions)の使い道として典型的なのは、Nullチェックのためのアサーションで、↓こんなようなのを作るわけですが

export function assertNotNull<T>(val:T): asserts val is NonNullable<T> {
    // nullとundefined をまとめてチェック
    if (val == null) {
        throw new Error("valがnullかundefinedですよ");
    }
}

これをアロー関数で書いたら、使おうとしたときにコンパイルエラーになる。

export const assertNotNull = <T>(val: T): asserts val is NonNullable<T> => {
    if (val == null) {
        throw new Error("valがnullかundefinedですよ");
    }
}

declare let stringOrNull: string | null;

// Assertions require every name in the call target to be declared with an explicit type annotation.
assertNotNull(stringOrNull);

型を明示しろって、 assertNotNull<string>(stringOrNull) こういうこと?と思ったが、解決しない。

いまいち理解できないが、TypeScriptの仕様(制約?)だということらしいですね。

解決策として、上記リンクでは、アロー関数の定義側で型を明示する方法も紹介されているが、上の assertNotNull<T> のようなジェネリック型の関数でうまく書く方法がわからなかった。
(書けたとしても定義が結構冗長になる。。)

素直に function で書くのがよさそうですね。

Discussion