TypeScriptのスプレッド構文に気を付けて
はじめに
TypeScriptにはスプレッド構文という便利な記法があります。その記法を使えば、オブジェクトからオブジェクトへの値の代入が簡単になりますが、注意点があったので記事を書きたいと思います。
記事で紹介しているコードはTypeScript Playgroundで試すことが出来ます。
スプレッド構文の説明
オブジェクトでの使い方
説明
スプレッド構文とは、下のコードの...{変数名}としている記法のことです。
この記法を用いることで、UserからUserResのオブジェクトに値を入れなおすことが出来ます。
type User = { id: number; name: string; }
const user = { id: 0, name: "あお"}
type UserRes = { id: number; name: string; }
const resUser: UserRes = { ...user }
console.log(resUser)
出力
{
"id": 0,
"name": "あお"
}
便利な使い方
スプレッド構文を使いながら、ageのような足りないメンバを補ったり、
nameのように上書きすることが出来ます👍
足りないメンバがある場合は、TypeScriptが指摘してくれるので安心です💕
type User = { id: number; name: string; }
const user = { id: 0, name: "あお"}
type UserRes = { id: number; name: string; age: number}
const resUser: UserRes = { ...user, name: "ウグイス", age: 26 }
console.log(resUser)
出力
{
"id": 0,
"name": "ウグイス",
"age": 26
}
使い方3
複数のスプレッド構文を使うこともできます。
type User = { id: number; name: string; }
const user = { id: 0, name: "あお"}
const userAddress = { pref: "神奈川", city: "横浜"}
type UserRes = { id: number; name: string; age: number; pref: string, city: string}
const resUser: UserRes = { ...user, name: "ウグイス", age: 26, ...userAddress}
console.log(resUser)
配列での使い方
配列を結合することが出来ます。
const list1 = [0, 1, 2]
const list2 = [3, 4, 5]
const listNew = [...list1, ...list2]
console.log(listNew)
出力
[0, 1, 2, 3, 4, 5]
スプレッド構文の注意点
一番伝えたいことになります。
以下のようにスプレッド構文を書いた場合resUserはどうなるでしょうか?
TypeScriptで型注釈しているから、userResには{ id: 0, name: "あお"}が入るはず。
メンバが足りなかったら怒られるし。。
type User = { id: number; name: string; innerData: string }
const user = { id: 0, name: "あお", innerData: "外に出す必要がないデータ"}
type UserRes = { id: number; name: string; }
const resUser: UserRes = { ...user }
console.log(resUser)
しかし、出力されるのは以下の内容になります。
{
"id": 0,
"name": "あお",
"innerData": "外に出す必要がないデータ"
}
UserResの型にはないinnerDataが入ってしまいます😰
これに関しては、こういう仕様だとしか言えないのですが、
スプレッド構文は下のようにJavaScriptに変換されます。
const resUser = Object.assign({}, user);
TypeSciptはメンバが足りないときに指摘してくれたとしても、
余分なメンバがある時には指摘せずにObject.assign({},...)に変換してしまいます。
このコードが動けば余分メンバが入ってしまいます😢
これを回避するためには、メンバごとに代入をしていく必要があります。
おわりに
スプレッド構文はコードが少なくなって、見やすくはなりますが、
代入先の型注釈に無いメンバが入りこむ場合がありますの、使い場所に注意しましょう!
Discussion