There is an export import syntax for legacy modules, and a standard export format for modern ES6 modules:
// export the default export of a legacy (`export =`) module
export import MessageBase = require('./message-base');
// export the default export of a modern (`export default`) module
export { default as MessageBase } from './message-base';
// when '--isolatedModules' flag is provided it requires using 'export type'.
export type { default as MessageBase } from './message-base';
// export an interface from a legacy module
import Types = require('./message-types');
export type IMessage = Types.IMessage;
// export an interface from a modern module
export { IMessage } from './message-types';
Answer from C Snover on Stack OverflowThere is an export import syntax for legacy modules, and a standard export format for modern ES6 modules:
// export the default export of a legacy (`export =`) module
export import MessageBase = require('./message-base');
// export the default export of a modern (`export default`) module
export { default as MessageBase } from './message-base';
// when '--isolatedModules' flag is provided it requires using 'export type'.
export type { default as MessageBase } from './message-base';
// export an interface from a legacy module
import Types = require('./message-types');
export type IMessage = Types.IMessage;
// export an interface from a modern module
export { IMessage } from './message-types';
Some more examples besides #c-snover's answer from here. You can put them together.
import 'jquery'; // import a module without any import bindings
import $ from 'jquery'; // import the default export of a module
import { $ } from 'jquery'; // import a named export of a module
import { $ as jQuery } from 'jquery'; // import a named export to a different name
import * as crypto from 'crypto'; // import an entire module instance object
export var x = 42; // export a named variable
export function foo() {}; // export a named function
export default 42; // export the default export
export default function foo() {}; // export the default export as a function
export { encrypt }; // export an existing variable
export { decrypt as dec }; // export a variable as a new name
export { encrypt as en } from 'crypto'; // export an export from another module
export * from 'crypto'; // export all exports from another module
// (except the default export)
To export or not to export types (implicit vs explicit)
`export type * from 'somewhere'`
How to export/import a only a type definition in TypeScript - Stack Overflow
Import and export TS types and interfaces in Next.js app don't needed anymore?
Videos
Hello,
I've been putting types that can be used all over my app on types.ts files. The interfaces and types in these files don't get exported and this way VSCode / Typescript somehow knows that they exist globally. This avoids having to import them whenever they are used as normally I already have quite a few other imports for actual code. That's the main reason I've been using to not having to explicitly export/import those types.
However recently I came up with two other thoughts:
-
When creating a library, it seems the way to go is to export types. This way you can select which types are exposed (or not) and you avoid "namespacing". To avoid name conflicts when not explicitly exporting types, I normally use something like
PossiblyLongNamePropsorPossiblyLongNameState. These names can get long and repetitive (thePossiblyLongNamepart). -
These long names for "namespacing" got me thinking that I should probably be exporting types, at least in some cases. So it's sort of a conflict between "I don't want to be using long names for my interfaces/types" vs "I don't want to explicitly import every single type I use".
Does that make sense? What do you think? What's your approach to this?
Thank you!
Typescript 3.8 and later has type only exports and imports:
https://devblogs.microsoft.com/typescript/announcing-typescript-3-8/#type-only-imports-exports
import type { SomeThing } from "./some-module.js";
export type { SomeThing };
You just import it normally and the compiler works out that you don't need the import statement emitted because no concrete code is used.
Here's an example:
component.ts
export interface MyInterface {
name: string;
}
app.ts
import { MyInterface } from './component';
class MyClass implements MyInterface {
constructor(public name: string) { }
}
The app.js file is simply (ES2015 version):
class MyClass {
constructor(name) {
this.name = name;
}
}
Or in older ES5 terms:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var MyClass = /** @class */ (function () {
function MyClass(name) {
this.name = name;
}
return MyClass;
}());
The important thing here is that the TypeScript compiler has worked out that the import is only needed at compile time, not runtime.