社内勉強会でTypeScript勉強を行ったのでメモとして残します。
内容をAIと話しながら内容を整理して、最終的なまとめはAIに行ってもらいました。
あくまで備忘録して残したいため。
以下概要
React + TypeScript の勉強会で印象的だったのが、
reduceやmapの実装ではなく「型定義(シグネチャ)」を見るという話でした。
普段は
array.map(...)
array.reduce(...)
のように使うだけですが、
TypeScriptでは 型定義を見ると理解がかなり深まるという話でした。
実際に画面に型定義を出して、指差しながら説明してもらったのがとてもわかりやすかったので、自分のメモとして整理しておきます。
配列とは何か
まず前提として、TypeScriptでは配列はこう定義されています。
interface Array<T>
ここで
T = 配列の要素の型
です。
例えば
const a = [1,2,3]
これは実際には
Array<number>
つまり
T = number
になります。
勉強会で言われて印象に残ったのは、
「配列です」ではなく「何の配列か」が重要
という話でした。
Javaだと
List<String>
Pythonだと
list[str]
のように 要素型が必ず決まるので、
Array<T>
も同じ考え方です。
new Array()
例えば
const b = new Array<string>()
これは
Array<string>
を作っているという意味です。
つまり
T = string
なので、この配列には
string
が入る想定になります。
実際のreduceの型定義
TypeScriptのArrayにはこういう型定義があります。
interface Array<T> {
reduce<U>(
callbackfn: (
previousValue: U,
currentValue: T,
currentIndex: number,
array: T[]
) => U,
initialValue: U
): U;
}
ここで重要なのが
T
U
です。
T と U とは
T = 配列の要素型
U = reduceの結果の型
です。
実際のコードで考える
const a = [1,2,3]
これは
Array<number>
なので
T = number
です。
reduceの例
const b = new Array<string>()
b.reduce((acc, hoge, foo, piyo) => {
return ''
}, 'a')
ここで
T = string
になります。
なので
hoge: string
です。
initialValueでUが決まる
この部分
'a'
が
initialValue
なので
U = string
になります。
つまり
acc: string
return: string
になります。
勉強会での説明(ここが理解ポイント)
勉強会では型定義を見ながらこう説明してくれました。
reduce<U>(
callbackfn: (
previousValue: U,
currentValue: T,
ここで
T
U
が決まると
他の場所も全部決まる
という説明でした。
例えば
T = string
なら
currentValue: string
array: string[]
になります。
mapの型定義
参考としてmapも見てみます。
map<U>(
callbackfn: (value: T, index: number, array: readonly T[]) => U
): U[];
ここでは
T → U
という変換です。
例えば
[1,2,3].map(n => n.toString())
ここでは
T = number
U = string
なので
string[]
が返ります。
reduceとmapの違い
整理すると
map
T → U
reduce
T → U (集約)
mapは
number[] → string[]
reduceは
number[] → number
などになります。
コードフォーマットの話
勉強会では、reduceの改行位置についても話がありました。
例
array.reduce(
(acc, cur) => {
return something
},
initialValue
)
または
array.reduce((acc, cur) => {
return something
}, initialValue)
まとめ
今回の勉強会で一番学びになったのは
実装ではなく型定義を見る
ということでした。
特に
interface Array<T>
reduce<U>()
map<U>()
のようなジェネリクスを見ると
- T = 配列の要素型
- U = 変換後の型 / 結果型
が理解できます。
reduceやmapは普段何気なく使っていますが、
型定義を読むことで TypeScriptの理解がかなり深まると感じました。


コメント