-- Views
June 27, 26
スライド概要
はじめまして、yukikoと申します。 IT教育支援や、DX推進が可能です。 ◆ スキル LPIC レベル2 AI / Python Splunk BI(データ可視化・分析) ◆ その他 新卒・未経験の学生向けに、エンジニア転職を応援する資料を趣味で作成しています。 もしよろしければご活用ください。
TypeScript TS 原理原則・公式仕様・ライブラリ完全ガイド 型理論 構造的部分型 公式仕様書 型推論エンジン うさうさ研修工房 | うさうさ先生 Spec: TypeScript Language Specification | typescriptlang.org | GitHub: microsoft/TypeScript エコシステム
TypeScript 公式設計目標(Design Goals) G1 JavaScript のスーパーセット 全ての有効なJSコードは有効なTS。 既存資産を100%活用可能。 G2 静的型検査(オプション) 型アノテーションは任意。 段階的型付け(Gradual Typing)採用。 G4 大規模開発向けの言語 G5 型消去(Type Erasure) モジュール・名前空間・クラスで 巨大コードベースを管理可能に。 実行時に型情報は消える。 ランタイムオーバーヘッドゼロ。 出典: microsoft/TypeScript — Design Goals (GitHub Wiki) G3 最新JS機能のサポート TC39 提案をいち早く実装。 ES2015〜最新まで対応。 G6 優れた開発者体験 LSP対応・IDEサポートが設計の中心。 補完・リファクタリング・エラー表示。
型理論の核心:構造的部分型(Structural Subtyping) 構造的型付け(Duck Typing) 「同じ形=同じ型」 名前でなく構造で互換性を判定。 Javaのような nominal typing とは別物。 部分型関係 型Aが型Bのすべてのプロパティを 持つなら A は B のサブタイプ。 幅(width)・深さ(depth)の両方向で成立。 Excess Property Checks オブジェクトリテラル直接代入時のみ 余分なプロパティを検出。 変数経由なら検査されない(設計上の意図)。 参考: TypeScript Handbook — Type Compatibility // 構造的部分型の例 interface Point2D { x: number; y: number; } interface Point3D { x: number; y: number; z: number; // 余分なプロパティ } const p3: Point3D = {x:1, y:2, z:3}; // OK: Point3D は Point2D のサブタイプ const p2: Point2D = p3; // NG: オブジェクトリテラル直接代入 const p2b: Point2D = {x:1,y:2,z:3}; // → Object literal may only specify // known properties
型推論エンジンの仕組み(Type Inference)
① 変数初期化推論
② 関数戻り値推論
let x = 42;
// number
let s = "hello";
// string
let b = true;
// boolean
let arr = [1, 2, 3]; // number[]
function add(a: number, b: number) {
return a + b; // 戻り値: number
}
// → (a: number, b: number) => number
③ コンテキスト型推論
④ Best Common Type
const nums = [1, 2, 3];
nums.forEach(n => {
// n は自動的に number 型
console.log(n.toFixed(2));
});
出典: TypeScript Handbook — Type Inference
// 異なる型の配列→共通型を推定
let mixed = [1, "two", true];
// → (number | string | boolean)[]
let items = [new Dog(), new Cat()];
// → (Dog | Cat)[]
型の合成:Union / Intersection / Conditional Types
Union Type ( A | B )
type ID = string | number;
type Result = "ok" | "error" | "pending";
最も多用される型合成。Discriminated
Union はTSのイディオム中のイディオム
。
// Discriminated Union(判別共用体)
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rect";
w: number; h: number };
Intersection Type ( A & B )
type Admin = User & { permissions: string[] };
型を「掛け合わせる」。Mixin設計や
APIレスポンスの拡張に頻出。
// Mixin パターン
type Serializable = { serialize(): string };
type Printable = { print(): void };
type Document = Serializable & Printable;
Conditional Type ( T extends U
?X:Y)
// 標準ライブラリも多用
type NonNullable<T> = T extends null | undefined ? never : T;
type ReturnType<T> = T extends (...args: any) => infer R ? R : never;
TypeScript最大の特徴。型レベルのifthen-else。inferキーワードで型を「抽出
」する。
// 分配条件型(Distributive)
type ToArray<T> = T extends any ? T[] : never;
type Res = ToArray<string | number>; // string[] | number[]
出典: TypeScript Handbook — Unions, Intersections, Conditional Types
Generics(ジェネリクス)詳解
Generics とは?
型パラメータ化
型を「変数」として扱う。
コードの再利用性を最大化。
制約(Constraints)
extends で型パラメータに
条件を追加できる。
デフォルト型
T = string のように
デフォルト値を設定可能。
複数型パラメータ
<K, V> のように複数指定。
MapやDictionaryで多用。
出典: TypeScript Handbook — Generics
// 基本的なジェネリック関数
function identity<T>(arg: T): T {
return arg;
}
// 制約付きジェネリクス
function getLength<T extends { length: number }>(
arg: T
): number {
return arg.length;
}
// ジェネリッククラス
class Stack<T> {
private items: T[] = [];
push(item: T): void { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
}
// keyof 制約(プロパティアクセス安全化)
function getProperty<T, K extends keyof T>(
obj: T, key: K
): T[K] {
return obj[key];
}
組み込み Utility Types(標準ライブラリ) Partial<T> Required<T> Readonly<T> Pick<T, K> 全プロパティをOptionalに 全Optionalを必須に 全プロパティを読み取り専用に 指定プロパティのみ抽出 Partial<User> が? → 全フィールド Required<Config> → ?を除去 Readonly<Point> → 代入不可 Pick<User, 'id'|'name'> Omit<T, K> Record<K, V> Exclude<T, U> Extract<T, U> 指定プロパティを除外 KeyとValueでオブジェクト型を構 築 Union型からUを除外 Union型のうちUに代入可能なもの だけ Omit<User, 'password'> Record<string, number> Exclude<'a'|'b'|'c', 'a'> 'b'|'c' NonNullable<T> ReturnType<T> Parameters<T> Awaited<T> null / undefined を除外 関数の戻り値型を取得 関数の引数タプル型を取得 Promise の解決型を取得 ReturnType<typeof fetch> Parameters<typeof console.log> Awaited<Promise<string>> string NonNullable<string|null> string → 出典: TypeScript Handbook — Utility Types | lib.es5.d.ts / lib.es2015.d.ts → Extract<string|number, number> → number →
tsconfig.json 重要オプション解説 tsconfig.json — 推奨設定 { strict: true "compilerOptions": { // 出力ターゲット "target": "ES2022", "module": "NodeNext", "lib": ["ES2022", "DOM"], 7つの厳格チェックを一括有効化。 必ずONにすること。 target // 厳格チェック(全部 ON) "strict": true, // noImplicitAny は strict: true に含まれる // モジュール解決 "moduleResolution": "NodeNext", "esModuleInterop": true, // 出力先 "outDir": "./dist", "rootDir": "./src", "declaration": true, "declarationMap": true, "sourceMap": true, 設定の意味 コンパイル後のJS バージョン。 Node.js 18+ → ES2022推奨。 module モジュール形式。 NodeNext でESM/CJS自動判別。 declaration: true 型定義ファイル(.d.ts)を生成。 ライブラリ公開時は必須。 sourceMap: true // .d.ts生成 } } 出典: TSConfig Reference — typescriptlang.org/tsconfig デバッグ用マップを生成。 本番でもエラー追跡が容易に。 moduleResolution NodeNext はpackage.json exports フィールド対応。
TypeScript エコシステム主要ライブラリ フレームワーク Next.js バリデーション Zod React+TS公式推奨。App Router完全対応。 スキーマ定義から型を自動生成。z.infer<typeof Schema>が強力。 NestJS Yup Node.js バックエンドフレームワーク。デコレータ多 用。 フォームバリデーション定番。Formikと組み合わせ 多い。 状態管理 Zustand 軽量でTS型安全。Reactとの相性○。 Redux Toolkit RTKはTS前提設計。createSliceで型推論。 Angular class-validator TanStack Query TSファースト設計の老舗フレームワーク。 デコレータベース。NestJSと相性抜群。 非同期状態管理。型安全なAPI通信。 テスト ビルドツール 型定義 Vitest ts-node / tsx DefinitelyTyped Vite連携・Jest互換。TS対応が最速。 TSファイルを直接実行(開発時)。 @types/xxx で型定義を追加。Github最大規模。 Jest + ts-jest esbuild type-fest 最も普及。設定は多いが安定。 超高速バンドラー。TSトランスパイルも爆速。 便利なユーティリティ型コレクション。 Playwright swc ts-toolbelt E2EテストのデファクトスタンダードTS対応。 Rustで書かれた爆速TSコンパイラ。 型レベル操作の高度ライブラリ。
型定義ファイル(.d.ts)と Declaration Merging
.d.ts ファイルとは
型情報のみを含む宣言ファイル。JSライブラリに型情報を後付けできる。コンパイル後のJSには含まれない(型消去)。
@types/* パッケージはDefinitelyTypedリポジトリで管理されOSSコミュニティが保守。
// math.d.ts(型定義ファイル)
declare module 'my-math' {
export function add(
a: number, b: number
): number;
export const PI: number;
export interface Vector {
x: number; y: number;
}
}
// global宣言の拡張
declare global {
interface Window {
myPlugin: Plugin;
}
}
出典: TypeScript Handbook — Declaration Merging, .d.ts Files
Declaration Merging
インターフェースのマージ
同名interfaceは自動的にマージされる。
型の段階的拡張が可能。
モジュール拡張
既存ライブラリの型定義を
プロジェクト内で拡張できる。
namespaceとクラスの合体
classに同名namespaceを追加し
静的メソッドの型を分離管理。
型ガード(Type Guards)と Narrowing
typeof ガード
instanceof ガード
function pad(x: string | number) {
if (typeof x === "string") {
return x.toUpperCase(); // ← string確定
}
return x.toFixed(2); // ← number確定
}
function handle(e: Error | MyError) {
if (e instanceof MyError) {
e.customMethod(); // MyError確定
} else {
console.error(e.message);
}
}
in 演算子ガード
ユーザー定義型ガード(is)
type Cat = { meow(): void };
type Dog = { bark(): void };
function isString(x: unknown): x is string {
return typeof x === "string";
}
function speak(pet: Cat | Dog) {
if ("meow" in pet) {
pet.meow(); // Cat確定
} else pet.bark();
}
出典: TypeScript Handbook — Narrowing
// Assertionガード
function assertDefined<T>(
x: T | undefined
): asserts x is T {
if (!x) throw new Error();
}
公式リファレンス・参考文献一覧 公式ドキュメント(必 読) 深掘りリソース 学術・仕様系 TypeScript Handbook typescriptlang.org/docs/handbook/intro.html — 全機能の公式ガイド TSConfig Reference typescriptlang.org/tsconfig — 全コンパイルオプション網羅 TS Language Specification github.com/microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md What's New in TS typescriptlang.org/docs/handbook/release-notes/overview.html Type Challenges github.com/type-challenges/type-challenges — 型パズル500問以上 TypeScript Deep Dive basarat.gitbook.io/typescript — 無料・高品質・英語 Total TypeScript totaltypescript.com — Matt Pocock のTS上級コース ts-pattern github.com/gvergnaud/ts-pattern — Pattern Matching ライブラリ Bierman et al. (2014) "Understanding TypeScript" — ECOOP 2014 論文。型システムの理論的背景 Gao et al. (2017) "To Type or Not to Type" — MSR 2017。JSバグの15%予防を実証 TC39 Proposals github.com/tc39/proposals — TS先行実装の元となるJS提案一覧 DefinitelyTyped github.com/DefinitelyTyped/DefinitelyTyped — @types の源泉 うさうさ研修工房 — TypeScript 原理原則・公式仕様・ライブラリ完全ガイド