I've just been tasked with converting a fairly large project from Javascript to Typescript. One of the difficulties is that one of the 3rd-party modules we are using is also in Javascript, but ideally we'd like to add the types for that as well. This 3rd-party module is used extensively throughout the codebase, so we'd like to add the types progressively.
So, let's say we have two components like this:
// -----| FirstComponentConsumer.tsx |-------------------------
import { FirstComponent } from 'third-party';
export const FirstComponentConsumer = () => {
return (
<FirstComponent name="pants" />
);
};
// -----| SecondComponentConsumer.tsx |------------------------
import { SecondComponent } from 'third-party';
export const SecondComponentConsumer = () => {
return (
<SecondComponent type="text" />
);
};
Now, I'd like to add the types for FirstComponent but not SecondComponent YET - I'll add these later (in reality there are hundreds of exports that will need to be typed). So I can create my types file, something like:
// types.d.ts
import type { ReactNode } from 'react';
declare module 'third-party' {
export type FirstComponentProps = {
name?: string;
}
export const FirstComponent = (props: FirstComponentProps) => ReactNode;
}
This works as expected - FirstComponent is now typed! But, it breaks SecondComponentConsumer because I haven't said that the third-party module exports a SecondComponent:
Module '"third-party"' has no exported member 'SecondComponent'. TS2305
Of course this makes perfect sense, but can I turn off this checking for "undeclared types"? Or is that trying to have my cake and eat it too?
Something like this might do the trick, basically you are just exporting everything as any, but specifically typing a single component. I haven't tested this, but I think it should work.
declare module "third-party" {
const FirstComponent: (name?: string) => ReactNode;
type Exports = {
FirstComponent: typeof FirstComponent;
} & {
[key: PropertyKey]: any;
}
const exports: Exports;
export default exports;
export { FirstComponent };
}