You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: book-content/chapters/14-configuring-typescript.md
+75-5Lines changed: 75 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -363,17 +363,83 @@ This is because the bundler will take care of resolving the file paths and exten
363
363
364
364
This means that if you're using an external bundler or transpiler, you should use `module: "Preserve"` in your `tsconfig.json` file. This is also true if you're using a frontend framework like Next.js, Remix, Vite, or SvelteKit - it will handle the bundling for you.
365
365
366
-
## `import type`
366
+
## Importing Types With `import type`
367
367
368
-
<!-- TODO -->
368
+
When you're importing types from other files, TypeScript has some choices to make. Let's say you're importing a type of `Album` from `album.ts`:
369
+
370
+
```typescript
371
+
// index.ts
372
+
373
+
import { Album } from"./album";
374
+
```
375
+
376
+
What should the emitted JavaScript look like? We're only importing a type, which disappears at runtime. Should the import remain, but with the type removed?
377
+
378
+
```javascript
379
+
// index.js
380
+
381
+
import {} from"./album";
382
+
```
383
+
384
+
Or should the import be removed entirely?
385
+
386
+
These decisions matter, because modules can contain effects which run when they're first imported. For instance, `album.ts` might call a `console.log` statement:
387
+
388
+
```typescript
389
+
// album.ts
390
+
391
+
exportinterfaceAlbum {
392
+
title:string;
393
+
artist:string;
394
+
year:number;
395
+
}
396
+
397
+
console.log("Imported album.ts");
398
+
```
399
+
400
+
Now, if TypeScript removes (or, as they say in the TypeScript docs, elides) the import, the `console.log` statement won't run. This can be surprising if you're not expecting it.
401
+
402
+
The way TypeScript resolves this is with the `import type` syntax. If you're importing a type and you don't want the import to be emitted in the JavaScript, you can use `import type`:
403
+
404
+
```typescript
405
+
// index.ts
406
+
407
+
importtype { Album } from"./album";
408
+
```
409
+
410
+
Now, only the type information is imported, and the import is removed from the emitted JavaScript:
411
+
412
+
```javascript
413
+
// index.js
414
+
415
+
// No import statement
416
+
```
369
417
370
418
### `import type { X }` vs `import { type X }`
371
419
372
-
<!-- TODO -->
420
+
You can combine `import` and `type` in two ways. You can either mark the entire line as a type import:
421
+
422
+
```typescript
423
+
importtype { Album } from"./album";
424
+
```
425
+
426
+
Or, if you want to combine runtime imports with type imports, you can mark the type itself as a type import:
427
+
428
+
```typescript
429
+
import { typeAlbum, createAlbum } from"./album";
430
+
```
431
+
432
+
In this case, `createAlbum` will be imported as a runtime import, and `Album` will be imported as a type import.
433
+
434
+
In both cases, it's clear what will be removed from the emitted JavaScript. The first line will remove the entire import, and the second line will remove only the type import.
373
435
374
436
### `verbatimModuleSyntax` Enforces `import type`
375
437
376
-
<!-- TODO -->
438
+
TypeScript has gone through various iterations of configuration options to support this behavior. `importsNotUsedAsValues` and `preserveValueImports` both tried to solve the problem. But since TypeScript 5.0, `verbatimModuleSyntax` is the recommended way to enforce `import type`.
439
+
440
+
The behavior described above, where imports are elided if they're only used for types, is what happens when `verbatimModuleSyntax` is set to `true`.
441
+
442
+
You might be wondering why it isn't part of the recommended set of options detailed above. The reason is that it also has some impact on how modules work in TypeScript - we'll talk about that in the next section.
377
443
378
444
## ESM and CommonJS
379
445
@@ -387,10 +453,14 @@ This means that if you're using an external bundler or transpiler, you should us
387
453
388
454
<!-- TODO -->
389
455
390
-
#### `import X = require('x')`
456
+
#### Importing and Exporting In CJS
457
+
458
+
`import X = require('x')`
391
459
392
460
<!-- TODO -->
393
461
462
+
#### When `verbatimModuleSyntax` Isn't Appropriate
463
+
394
464
## `noEmit`
395
465
396
466
The `noEmit` option in `tsconfig.json` tells TypeScript not to emit any JavaScript files when transpiling your TypeScript code.
0 commit comments