概要
Claudeにちゃんと書いてこなかった言語のカリキュラムをつくってもらって学習している。
TypeScript学習カリキュラム Day 2。関数の型アノテーション、Union型・Intersection型、never型による網羅性チェックを学習した。
今日学んだこと
※一部Day1の内容が混ざっている
関数の型アノテーション
- 基本の
function宣言とアロー関数(=>)の2パターン - オプショナル引数(
?)とデフォルト値 - Null合体演算子(
??): Rubyの||に近いが、nullとundefinedだけを判定する
Union型の深掘り
- リテラル型のUnion(
type Status = "pending" | "in_progress" | "done")で、決まった値だけを許容する型が作れる - Rubyのシンボル的な使い方に近い
Intersection型(&)
- 複数の型を合体させる(
type Person = Name & Age) - Rubyの
Hash#mergeのイメージ
never型と網羅性チェック
neverは「ここには絶対来ないはず」を表す型switchのdefaultでneverに代入することで、case の追加漏れをコンパイルエラーで検出できる- Rubyの
raiseのコンパイル時版のようなもの _exhaustive: neverをreturnすれば、neverは全ての型の部分型なので戻り値の型エラーにならない
実践課題
formatValue(value: string | number | boolean): string を実装。
string→"文字列: hello"number→ 小数点2桁にして"数値: 3.14"(.toFixed(2))boolean→"真偽値: はい"/"真偽値: いいえ"typeofによる型ガードで分岐neverによる網羅性チェック
結果: 課題クリア!型ガードと網羅性チェックを正しく実装できた。
質問と回答
Q: Union型はRubyにない概念?一つの変数で複数の型を許容できる?
その通り。Rubyは動的型付けなので何でも入るが、TSは|で明示的に許容する型を宣言する。
Q: null / undefinedはRubyでいうとnilと変数未定義?
ほぼ合っている。null = Ruby の nil(意図的に「値がない」)、undefined = 変数が未定義・プロパティが省略された状態。
Q: 型ガードはどう実現されている?
実行時に何か特別なことをしているわけではなく、TSコンパイラが if 文を静的解析して型を絞り込んでいる。コンパイル後のJSには型情報は一切残らない。
Q: neverのdefaultで何をreturnすればいい?
const _exhaustive: never = value; return _exhaustive; とすればOK。never は全ての型の部分型なので、string を返す関数でも型エラーにならない。
Q: 変数名の先頭の _ は慣習?
Rubyと同じで「この変数は使わないよ」という意味の慣習。TSでも未使用変数の警告を抑制できる。
Q: 独自型の命名に慣習はある?
大文字始まり(PascalCase)が慣習。Status、Value など。
メモ
- 変数展開文字列は
`${}` toFixedは文字列を返すswitchのあとが評価式でcaseに値が来る- 三項演算子はRubyと一緒