🎄

TypeScript一人カレンダー 2022/2024 目次と索引 記号・A-N

2024/12/26に公開

こんにちは、クレスウェア株式会社の奥野賢太郎 (@okunokentaro) です。本記事は『TypeScript 一人 Advent Calendar 2022』および『TypeScript 一人 Advent Calendar 2024』(TypeScript一人カレンダー) 全50記事の目次と索引ページです。

本アドベントカレンダー内の各記事では、2024年12月、TypeScript 5.7, Next.js 14.x, Valibot 0.42の時点で解説しています。本アドベントカレンダーのすべての記事は、TypeScript初心者を脱し始めてもっと活用していきたいと願う読者層に向けていますので、最低限の前提は省略して記述しています。

目次

シーズン1

第1部 Conditional Types

第2部 Mapped Types

第3部 Assertion Types

  • 17日目 NonNullable<T>と実例 assertExists()
    • NonNullable<T>
    • nullの可能性を除去する実装
      • コンポーネント内でNullableな変数を扱うハンドラ
      • 雑なnull逃し
      • 例外を投げるように変更
    • Assertion Functions
    • assertExists()
    • exists()
    • コンポーネントのハンドラを短く書く
    • 嘘をつけてしまうため注意
    • Array.prototype.filter()でのちょっと便利な書き方
  • 18日目 Branded Typesを導入してみる
    • Nominal TypingとStructural Typing
    • Type Alias
    • Nominal Typing Likeなclass
    • Branded Types
      • Branded Types が解決したこと
  • 19日目 実例 FilledString, UserId
    • Branded Typesの改良
      • Type Assertionsが使えるときと、使えないとき
      • Type Assertionsが危険である状況
      • Assertion Functionsを採用する
    • assertString()asString()
    • FilledString
    • アレンジしたBrand<K, T>で宣言するUserId
  • 20日目 String Literal Typesとas const
    • enum
    • String Literal TypesとUnion Types
    • isSuit()関数を実装する
      • 定数を先に宣言しておくリファクタリング
      • 定数から型定義を作りたい
    • as const

コラム

  • 21日目 if文とswitch文は使い分ける?
    • ちょっとした疑問
    • Narrowingとエディタの挙動
    • Visual Studio Code
      • if
      • switch
    • WebStorm
      • if
      • switch
    • 結論、やはりどっちでもいい
  • 22日目 実例 mapOrElse()
    • ジェネリクスはどういうときに使うか
    • mapOrElse()
    • 身近なジェネリクスを扱う例
  • 23日目 実例 extends Error
    • TypeScriptプログラミングにおけるエラー
    • ECMAScript処理系で実行されるという事実からは逃れることができない
      • 完璧なフォローはコストが高い
    • catchブロック内での型付け
    • catcherrError型インスタンスとは限らない
    • 暗黙的にerr: Errorであると扱えない理由
    • 実例 extends Error
      • Errorを継承しないクラスはおすすめしない
  • 24日目 実例 再帰型定義とRGBA
    • 過去の頑張りを話します
    • TypeScriptの限界
    • RGBA
    • TypeScript 5.0

第4部 Conditional Types, Mapped Types, Assertion Typesを組み合わせる

  • 25日目 実例 assertMatchedType()
    • TypeScriptの集大成
    • 不確実な環境での安心の獲得
      • 不整合は常に起こりうる
      • 防御的プログラミングと契約による設計
      • 不整合はなぜ起こったか
      • 内部起因か外部起因か
    • unknown型を扱った信頼できる仕組みづくり
      • Assertion Functions
      • unknown型を採用する欠点
      • 開発のモチベーション
    • assertMatchedType()の実装
      • 型のユニットテスト
      • 登り方を検討する
      • RemoveNeverProperties<T>
      • Escape<T>
      • UnionToUnionTuple<T>
      • isMatchedType<T>()のランタイム実装
      • assertMatchedType()
    • 完成
    • 総括

シーズン2

第1部 Valibot を前提とした実装の変化

