cf.completefrontend
Open lab My progress
THE TYPESCRIPT FIELD GUIDE

Modules & type imports

Export types from one file and import them in another, see why import type exists, what verbatimModuleSyntax checks, and how a module differs from a script.

By the end, you can
  • 01
    Share types between filesExport a type alias or an interface from one file and import it in another, and read the errors when an export is missing.
  • 02
    Mark imports that are only typesUse import type and import { type … }, and say what each one leaves in the JavaScript the browser runs.
  • 03
    Use verbatimModuleSyntax and modulesExplain why build tools need types marked, fix the errors verbatimModuleSyntax reports, and turn a script into a module.

Types that travel between files

A shop app isn't one long file. One file describes a product, another shows the cart, another handles checkout. In JavaScript, files share values with export and import (the import and export lesson covers how). In TypeScript, files share types the same way. Here is a file that describes a product:

product.ts: two types and a functionPop out in the code editor (opens in a new tab)TypeScript
export type Product = { name: string; price: number }; export interface CartItem {  product: Product;  quantity: number;} export function formatPrice(price: number) {  return "$" + price.toFixed(2);}

Line 1 exports a type alias called Product: a name and a price. Lines 3 to 6 export an interface called CartItem: a product and how many of it. Lines 8 to 10 export a function, formatPrice, that turns a price like 3 into the text $3.00. The word export works the same in front of all three. Another file can now use them:

cart.ts imports a type and a functionPop out in the code editor (opens in a new tab)TypeScript
import { Product, formatPrice } from "./product"; const tea: Product = { name: "Tea", price: 3 };console.log(tea.name, formatPrice(tea.price));

Line 1 imports Product and formatPrice from "./product", which means the file product.ts in the same folder. You leave out the .ts, as you would in a project built with a tool like Vite. Line 3 uses Product as the type of tea, so TypeScript checks that the tea has a name and a price. Line 4 calls formatPrice and prints Tea $3.00. Point at Product on line 1: TypeScript shows the type it brought in from product.ts. Press Edit & run, and cart.ts runs with product.ts beside it.

A file product.ts exports the type Product, the interface CartItem, and the function formatPrice. An arrow leads to a file cart.ts, which imports Product and formatPrice from ./product.product.tsexport type Productexport interface CartItemexport function formatPriceexports types and a valuecart.tsimport {Product,formatPrice} from "./product"imports what it needs
product.ts exports two types and a function. cart.ts imports the Product type and the formatPrice function with one import, the same way for both.

One import brought in two very different things. formatPrice is a value: real code that the browser loads from product.js and runs. Product is only a type. Types are removed before the browser runs anything (the How TypeScript works lesson shows how), so product.js has no Product in it at all. This lesson is about what that means for your imports.

Real-life analogyA catalog page and a delivery truck

You order a sofa. First the shop sends you its catalog page: the size and the color. You use the page to plan where the sofa goes. On delivery day, the truck brings the sofa itself. Nobody puts the catalog page on the truck; you only needed it for planning. And if you only want the page, you tick "catalog page only", and no truck comes.

In real life: The shop sends you the catalog page for a sofa
In TypeScript: product.ts exports the Product type
In real life: You use the page to plan your room
In TypeScript: TypeScript uses the type to check cart.ts
In real life: The truck brings the sofa, never the page
In TypeScript: The browser gets values like formatPrice, never types
In real life: You tick "catalog page only" on the order form
In TypeScript: You write import type, so nothing is loaded for it
The main idea

A file with import or export is a module, and modules share types just as they share values. Types are only for checking, so they're removed from the JavaScript. import type marks an import that brings only types, so every tool can remove it safely.

Exporting and importing types

To share a type, put export in front of it, as product.ts does on lines 1 and 3. To use it, import it by name. Here is a checkout file that uses the CartItem interface:

checkout.ts uses the CartItem interfacePop out in the code editor (opens in a new tab)TypeScript
import { CartItem, formatPrice } from "./product"; const item: CartItem = {  product: { name: "Cake", price: 4 },  quantity: 2,};const total = item.product.price * item.quantity;//    ^?console.log(formatPrice(total));

Line 1 imports the CartItem interface and the formatPrice function. Lines 3 to 6 make an item that must match CartItem: a cake at 4, twice. Line 7 multiplies the price by the quantity, and the query on line 8 shows const total: number. Line 9 prints $8.00. Inside checkout.ts, an imported type works exactly like a type written in the same file.

