Search code examples
typescriptwebpackwebpack-4

Cannot re-export a type when using the --isolatedModules with TS 3.2.2


I probably need to rethink the way we structure our React components. We are using the latest react-scripts that allow Typescript to be used and by default, the isolatedModules is being enabled which currently bugs me a bit.

We used to structure a component like this:

Component
|_ Component.tsx
|_ index.ts
|_ types.ts
  • Component.tsx holds the actual component without declarations
  • index.ts is just re-exporting everything so we can have a singular entry point and can do something like import Component, { ComponentType } from '@/Component';

  • types.ts holds the actual type definitions and exports most or all of them.

So far so good and that works without the isolatedModules. However, we also export some of the type definitions, effectively re-exporting the interfaces that were specified within Component/types.ts. This won't work as TypeScript itself would not transpile the code any longer.

How can I re-export this without having a separate import statement going to @/Component/types (which might be actual the simpler way anyway)?


Solution

  • TS 3.8+

    You can use type-only imports and exports with --isolatedModules:

    // types.ts
    export type MyType = { a: string; b: number; };
    
    // main.ts 
    
    // named import/export
    import type { MyType } from './types'
    export type { MyType }
    
    // re-export
    export type { MyType } from './types'
    
    // namespace import
    import type * as MyTypes from "./types";
    export type RenamedType = MyTypes.MyType;
    export { MyTypes };
    
    //     ^ Note the "type" keyword in statements above
    

    Example Playground; Take a look at the PR for possible extension forms and proposals.


    TS 3.7 or older

    In previous versions, the following is not possible:

    import { MyType } from './types'; 
    export { MyType }; // error: Cannot re-export a type with --isolatedModules
    
    export { MyType } from "./types"; // error, like above
    

    Type re-exports have to use a workaround:

    import { MyType as MyType_ } from "./types";
    export type MyType = MyType_;
    
    // or
    export * from "./types"