第2部 ユーティリティ集から学ぶ

  • 6日目 DeepReadonly<T>
    • DeepReadonlyを求める理由
    • ts-essentialsのDeepReadonlyを導入する
    • ライブラリ導入時に考えたいこと
    • まとめ
  • 7日目 StrictOmit<T, K>
    • Omit<T, K>の弱点
    • StrictOmit型で厳密なエラーチェック
    • TypeScript標準ユーティリティの設計意図と実務での選択
  • 8日目 実例 ExtractKeyOf
    • Extractの弱点とキー操作
    • ExtractKeyOf<T, K> を自作
    • Rustから学んだ「エラーは学びの源」
    • 自作型作成の指針
  • 9日目 実例 is()
    • typeプロパティを持つオブジェクトとDiscriminated union
    • User-defined Type Guard量産からの卒業
    • 汎用的なis()関数による絞り込み
    • なぜis()が有効なのか
    • まとめ
  • 10日目 実例 hooksTestingTools()
    • runRenderHook() につきまとう副作用の取り扱いとトラブル
    • hooksTestingToolsFactory()の導入
    • 実務発のニーズとそれを解決させる工夫の匙加減
  • 13日目 実例 mustFind()
    • strictNullChecksの便利さと不便さ
    • mustFind() の実装例
    • オーバーロードでType predicate signatureにも対応する
    • テストコードでの確認
    • TypeScriptテクニックを実務に活かす
  • 14日目 Vitest test-d.ts で複雑な型をテストする
    • 型定義にもテストを書く時代
    • Vitestで型定義をテストする
      -「型パズル」と呼ばせないために

第3部 TypeScript の新機能を学ぶ

  • 11日目 noUncheckedIndexedAccess
    • 配列アクセス時のundefinedリスクを検出するオプション
    • 無効時と有効時の挙動を比較
    • undefinedチェックの手間を惜しまない
    • as const も併用する
    • 今すぐオプションの有効化を検討しよう
  • 12日目 satisfies
    • satisfiesで型適合性を柔軟に示す
    • 変数型アノテーションとas constの組み合わせによる歪み
    • satisfiesで型を表現
    • satisfiesは難しそう?いや文字数が長いだけ
  • 20日目 ECMAScript Private Fields
    • TypeScriptにおけるprivateとECMAScript Private Fields
    • コンパイラ・ランタイムの対応状況と運用
    • 実際の業務ではどう使う?
    • まとめ
    • おまけ サンプルコード全容
  • 21日目 using宣言
    • ECMAScriptの進化とusing宣言
      • using宣言とは?
      • finallytryだけの組み合わせをシンプル化
      • デバッグ用ツールへの導入例
      • usingはリソース破棄だけに使うべきか
      • 将来への期待
    • おまけ:計測処理の全容

第4部 モダンWebアプリケーション開発現場からの実例集

  • 15日目 App Router 時代のエラーハンドリング
    • 2年前からのエラーハンドリングの変化
    • App Routerでのエラーハンドリングの難しさ
    • e instanceof に頼らないハンドリングへの回帰
    • RSCからClient componentへのインスタンス渡しの問題
    • 早期発見の仕組みのために点検を
    • エラーハンドリングは最優先で習得すべきスキル
  • 16日目 実例 Result<T, E>
    • エラーの系統を考察する
    • プラットフォームがエラーメッセージを加工する盲点
    • throwからResult<T, E>への転換
    • Result<T, E>
    • さらなる欲求
    • 戦略的な割り切り
    • 学びと総括
  • 17日目 実例 ConvenienceFixture, orDefault()
    • テストとモックの煩雑さに立ち向かう
    • Branded typesとテストモックの両立
    • ConvenienceFixture型とorDefault()関数
    • ConvenienceFixture型の型テスト
  • 18日目 実例 PageContext, AllowTransitionFrom
    • App Routerへの大規模リアーキテクチャ
    • 複雑なパラメータを管理するPageContextという概念を整備
      • どこで使いたいものか、どこでなら再利用してよいのか
    • 複雑な遷移を型レベルで制御
      • AllowTransitionFrom型の実例
      • なぜページ名の分岐パラメータを増やさないのか
      • 「自由を奪う」ことのメリット
    • まとめ
  • 19日目 実例 UnknownifyDiscriminatedUnion
    • PageContextsubjectパラメータ
    • extractPageContext() 関数で PageContext を作成
    • InferInput<T>unknown
    • subject 以外をすべて unknown
    • 型テストの実例
    • any回避とunknownの採用

