18
10

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.

ts-resetでTypeScriptのストレスを解消

Last updated at Posted at 2023-03-02

概要

TypeScriptでコーディングしていて、こんなことでストレスを覚えたことはありませんか?

  • Response.json(in fetch)やJSON.parseがanyを返してくるので危険
  • .filter(Boolean)後の型推論にunknownnullが含まれている
  • Array.includesの引数が勝手に推論される

2023/2/19にte-resetがリリースされました。ts-resetを使えばこれらはあなたの期待通りに評価されるようになります。しかも導入はReset CSSを適用するくらい簡単です!

準備

ts-resetを使用したいプロジェクトにパッケージをインストールします。

$ npm i -D @total-typescript/ts-reset

プロジェクトのソースコードディレクトリにreset.d.tsという名前のファイルを作成して、中身を下記の通りに記述します。

import "@total-typescript/ts-reset";

補足

下記のように使用したいルールを限定することもできます。

import "@total-typescript/ts-reset/json-parse";

使ってみる

.filter(Boolean)で偽の値を推論から排除する

Array.filter(Boolean)で配列から偽の値(undefinedやnull)の要素を排除してくれますが、返り値の型にはundefinedやnullが含まれているので困ってしまいます。

// BEFORE
const filteredArray = [1, 2, undefined, null].filter(Boolean); // (number | null | undefined)[]😡

ts-resetを適用すれば期待通りの型を返してくれるようになります。

// AFTER
const filteredArray = [1, 2, undefined, null].filter(Boolean); // number[]

JSON.parseがanyを返さないようにする

JSON.parse()は問答無用でanyを返却してくるので、結果の検証をおろそかにした危険なコードを量産しがちです。

// BEFORE
const result = JSON.parse('{}'); // any😡

console.log(result.hoge); // any型なのでコンパイルエラーにならない

ts-resetを適用すれば、危険なコードと決別できます。返り値の型はunknownになるので、型安全を保証しないとプロパティが参照できなくなります。

type Hoge = {
    fuga: string;
};

// Hoge型の検証
const typeCheckHoge = (obj: unknown): obj is Hoge => {
    const hoge = obj as Hoge
    return 'fuga' in hoge
}

// AFTER
const result = JSON.parse('{}'); // unknown

if (typeCheckHoge(result)) {
    console.log(result.fuga); // 型安全が保証されたのでfugaプロパティが参照できる
} else {
    throw new Error('result is not of type Hoge')
}

Array.includes()で定義以外の文字列を使う

Array.includes()で配列内の要素に対して存在チェックなどを行う場合、通常では型定義に含まれていない文字列は指定できません。

不特定のユーザー入力値が配列のメンバーと一致するかをチェックするシーンなどはよくあるので、そのたびにストレスです。

// BEFORE
const members = ['A', 'B', 'C'] as const;

// 指定できる値の型は 'A' | 'B' | 'C' なのでコンパイルエラーになる😡
members.includes('D');

ts-resetを適用すれば非メンバーの内容は限定されなくなります。

// AFTER
const members = ['A', 'B', 'C'] as const;

// 指定できる値の型は限定されない
members.includes('D');

さらにArray.includesと同様にSet.has()の引数も限定されなくなります。Setを使う場合もストレスフリーですね。

Array.isArray()で検証後にany[]にしない

気を抜くとすぐにanyで推論するTypeScriptですが、Array.isArray()での検証後もany[]で推論されます。これでは危険なコードを許してしまいます。

// BEFORE
const validate = (input: unknown) => {
  if (Array.isArray(input)) {
    console.log(input); // any[]😡
  }
};

ts-resetを適用すればunknown[]となるので、型安全の保証を強制させることができます。

// AFTER
const validate = (input: unknown) => {
  if (Array.isArray(input)) {
    console.log(input); // unknown[]
  }
};

まとめ

以上のようにts-resetを適用することで、TypeScriptのコーディングがさらに快適で安全になることは間違いありません。公式がこれらのストレス要因を解消してくれるまでは、問答無用でプロジェクトに採用したいくらいです。

導入も極めて簡単なので、ぜひとも利用を検討してみてはいかがでしょうか。

参考

18
10
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
18
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?