Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як виправити чи доповнити типи сторонньої бібліотеки, яку ви не контролюєте?

Типи бібліотек бувають неповними, застарілими чи надто загальними (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 чи в саму бібліотеку прибирає потребу в латках для всіх.

Докладніше в документації: Доповнення модулів

Схожі питання