Lewati ke konten utama
menjadi.dev
Chapter 18.6 JavaScript Lanjutan

TypeScript di Proyek Nyata: Config, ESLint, dan Pattern

Setup TypeScript production-ready dan pattern yang digunakan di industri

Tujuan Pembelajaran

  • Bisa konfigurasi tsconfig.json
  • Mengerti strict mode dan compiler options
  • Menguasai pattern TypeScript di proyek besar

Analogi

Diagram

      tsconfig.json:
├── strict: true (type safety maksimal)
├── noImplicitAny (larang any implisit)
├── strictNullChecks (null/undefined terpisah)
└── paths (path alias untuk import)
    

tsconfig.json adalah blueprint TypeScript — konfigurasi yang tepat sangat penting

Penjelasan Konsep

Setelah menguasai syntax TypeScript, saatnya belajar setup proyek production-ready.

Konfigurasi yang benar akan membantumu menangkap lebih banyak bug dan meningkatkan developer experience.

tsconfig.json: Konfigurasi Utama

tsconfig.json adalah file konfigurasi TypeScript.

Ini contoh konfigurasi untuk proyek modern:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "lib": ["ES2022", "DOM",

"DOM.Iterable"],
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}

Compiler Options Penting

strict: true

Mengaktifkan SEMUA strict type checking.

Ini SETTING PALING PENTING.

Dengan strict mode, TypeScript akan:

  • noImplicitAny: Melarang any implisit
  • strictNullChecks: Memisahkan null/undefined dari tipe lain
  • strictFunctionTypes: Memeriksa tipe fungsi lebih ketat
  • strictBindCallApply: Memeriksa bind/call/apply

Selalu aktifkan strict: true di proyek baru.

Lebih sulit di awal tapi menyelamatkan dari ratusan bug.

Pattern: Barrel Export

Sederhanakan import dengan mengelompokkan export di file index.ts:

// src/types/index.ts
export type { User, CreateUserDto, UpdateUserDto } from './user';
export type { Post, CreatePostDto } from './post';

// Penggunaan
import { User,

CreateUserDto } from '@/types';

Pattern: Branded Types

Bedakan tipe yang struktur datanya sama tapi maknanya berbeda:

type UserId = string & { readonly brand: unique symbol };
type PostId = string & { readonly brand: unique symbol };

function getUser(id: UserId) { ... }
function getPost(id: PostId) { ... }

const userId = 'abc' as UserId;
getUser(userId);     // OK
getPost(userId);     // Error!

UserId tidak assignable ke PostId

ESLint + TypeScript

Setup ESLint dengan TypeScript untuk aturan tambahan:

npm install -D eslint @eslint/js typescript-eslint

ESLint menangkap pola yang TypeScript compiler tidak tangkap: unused variables, prefer const, dan banyak aturan code quality.

Contoh Kode

json
// tsconfig.json untuk proyek React + Vite
{
  "compilerOptions": {
    "target": "ES2022",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"]
}

// Pattern: Repository dengan typed errors
type Result<T, E = Error> =
  | { ok: true; data: T }
  | { ok: false; error: E };

class UserRepository {
  async findById(id: number): Promise<Result<User>> {
    try {
      const user = await db.query('SELECT * FROM users WHERE id = ?', [id]);
      if (!user) return { ok: false, error: new Error('User not found') };
      return { ok: true, data: user };
    } catch (err) {
      return { ok: false, error: err instanceof Error ? err : new Error('Unknown') };
    }
  }
}

// Penggunaan — handle error secara eksplisit
const result = await userRepo.findById(1);
if (!result.ok) {
  console.error(result.error.message);
  return;
}
console.log(result.data.name);  // Type-safe, data pasti ada

Penjelasan Kode

noUnusedLocals: true mencegah variabel yang tidak terpakai. Result<T, E> pattern memaksa handle error secara eksplisit — tidak ada exception yang terlewat.

Prompt AI

Setup tsconfig.json dengan strict: true di proyekmu. Perbaiki semua error yang muncul setelah strict mode diaktifkan.

Pertanyaan Reflektif

Coba nonaktifkan strict: true sementara — berapa banyak any yang muncul? Itu adalah bug tersembunyi yang TypeScript selamatkanmu dari mereka.