Two things follow. A type without export stays private to its file. And when a type changes, every file that imports it is checked against the new version. Try both: each button changes line 1 of product.ts, and TypeScript checks cart.ts against it.

Playground: change what product.ts exports
product.tsTypeScript
export type Product = { name: string; price: number }; export interface CartItem {  product: Product;  quantity: number;} export function formatPrice(price: number) {  return "$" + price.toFixed(2);}
cart.ts, checked against itPop out in the code editor (opens in a new tab)TypeScript
import { Product, formatPrice } from "./product"; const tea: Product = { name: "Tea", price: 3 };console.log(tea.name, formatPrice(tea.price));
Line 1 of product.tsexport type
What happens in cart.ts
TypeScriptNo errors
When it runsprints Tea $3.00
Try it yourself

Line 1 exports the Product type, so cart.ts can import it. Its tea has a name and a price, so TypeScript has nothing to report.

Each button changes only line 1 of product.ts. The real TypeScript compiler checks both files together. Reset goes back to export type.

No export keeps Product inside product.ts. cart.ts gets Module '"./product"' declares 'Product' locally, but it is not exported, which means "product.ts has a Product, but keeps it to itself". export interface works just like export type: the importing file doesn't care which one it gets. Remove price changes only product.ts, yet TypeScript marks lines 3 and 4 of cart.ts. In every state the code still prints Tea $3.00, because types don't change what runs.

Every export is a type, a value, or both, and that decides what's left of it in the JavaScript. Read each row as: what a file exports, which kind of thing it is, and what the browser gets.

Types, values, and what's left of them
What the file exportsA type or a value?What's left in the JavaScript
export type Product = { … }A type.Nothing. The whole line is removed.
export interface CartItem { … }A type.Nothing. The whole interface is removed.
export function formatPrice(…)A value: a function you can call.The function, without its type annotations.
export class ShoppingCart { … }Both: a type you can write after a colon, and a value you can call with new.The class, without its type annotations.

The last row needs an example. A class makes both a type and a value with one name:

shopping-cart.ts: a class is a type and a valuePop out in the code editor (opens in a new tab)TypeScript
export class ShoppingCart {  items: string[] = [];  add(name: string) {    this.items.push(name);  }}

Line 1 exports a class, ShoppingCart. Another file can write cart: ShoppingCart to use it as a type, and new ShoppingCart() to make a real cart when the code runs (the Classes in TypeScript lesson covers classes). Lines 2 to 5 give each cart a list of items and an add method. Exercise 6 imports it.

import type: an import that disappears

When TypeScript removes the types from cart.ts, what happens to line 1? Here is what the browser gets:

cart.js: what the browser gets from cart.tsPop out in the code editor (opens in a new tab)JavaScript
import { formatPrice } from "./product";

const tea = { name: "Tea", price: 3 };
console.log(tea.name, formatPrice(tea.price));

Line 1 has lost Product. TypeScript saw that Product is only used as a type, in line 3's : Product, so it dropped the name from the import. That's exactly right: product.js has no Product to give. formatPrice stays, because line 4 calls it. Line 3 has lost its : Product too, and the code still prints Tea $3.00.

You can also say it yourself. import type is an import that brings only types:

cart.ts with a type-only importPop out in the code editor (opens in a new tab)TypeScript
import type { Product } from "./product";import { formatPrice } from "./product"; const tea: Product = { name: "Tea", price: 3 };console.log(tea.name, formatPrice(tea.price));

Line 1 imports Product with import type. Line 2 imports formatPrice with a plain import, because it's a value. Checking doesn't change: line 4 must still be a Product. When the types are removed, line 1 goes away completely, and the code prints Tea $3.00.

Left, cart.ts: import type Product, import formatPrice, and const tea: Product. An arrow labelled types removed leads to cart.js: the first line is gone, import formatPrice stays, and const tea has no type.cart.tsimport type { Product }import { formatPrice }const tea: Productwhat you writetypesremovedcart.js(line removed)import { formatPrice }const teawhat the browser runs
When the types are removed, the import type line goes with them. The formatPrice import stays, because it brings a value, and : Product is removed from the tea.

