S SmartDocs
シリーズ: Typescript typescript 79 行 · 更新日 2025-12-27

01-advanced-generics.ts

Typescript/src/03-advanced/01-advanced-generics.ts

// ============================================
// 01. Advanced Generics
// ============================================

// Higher-Order Generics
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

type A = UnwrapPromise<Promise<string>>; // string
type B = UnwrapPromise<string>;          // string

// Recursive unwrapping
type DeepUnwrapPromise<T> = T extends Promise<infer U>
  ? DeepUnwrapPromise<U>
  : T;

type C = DeepUnwrapPromise<Promise<Promise<string>>>; // string

// Generic Constraints with keyof
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

function setProperty<T, K extends keyof T>(
  obj: T,
  key: K,
  value: T[K]
): void {
  obj[key] = value;
}

const user = { name: "Alice", age: 25 };
console.log(getProperty(user, "name")); // string
setProperty(user, "age", 30); // OK
// setProperty(user, "age", "30"); // Error: type mismatch

// Conditional Generic Types
type ApiResponse<T> = T extends string
  ? { message: T }
  : T extends number
  ? { code: T }
  : { data: T };

// Variadic Tuple Types (TypeScript 4.0+)
type Concat<T extends readonly any[], U extends readonly any[]> = [
  ...T,
  ...U
];

type Result = Concat<[1, 2], [3, 4]>; // [1, 2, 3, 4]

function concat<T extends readonly any[], U extends readonly any[]>(
  arr1: T,
  arr2: U
): Concat<T, U> {
  return [...arr1, ...arr2] as any;
}

const result = concat([1, 2], [3, 4]); // [1, 2, 3, 4]

// Generic Type Predicates
function isArrayOf<T>(
  arr: unknown,
  predicate: (item: unknown) => item is T
): arr is T[] {
  return Array.isArray(arr) && arr.every(predicate);
}

function isString(item: unknown): item is string {
  return typeof item === "string";
}

const arr: unknown = ["a", "b", "c"];
if (isArrayOf(arr, isString)) {
  // arr is string[]
  arr.forEach(s => console.log(s.toUpperCase()));
}

export { getProperty, setProperty, concat, isArrayOf };

関連記事