Дженерик-функции
Дженерик-функции принимают параметр типа и работают с любым типом.
Базовый пример
function identity<T>(value: T): T {
return value;
}
const a = identity('hello'); // string
const b = identity(42); // number
const c = identity({ x: 1 }); // { x: number }
Несколько параметров
function pair<A, B>(a: A, b: B): [A, B] {
return [a, b];
}
const p = pair('x', 1); // [string, number]
Дженерик-массивы
function first<T>(items: T[]): T | undefined {
return items[0];
}
function last<T>(items: T[]): T | undefined {
return items[items.length - 1];
}
function filter<T>(items: T[], predicate: (item: T) => boolean): T[] {
return items.filter(predicate);
}
Map
function map<T, U>(items: T[], fn: (item: T) => U): U[] {
return items.map(fn);
}
const lengths = map(['a', 'bb', 'ccc'], (s) => s.length);
// number[]
TypeScript выводит U из возвращаемого типа функции.
Функция с callback
function tap<T>(value: T, fn: (value: T) => void): T {
fn(value);
return value;
}
tap(5, (n) => console.log(n.toFixed(2)));
Тип n выведен как number.
Async-функции
async function fetchData<T>(url: string): Promise<T> {
const res = await fetch(url);
return res.json() as Promise<T>;
}
const user = await fetchData<User>('/api/user');
Явное указание типа нужно, потому что res.json() возвращает any.
Обёртка с сохранением типа
type Result<T> = { data: T; error: null } | { data: null; error: string };
function ok<T>(data: T): Result<T> {
return { data, error: null };
}
function fail<T>(error: string): Result<T> {
return { data: null, error };
}
Дефолтное значение
type ApiResponse<T = unknown> = {
data: T;
status: number;
};
const res: ApiResponse = { data: 'any', status: 200 };
// data: unknown
Возврат кортежа
function toArray<T>(value: T): [T] {
return [value];
}
const arr = toArray(5); // [5]
Практика: useToggle
function useToggle(initial: boolean): [boolean, () => void] {
const [value, setValue] = useState(initial);
const toggle = () => setValue((v) => !v);
return [value, toggle];
}
Здесь дженерик не нужен — тип фиксированный.
Дженерик + ограничение
function logLength<T extends { length: number }>(value: T): T {
console.log(value.length);
return value;
}
logLength('hello');
logLength([1, 2, 3]);
logLength(42); // ошибка
Итоги
<T>перед аргументами- TypeScript выводит тип
- Несколько параметров через запятую
- Работает с async и callback
- Ограничения —
extends