TypeScriptを使用しているとき、型の推論が意図通りではない部分があります。
そのような場合に役立つアプリケーションコードとして、ts-resetが挙げられます。
ts-resetとは
ライブラリではなく、アプリケーションコードで使用するように設計されているようです。
インポートするだけで、TypeScriptの組み込み型付けを補正してくれます。
どういった推論になるのか、代表的なメソッドに絞って検証していきます。
.filter(Boolean)
配列の各要素に対して実行するテスト関数で、false
を返した要素を取り除きます。
実装前
推論結果にundefined
が含まれています。
以下のコードでundefined
は入らないことが決まっていますので、falsyな値を除いた型を返して欲しいです。
const filteredArray = [1, 'a', null, undefined].filter(Boolean)
// (string | number | null | undefined)[]
実装後
falsyな値はなくなり、残りの型の推論だけ行われていることが確認できます。
import '@total-typescript/ts-reset/dist/filter-boolean'
const filteredArray = [1, 'a', null, undefined].filter(Boolean)
// (string | number)[]
JSON.parse
文字列をJSONとして解析し、文字列によって記述されているJavaScriptの値やオブジェクトを構築するメソッドです。
実装前
推論結果はany
型になっており、なんでも受け付けてしまいます。
const json = JSON.stringify({
name: 'John'
})
const parse = JSON.parse(json) // any
実装後
unknown
型に推論されます。
これで型がより強固になり、型ガードを使用して型推論するようになっています。
import '@total-typescript/ts-reset/dist/json-parse'
...
type Props = {
name: string
}
// エラー
const parse = JSON.parse(json) // unknown
console.log(parse.name) // 'parse' is of type 'unknown'
// 型ガード
function isParseProps(value: unknown): value is Props {
return typeof value === 'object' && value !== null && 'name' in value
}
if (isParseProps(parse)) {
console.log(parse.name) // parse: Props
}
json()
fetch APIを使用している場合、json()
メソッドを使用してデータを取得していきます。
実装前
json()
使用後は型はany
型になっています。
fetch('/')
.then(res => res.json())
.then(json => {
console.log(json) // any
})
実装後
unknown
となります。
JSON.parse()
と同じく、型ガードを使用して型推論するようになっています。
import "@total-typescript/ts-reset/dist/fetch";
fetch('/')
.then(res => res.json())
.then(json => {
console.log(json) // unknown
})
includes on as const
includes
メソッドは配列内に指定した値があるかを検査してくれます。
ここでは、定数にas const
を使用した場合の挙動を見ていきます。
実装前
as const
を使用したことで、テストする文字列の引数はusers
の中の値に絞られています。
以下のように、入力した値がusers
にあるか確認したい時には不都合です。
const users = ['a', 'b', 'c'] as const
const isUser = (input: string) => {
// Argument of type 'string' is not assignable to parameter of type '"a" | "b" | "c"'
if (users.includes(input)) {
console.log(input)
}
}
実装後
as const
でリテラル型として扱われていた型がstring型まで拡張されています。
これにより、不都合な型の絞り込みを解消できます。
import '@total-typescript/ts-reset/dist/array-includes'
...
// string
if (users.includes(input)) {
console.log(input);
}
...
個人的な使用感
組み込みTypeScriptでは届かない部分を補ってくれた印象です。個人的にはfilter
メソッドの改善が嬉しいです。
使用頻度の高いメソッドに対して導入していき、型をより強固にする方法がいいかと感じます。
他にも対応しているメソッドがありますので、詳細はドキュメントから確認してください。
最後に
GoQSystemでは一緒に働いてくれる仲間を募集中です!
ご興味がある方は以下リンクよりご確認ください。