Загрузка…
Загрузка…
TypeScript · middle · сложность 5
Generics сохраняют связь «тип элементов массива → тип результата». Ниже — типичные паттерны на собеседовании: first, map, контейнер Stack и антипаттерны с any и «бесполезным» <T> только в return.
// Generic preserves the input→output relationship; inference fills T
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
const n = first([1, 2, 3]); // T = number → number | undefined
const s = first(['a', 'b']); // T = string → string | undefined
// ❌ any loses the type; caller gets no help downstream
function firstBad(arr: any[]): any { return arr[0]; }
const x = firstBad([1, 2]); // x: any — unsafe from here on
// Multiple type params chain through composition
function map<T, U>(arr: T[], fn: (x: T) => U): U[] {
return arr.map(fn);
}
map([1, 2], n => `#${n}`); // T=number inferred, U=string inferred → string[]
// ❌ Unusable generic — T appears only in return; nothing to infer from
function create<T>(): T { return {} as T; } // caller MUST annotate; smell// Generic container: remembers what it holds
class Stack<T> {
private items: T[] = [];
push(x: T) { this.items.push(x); }
pop(): T | undefined { return this.items.pop(); }
}
const s2 = new Stack<string>(); // or inferred from first push in some casesХороший generic связывает несколько позиций в сигнатуре и выводится из аргументов; any и «одинокий» type parameter — признаки плохого дизайна.