Since Typescript 3.8 you can use the following syntax:
import type { ExternalFoo } from "foo";
So if you're just using that library for type information, you probably don't have to list it as a dependency
or optionalDependency
anymore. You might prefer to leave it as a peerDependency
so that if your users will have those dependencies, they'll be on versions compatible with your library. Naturally, adding as devDependency
is useful too.
The import will live on the generated d.ts
files only, but not on .js
transpiled code. One problem, though, is that if users don't have that library installed, that type becomes any
and this might mess up your own typing a bit. For example, if foo
is not installed your function becomes
customPackage = (source: any | ExternalBar) =>
// equivalent to customPackage = (source: any) =>
And for this particular type annotation, it sucks because even if I have bar
installed, it won't be used in that type checking. So there is a way to not depend on that library anymore, but it doesn't solve the hardship of writing type annotations that won't break down if that type is not there.
Edit: please take a look at this answer on how to deal with missing types.
Reference