As seen in this answer, Typescript 3.8 introduced:
import type
to safely import definitions (source):
import type only imports declarations to be used for type annotations and declarations. It always gets fully erased, so there’s no remnant of it at runtime. Similarly, export type only provides an export that can be used for type contexts, and is also erased from TypeScript’s output.
However, you still need to include the package as a dependency.
This can lead to circular dependencies as seen in my case. A simplified description of my monorepo is:
client-web: a web client powered byvite(client)client-store: a redux store package (model)image-gallery: an image gallery package (presentation)
They all need to be aware of the following type:
type IImage = {
id: string;
title: string;
url: string;
urlThumb: string;
}
However, it is not clear to me where this type should "live". There seems to be a few options:
- put it in the presentation =>
image-galleryand import it to the other packages - put it in the model =>
client-storeand import it to the other packages - create a shared
common-typespackage (manually) - create an auto-generated shared
common-typespackage (composition)
No matter which path you choose you may encounter the downsides of complicating your dependency graph and thus making your build sequential rather then parallel. Furthermore, not all types are made equal, sometimes you want your types close to a component, other times you want your types grouped by semantic context.
I wonder whether there is a way out I haven't thought of?