背景
配列の中にundefinedが紛れていて、それを取り除いた配列を作りたい場合、例えばrubyだと
# ruby
2.5.5 (main)> ["foge", nil, "huga", "foga", nil, "fuge"].compact
=> ["foge", "huga", "foga", "fuge"]
こんな感じでパッとかけますが、jsだと多少面倒。
// javascript
["foge", undefined, "huga", "foga", undefined, "fuge"].filter(e => e)
=> ["foge", "huga", "foga", "fuge"]
これをtypescriptで書くと悲しいことに、
// typescript
const newArray = ["foge", undefined, "huga", "foga", undefined, "fuge"].filter(e => e);
この newArray
の型が、 (string | undefined)[]
となってしまう。これをどうにかして string[]
にしたいよね、という話。
解決策: Type predicates を使う
例はこんな感じ。
function isHoge(s): s is Hoge {
return typeof s === 'hogehoge';
}
この例では訳わからないことをしていますが、あくまで例として。
type predicates
は s is Hoge
部分です。
なにをやっているかを一言で言うと、 この関数がtrueを返す場合、パラメータsの型をHogeとする ということです。
これを使って色々なものが書きやすくなりますが、今回はあくまで上記の filter
の例にかぎって紹介します。
完成形
const newArray = ['foge', undefined, 'huga', 'foga', undefined, 'fuge'].filter((e): e is string => Boolean(e));
つまり、 Boolean(e)
がtrueを返す場合(この場合だと undefined
以外)、e
をstring
とする、と宣言しているわけです。
これで、 newArray
の型が、 string[]
となります。
PS
typescript強者の方、これよりも良い方法があればご教示ください...