第5部 昨今の開発環境とエコシステムを追いかける

  • 22日目 tsx TypeScript Execute
    • tsx とは
      • Node.jsでTypeScriptを動かす
    • CJS, ESMの移行過渡期による混迷と、tsxの登場
    • TypeScriptランタイムとしての選択肢
      • WinterCGの動き
    • それでもtsxがしっくりくる
  • 23日目 tsupでバンドルする
    • JavaScriptのモジュール史とバンドル文化
      • ESMが正式に実装される流れ
      • 2024年現在の様子
    • tsupが生まれた背景
      • なぜtsupが優れているか
      • 省コンフィグ
    • tsupの裏側
    • まとめ
  • 24日目 Biomeを使ったLintとフォーマット
    • ESLintというlintツール
    • Prettierというフォーマットツール
    • Biomeの台頭
    • Biomeへの乗り換え手順
      • タブインデントへの抵抗感
      • 5匹の猿の実験
    • 今後のBiomeに期待
  • 25日目 今後のTypeScriptに期待すること
    • TypeScriptへの期待
      • TypeScriptはここ数年でも進化を続けている
    • 今後を自由に妄想
      • NonNullable<T>のsugar記法がほしい
      • ConstraintOf<T>のような型制約を取り出すユーティリティ型
      • 高カインド型 (HKT) も欲しい
      • 型のパターンマッチも欲しい
    • TC39提案の動向
    • WASMの進化はどうなるか
      • WASMとJSを両方出力する言語が流行る?
    • 遥か未来のWebアプリケーション開発
      • Webブラウザ界に一波乱あるか
      • AIフレンドリーなコード
    • TypeScript 一人 Advent Calendar 2024のしめくくり

索引

記号・数字

  • __brand (Branded Types Idiom) / 2218, 2219, 2402
  • --strictNullChecks / → Strict Null Checks
  • -readonly / → Mapping Modifiers
  • ! / → Non-null Assertion Operator
  • ?: / → Mapped Types
  • ?. (オプショナルチェーン演算子) / 2411
  • ? : / → Conditional Types
  • .cjs (拡張子) / 2423
  • .cts (拡張子) / 2423
  • .editorconfig / 2424
  • .js (拡張子) / 2423
  • .mjs (拡張子) / 2423
  • .mts (拡張子) / 2423
  • .test-d.ts (拡張子) / 2414
  • .ts (拡張子) / 2422
  • .tsx (拡張子) / 2422
  • "" (空文字列) / 2212, 2219
  • "use client" (React) / 2415
  • [...arr] / → Spread Syntax
  • [] (空配列) / 2212
  • [0] / → Indexed Access Types
  • [number] / 2205
  • [object Object] / 2218
  • [P in K] (Mapped Types) / 2209
  • [P in keyof T] (Mapped Types) / 2209
  • @testing-library/react / 2204
  • # (Private Fields) / 2420
  • +?: / → Mapping Modifiers
  • <T> / → ジェネリクス
  • | null (Nullable) / 2206, 2217
  • | / → Union Types
  • $() (筆者作、Valibot) / 2405
  • ${T[P]} (Template Literal Types) / 2209
  • 5匹の猿の実験 / 2424

A

B

C

D

E

F

G

H

  • Haskell / 2213, 2223, 2416
  • HasProperty (ECMAScript) / 2212
  • Higher Kinded Types / → 高カインド型
  • hooksTestingToolsFactory() (筆者作) / 2410
  • IDE / 2221

I

J

K

L

M

N

0-Z・あーん

Discussion