Типи бібліотек бувають неповними, застарілими чи надто загальними (any). Є кілька способів це виправити - від найбезпечнішого до найризикованішого.
1. Обгортка з точними типами - найнадійніше:
import { get } from 'legacy-http'; // повертає Promise<any>
export async function fetchJson<T>(url: string, schema: z.ZodType<T>): Promise<T> {
return schema.parse(await get(url));
}
Решта коду працює з вашою функцією, а не з бібліотекою. any локалізовано в одному місці і перевірено під час виконання.
2. Доповнення модуля (module augmentation) - додати до існуючих типів те, що бібліотека дозволяє розширювати:
// types/vue-router.d.ts
import 'vue-router';
declare module 'vue-router' {
interface RouteMeta {
requiresAuth?: boolean;
title?: string;
}
}
Працює лише з інтерфейсами (їх можна «доповнювати» через злиття оголошень), а не з аліасами type. Багато бібліотек навмисно лишають такі «точки розширення»: RouteMeta у Vue Router, ComponentCustomProperties у Vue, Register у TanStack Router, теми в styled-components.
3. Глобальні доповнення:
declare global {
interface Window {
analytics?: { track(event: string, props?: Record<string, unknown>): void };
}
}
export {};
4. Оголошення для пакета без типів:
// types/untyped-lib.d.ts
declare module 'untyped-lib' {
export function format(value: number, options?: { currency?: string }): string;
}
Краще описати лише використану частину API, ніж declare module 'untyped-lib'; (усе стає any).
5. Латка пакета (patch-package, pnpm patch) - виправити .d.ts прямо в node_modules. Крайній засіб: латку треба підтримувати при кожному оновленні.
Що варто знати:
- файл з доповненням має бути модулем (мати
importчиexport), інакшеdeclare moduleстворить новий модуль замість доповнення існуючого; - файл має потрапити в компіляцію - через
includeуtsconfig; - з TypeScript 6
typesза замовчуванням порожній - глобальні типи з@types/*(наприклад,@types/node) треба перелічувати явно в"types": ["node"]; - внесок в оригінал: виправлення типів у DefinitelyTyped чи в саму бібліотеку прибирає потребу в латках для всіх.