← Back to TypeScript Course | Chapter 28: Real World Projects | Lesson 13 of 14

TypeScript Best Practices Review

A best-practices review checks compiler settings, type design, project structure, error handling, testing, and maintainability. The goal is useful types rather than types for their own sake.

Core Concept

A best-practices review of a TypeScript codebase typically checks for any usage (each one is a gap in type safety), whether strict mode is enabled, and whether types are colocated sensibly rather than duplicated across files.

Example: Core Concept

typescript
// Checklist: grep for ": any", check strict mode, check for duplicated types.
function search(term: string): any { return term; } // flagged in a review
console.log(search("x"));

Basic Setup

A basic review process runs tsc --noEmit with strict: true temporarily enabled (even if the project doesn't use it day-to-day) to surface how many latent type issues exist beneath the current configuration.

Example: Basic Setup

typescript
// tsc --noEmit --strict   (run temporarily even if not the project default)
console.log("Reveals latent type issues hidden beneath the current config");

Typed Example

A typed example of a common finding: a function typed to return SomeType | null where every actual call site immediately does result!.property (a non-null assertion) usually signals the type should just be narrowed properly instead of asserted away.

Example: Typed Example

typescript
interface Result { value: string; }
function find(id: number): Result | null {
  return id === 1 ? { value: "found" } : null;
}
const result = find(2);
// result!.value is a red flag -- prefer narrowing instead:
if (result) console.log(result.value);

Project Usage

In a real project, a periodic review also checks for overly broad types (object, Function, any[]) that technically compile but provide little real safety, replacing them with specific interfaces or generics.

Example: Project Usage

typescript
// Flag overly broad types found during review:
function process(data: object) { // too broad
  console.log(data);
}
interface Payload { id: number; } // replace with something specific
process({ id: 1 } satisfies Payload);

Best Practices

Track a metric like "count of any and @ts-ignore occurrences" over time in CI, since a rising trend usually means type debt is accumulating faster than it's being paid down.

Example: Best Practices

typescript
// CI metric: count of ": any" and "@ts-ignore" occurrences over time
let anyCount = 0;
let tsIgnoreCount = 0;
console.log("Track these counts in CI to catch rising type debt");

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.