A JavaScript dependency without types is an implicit any, and under noImplicitAny it is a compile error — so the choice is a declaration or a suppression.
// types/legacy-widget/index.d.ts
declare module 'legacy-widget' {
export interface Options {
container: HTMLElement;
onSelect?: (id: string) => void;
}
export function mount(options: Options): void;
}
// the escape hatch, when the shape is genuinely unknown:
// declare module 'legacy-widget'; // everything is any
Describing only the surface you actually call is the practical approach — a complete declaration for a large library is a project, and a partial one is useful immediately. The real hazard is that a declaration is unchecked against the library: a wrong signature moves the failure from the compiler to production, which is worse than no types. Checking DefinitelyTyped first takes thirty seconds and usually makes the whole question moot.