Why write type if TypeScript drops type imports anyway? Two reasons. Anyone reading line 1 knows at once that it loads nothing when the code runs. And some build tools can't work it out the way TypeScript did, so they need the mark; the next section shows them. The opposite mistake gets an error. Here formatPrice is imported with import type, on purpose:

A function imported as a type (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
import type { Product, formatPrice } from "./product"; const tea: Product = { name: "Tea", price: 3 };console.log(tea.name, formatPrice(tea.price));

TypeScript marks line 4: 'formatPrice' cannot be used as a value because it was imported using 'import type'. In plain words: "you said this import brings only types, but you're calling it like a function". Run it anyway, and the whole of line 1 is gone, so it stops with ReferenceError: formatPrice is not defined.

There's a shorter way to mix the two: put type in front of one name inside the braces, import { type Product, formatPrice } from "./product";. Try every form yourself. Type line 1 of cart.ts and watch the list under the code:

Playground: write the import line
import { Product, formatPrice } from "./product"; const tea: Product = { name: "Tea", price: 3 };console.log(tea.name, formatPrice(tea.price));
Line 1 in the browser's copyimport { formatPrice } from "./product";
What happens
TypeScriptNo errors
When it runsprints Tea $3.00
Try it yourself

Line 1 brings the Product type and the formatPrice function. No errors. The browser's copy keeps only formatPrice, because Product is a type.

The code is checked by the real TypeScript compiler, together with product.ts, each time you type. Only line 1 changes. Reset puts the plain import back.

With type after import, line 4 can't call formatPrice. With type in front of Product, there are no errors, and the browser's line 1 is import { formatPrice } from "./product";. Without Product in the braces, line 3 gets Cannot find name 'Product', and a misspelled path gets Cannot find module './products' or its corresponding type declarations.

The table below sums up the three forms. Each line ends in from "./product";, left out to keep the table short. Read each row as: the import line, what it brings, and what the JavaScript keeps.

Three ways to import a type and a value
The import lineWhat it bringsWhat the JavaScript keeps
import { Product, formatPrice }A type and a value.import { formatPrice }, because TypeScript works out that Product is a type and drops it.
import type { Product }Only types.Nothing. The whole line is removed, and the file isn't loaded for it.
import { type Product, formatPrice }A type, marked with type, and a value.import { formatPrice }, because the marked name is removed.

verbatimModuleSyntax: what you write is what you get

The TypeScript compiler, tsc, reads every file in your project, so it knows that Product is a type. Many build tools work differently. Tools like Vite, esbuild, and SWC turn each .ts file into JavaScript on its own, one file at a time and without checking types, because that's fast (the Bundlers lesson explains what they do). A tool that sees one file can't always tell a type from a value. Here is a file where that goes wrong:

shop.ts passes on two types and a functionPop out in the code editor (opens in a new tab)TypeScript
// shop.ts passes on what product.ts exports.export { Product, CartItem, formatPrice } from "./product";

Line 2 passes on three names from product.ts, so other files can import them all from shop.ts. This is called a re-export. TypeScript reports no errors: tsc read product.ts and knows to drop the two types. A tool that sees only this file can't know which names are types, so it keeps line 2 exactly as it is. Press Edit & run: this page removes types one file at a time too, and the browser stops with a SyntaxError saying that the module doesn't provide an export named Product.

A file shop.ts holds export Product from ./product. An arrow leads to a build tool that sees one file and asks: is Product a type or a value? It keeps the line. An arrow leads to a browser, which finds no export named Product.shop.tsexport {Product} from …passes Product onbuild toolsees one file:type or value?browserlooks forProductin product.jsno such export
The build tool sees only shop.ts, so it can't tell that Product is a type, and it keeps the line. The browser then looks for a Product export that product.js doesn't have.

Here is why. This is product.ts after its types are removed. Only the function is left:

product.js: only the function is leftJavaScript
export function formatPrice(price) {
  return "$" + price.toFixed(2);
}

Lines 1 to 3 are the formatPrice function, without : number. There's no Product and no CartItem, so nothing can import them from it when the code runs.

The fix is a compiler option, verbatimModuleSyntax, which you turn on in tsconfig.json (the Setting up a project lesson covers that file). "Verbatim" means "word for word". With it on, the rule is simple: an import or export without type stays in the JavaScript exactly as you wrote it, and one with type is removed. A type must never reach the browser, so TypeScript now makes you mark every type. Here is shop.ts again with the option on:

shop.ts with verbatimModuleSyntax on (an error on purpose)TypeScript
// shop.ts passes on what product.ts exports.export { Product, CartItem, formatPrice } from "./product";

The list under the code shows the option this example sets. TypeScript marks line 2 twice, once for each type, on purpose: Re-exporting a type when 'verbatimModuleSyntax' is enabled requires using 'export type'. In plain words: "this passes on a type, so write export type".

shop.ts with its types markedPop out in the code editor (opens in a new tab)TypeScript
// shop.ts passes on what product.ts exports.export type { Product, CartItem } from "./product";export { formatPrice } from "./product";

Line 2 passes on the two types with export type, and line 3 passes on formatPrice. There are no errors, and any tool can now tell what to remove: line 2 goes, line 3 stays. Now try the option on an import. Pick a way to write line 1 of cart.ts, then turn verbatimModuleSyntax on and off:

Playground: turn verbatimModuleSyntax on and off
import { Product, formatPrice } from "./product"; const tea: Product = { name: "Tea", price: 3 };console.log(tea.name, formatPrice(tea.price));
Line 1 as tsc writes itimport { formatPrice } from "./product";
What happens
verbatimModuleSyntaxoff
TypeScriptNo errors
Try it yourself

With the option off, TypeScript works out that Product is a type and drops it, so tsc writes import { formatPrice } from "./product";. No errors.

The real TypeScript compiler checks cart.ts with product.ts, and the right side shows what tsc writes for line 1. The last button turns the option on and off. Reset goes back to the plain import, with the option off.

With the option off, the plain import is fine, because tsc drops Product for you. With it on, tsc keeps the line word for word, and TypeScript reports 'Product' is a type and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled: mark it with type. import { type Product, formatPrice } is fine either way, so it's the habit worth keeping. A new Vite project already turns verbatimModuleSyntax on in its tsconfig. An older option, isolatedModules, reports the same re-export error (the target, lib & module lesson covers it).

Modules and scripts

TypeScript, like JavaScript, has two kinds of files. A module has at least one import or export at the top level. A script has none. The difference is where the names a file declares at the top live (the Scope lesson explains scope). In a module, they stay inside the file. In a script, they go into the global scope, which every script on the page shares.

This site checks every example as a module unless it says otherwise, the way a new Vite project does with moduleDetection: "force". The next examples set moduleDetection: "auto", TypeScript's own default, so a file with no import or export is a script:

A script that declares name (an error on purpose)Pop out in the code editor (opens in a new tab)TypeScript
const name = "Asha";console.log("Hello, " + name);

Lines 1 and 2 have no import or export, so this is a script, and name would be global. But every browser page already has a global name: the browser window's own name, also called window.name. TypeScript knows it from the browser's types and marks line 1 on purpose: Cannot redeclare block-scoped variable 'name' means "this scope already has a name, and const can't make a second one". The code still prints Hello, Asha when it runs, but the error is a sign the file isn't what you meant.

The same file, made a module with export {}Pop out in the code editor (opens in a new tab)TypeScript
const name = "Asha";console.log("Hello, " + name); export {};

Line 4, export {};, exports nothing. But one export is enough to make the file a module, so name now belongs to this file alone, and the error is gone. It prints Hello, Asha.

Two scripts clash with each other in the same way. Here is a checkout script on its own:

checkout.ts, a scriptTypeScript
const total = 7;

Line 1 declares total, and on its own the file is fine. Now a cart script in the same project:

cart.ts, a script beside checkout.ts (an error on purpose)TypeScript
const total = 3;console.log(total);

Line 1 declares a total too. Both files are scripts, so both totals land in the same global scope, and TypeScript marks line 1: Cannot redeclare block-scoped variable 'total'. Add export {}; to either file and that file gets its own total.

Left, two scripts: cart.ts and checkout.ts each declare total, and both totals land in one shared global crate, a clash. Right, two modules: each file is its own crate with its own total.Two scriptscart.tscheckout.tstotaltotalglobalsame name twiceTwo modulestotalcart.tstotalcheckout.tseach file has its own
Two scripts put total in the same shared place, so the names clash. Two modules each keep their own total, and nothing clashes.

The table below compares the two kinds of file. Read each row as a question, then the answer for a module and for a script.

Modules and scripts
QuestionA moduleA script
What makes a file one?It has at least one import or export at the top level.It has no import or export at all.
Where do its top-level names live?Inside the file. Other files see only what it exports.In one global scope that every script on the page shares.
How does the browser load it?With <script type="module">, or through a bundler like Vite.With a plain <script> tag.
How do you make it the other kind?Remove every import and export. You rarely want to.Add export {};, which exports nothing.

One types file for a shop app

Real projects often keep the types that many files share in one file of their own, such as types.ts:

types.ts: the shop's shared typesTypeScript
export type Product = { id: number; name: string; price: number }; export interface CartItem {  product: Product;  quantity: number;} export type Order = { items: CartItem[]; paid: boolean };

Line 1 exports Product, now with an id. Lines 3 to 6 export CartItem, and line 8 exports Order: a list of cart items and whether it's paid. Every line is a type, so nothing in this file runs. tsc writes just export {}; for it: a module that exports nothing. Here is a file that uses it, in a project with verbatimModuleSyntax on:

order.ts imports only typesPop out in the code editor (opens in a new tab)TypeScript
import type { CartItem, Order } from "./types"; function orderTotal(order: Order) {  let total = 0;  for (const item of order.items) total += item.product.price * item.quantity;  return total;} const items: CartItem[] = [  { product: { id: 1, name: "Tea", price: 3 }, quantity: 2 },  { product: { id: 2, name: "Cake", price: 4 }, quantity: 1 },];console.log(orderTotal({ items, paid: false }));

Line 1 brings in CartItem and Order with import type, as the option requires. Lines 3 to 7 add up an order: each item's price times its quantity. Lines 9 to 12 hold two teas at 3 and one cake at 4, and line 13 prints 10. Because order.ts imports only types from types.ts, the browser never loads types.js at all. Now sort some import lines the way TypeScript would:

Error or fine?
  • import type { Product } from "./product";
  • import { Product } from "./product";
  • import { type Product, formatPrice } from "./product";
  • import type { formatPrice } from "./product"; formatPrice(3);
  • import { formatPrice } from "./product"; formatPrice(3);
  • import { CartItem } from "./product";
  • export { Product } from "./product";
  • export type { Product } from "./product";
Try it yourself
0 of 8 correct

verbatimModuleSyntax is on, and each line sits in a file beside product.ts from the overview. Sort each line by what TypeScript says about it. Each line is checked on its own.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Common mix-ups

  • "import type loads the file, then skips the types." No. The whole line is removed, so nothing is loaded for it when the code runs.
  • "A type is exported in the JavaScript, like a function." No. Types are removed, so product.js exports only formatPrice. That's why a re-exported type can break in the browser.
  • "Every import needs the word type." No. Only names that are types need it. A function, a constant, or a class you call with new needs a plain import, or the code can't use it.
  • "No error from tsc means every build tool will make working JavaScript." No. tsc sees every file; a tool that sees one file at a time may keep a type it can't recognize. verbatimModuleSyntax makes you mark every type, so every tool gets it right.
  • "verbatimModuleSyntax changes how my types are checked." No. It changes which import lines stay in the JavaScript, and asks you to mark types so that it stays safe.
  • "Every .ts file is a module." No. By default, a file needs a top-level import or export. Without one it's a script, and its names are global, unless your tsconfig sets moduleDetection: "force".

Practice exercises

Most exercises are files beside product.ts from the overview, and exercise 6 sits beside shopping-cart.ts. Press Edit & run on the starter code: TypeScript checks it with those files as you type, and it runs with them. Try a guess first, then use the hints.

Exercise 1 · Warm-upFind the line TypeScript marks

This cart.ts imports a type and a function. Which line will TypeScript mark?

Starter codePop out in the code editor (opens in a new tab)TypeScript
import type { CartItem, formatPrice } from "./product";

const item: CartItem = { product: { name: "Tea", price: 3 }, quantity: 2 };
console.log(formatPrice(item.product.price * item.quantity));

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · Warm-upPredict the browser's import line

    When the types are removed from this file, what does line 1 become? Write the whole line, or just what's left inside the braces.

    Starter codePop out in the code editor (opens in a new tab)TypeScript
    import { CartItem, formatPrice } from "./product"; const item: CartItem = { product: { name: "Cake", price: 4 }, quantity: 3 };console.log(formatPrice(item.product.price * item.quantity));

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeFix the imports for verbatimModuleSyntax

      This project turns verbatimModuleSyntax on, and line 1 has two errors. Fix line 1. What does the code print?

      Starter codePop out in the code editor (opens in a new tab)TypeScript
      import { CartItem, Product, formatPrice } from "./product"; const tea: Product = { name: "Tea", price: 3 };const item: CartItem = { product: tea, quantity: 2 };console.log(`${tea.name} x${item.quantity}: ${formatPrice(tea.price * item.quantity)}`);

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeTurn a script into a module

        This file uses TypeScript's default moduleDetection, and lines 1 and 2 both get Cannot redeclare block-scoped variable. Add one line to fix both. Which line?

        Starter codePop out in the code editor (opens in a new tab)TypeScript
        const name = "Asha";const status = "signed in";console.log(`${name} is ${status}`);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeFix a re-export that breaks in the browser

          shop.ts passes on what product.ts exports, and adds a shop name. With verbatimModuleSyntax on, line 1 has two errors. Fix it. Then: which names does the JavaScript for shop.ts still export?

          Starter codePop out in the code editor (opens in a new tab)TypeScript
          export { CartItem, Product, formatPrice } from "./product";export const shopName = "Corner Shop";

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeImport a class you also use as a value

            This file imports the ShoppingCart class from shopping-cart.ts with import type, and line 3 gets an error. Fix line 1. What does the fixed code print?

            Starter codePop out in the code editor (opens in a new tab)TypeScript
            import type { ShoppingCart } from "./shopping-cart"; const cart: ShoppingCart = new ShoppingCart();cart.add("Tea");console.log(cart.items.length);

            Answer, then press Check. Spacing and letter case don’t matter.

              Check your understanding

              For each question, ask two things: is this name a type or a value, and what is left of the line once the types are removed? The quiz shows its code without the checker, so the error list doesn't give the answers away.

              The modules and type imports quiz · 7 questionsScore: first tries count
              1. Question 1 of 7Which import line is removed completely from the JavaScript?

                Choose an answer to see the explanation.

              2. Question 2 of 7What does TypeScript say about line 4 of this cart.ts?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                import type { Product, formatPrice } from "./product";
                
                const cake: Product = { name: "Cake", price: 4 };
                console.log(formatPrice(cake.price));

                Choose an answer to see the explanation.

              3. Question 3 of 7With verbatimModuleSyntax on, which line of this file gets an error?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                import type { Product } from "./product";
                import { CartItem } from "./product";
                import { formatPrice } from "./product";
                
                const tea: Product = { name: "Tea", price: 3 };
                const item: CartItem = { product: tea, quantity: 1 };
                console.log(formatPrice(item.product.price));

                Choose an answer to see the explanation.

              4. Question 4 of 7With TypeScript's default settings, is this file a module or a script?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                const greeting = "Welcome back";
                console.log(greeting);

                Choose an answer to see the explanation.

              5. Question 5 of 7What does adding export {}; to the end of a file do?

                Choose an answer to see the explanation.

              6. Question 6 of 7This types.ts holds only types. What does the browser get from it?

                Read the code, then predictPop out in the code editor (opens in a new tab)TypeScript
                export type Product = { name: string; price: number };
                export interface CartItem {
                  product: Product;
                  quantity: number;
                }

                Choose an answer to see the explanation.

              7. Question 7 of 7Why can export { Product } from "./product"; break in a Vite build when tsc reports no error?

                Choose an answer to see the explanation.

              Key takeaways

              • A file with a top-level import or export is a module. Its names stay inside it unless it exports them.
              • Export a type alias or an interface with export, and import it by name, just like a value.
              • Types are removed from the JavaScript, so a type name can't be loaded from another file when the code runs.
              • import type brings only types and is removed whole. import { type X, y } marks one name.
              • Tools that see one file at a time can't tell a type from a value. verbatimModuleSyntax makes you mark every type, so the JavaScript is exactly what you wrote.
              • A file with no import or export is a script, and its names are global. export {}; makes it a module.

              Remember the one-liner.
              Types travel between modules for checking only, so mark them with type, and only values reach the browser.

              Coming next: Declaration files (.d.ts). It shows how TypeScript knows the types of JavaScript libraries that have no types of their own.

              CompleteFrontend Clear concepts. Working examples.