TypeScript

Lesson 10

Type-only imports and module boundaries

Separate type dependencies from runtime dependencies so modules stay lightweight.

Good Code

review-card.ts
import type { PullRequest } from "./pull-request";
import { formatAuthorName } from "./authors";

export function getReviewCardTitle(pullRequest: PullRequest) {
  // import type keeps PullRequest out of the runtime dependency graph.
  return pullRequest.title + " by " + formatAuthorName(pullRequest.authorId);
}

Bad Code

review-card.ts
import { PullRequest } from "./pull-request";
import { formatAuthorName } from "./authors";

export function getReviewCardTitle(pullRequest: PullRequest) {
  // A value import blurs type-only and runtime dependencies.
  return pullRequest.title + " by " + formatAuthorName(pullRequest.authorId);
}

Review Notes

What to review

Good Code

The good version makes it clear that PullRequest is only a type dependency while formatAuthorName is a runtime value dependency.

Bad Code

The bad version imports a type like a runtime value, which can blur module boundaries and create unnecessary runtime coupling depending on compiler settings.

Takeaways

  • Use `import type` when a module only needs a type and keep runtime imports for values that execute.