[TypeScript]ジェネリッククラス
class Box<T> { private value: T; constructor(value: T) { this.value = value; } getValue(): T { return this.value; } setValue(newValue: T): void { this.value = newValue; } } // 使用例 const numberBox = new Box<number>(10); console.log(numberBox.getValue()); // 10 const stringBox = new Box<string>("Hello"); console.log(stringBox.getValue()); // "Hello"
複数の型パラメータ
class Pair<T, U> { constructor(private first: T, private second: U) {} getFirst(): T { return this.first; } getSecond(): U { return this.second; } } // 使用例 const pair1 = new Pair<number, string>(1, "One"); console.log(pair1.getFirst()); // 1 console.log(pair1.getSecond()); // "One" const pair2 = new Pair<boolean, string>(true, "True"); console.log(pair2.getFirst()); // true console.log(pair2.getSecond()); // "True"
ジェネリック型Tに特定の型を継承させて型の制約を設ける
class Calculator<T extends number> { private value: T; constructor(value: T) { this.value = value; } add(num: T): number { return this.value + num; } } // 使用例 const calc = new Calculator(10); console.log(calc.add(5)); // 15 // const invalidCalc = new Calculator("Hello"); // エラー: stringはnumberを継承していない
クラスとインターフェースの組み合わせ
interface Identifiable { id: number; } class Repository<T extends Identifiable> { private items: T[] = []; add(item: T): void { this.items.push(item); } findById(id: number): T | undefined { return this.items.find(item => item.id === id); } } // 使用例 interface User { id: number; name: string; } const userRepo = new Repository<User>(); userRepo.add({ id: 1, name: "Taro" }); userRepo.add({ id: 2, name: "Jiro" }); console.log(userRepo.findById(1)); // { id: 1, name: "Taro" } console.log(userRepo.findById(3)); // undefined
デフォルト型を指定
class DefaultBox<T = string> { private value: T; constructor(value: T) { this.value = value; } getValue(): T { return this.value; } } // 使用例 const defaultBox = new DefaultBox("Hello"); // string型を推論 console.log(defaultBox.getValue()); // "Hello" const numberBox = new DefaultBox<number>(100); // 明示的にnumber型を指定 console.log(numberBox.getValue()); // 100
コンストラクタで型推論
class DataStorage<T = number>{ private items:T[] = []; constructor(initItems?:T[]){ if(initItems){ this.items.push(...initItems); } } } let stringStorage = new DataStorage(["A","B"]);
ジェネリッククラスの継承
class DataStorage<T>{ private items:T[] = []; } class DataStorageSub extends DataStorage<string>{ logAllItems():void{ console.log([...this.items]); } } class DataStorageSub<T> extends DataStorage<T>{ logAllItems():void{ console.log([...this.items]); } getLastValue():T{ return this.items[this.items.length-1]; } }