Phase 6 · Advanced & ProfessionalModule 39~52 min read

Security, TypeScript & Professional Workflow

Harden JavaScript applications, add gradual static typing, and collaborate with production-grade workflows.

What you'll learn

Professional JavaScript combines threat-aware boundaries, gradual static typing, reviewed changes, and automated delivery. Security and types reduce different classes of uncertainty and work best together.

By the end of this lesson, you'll be able to:

  • Prevent common web injection and request attacks
  • Use TypeScript narrowing and generics
  • Design a reviewable CI workflow

Core mental model

Use this decision table as a compact reference. Focus on what each tool means and when it earns its place in production code.

ConceptWhat it meansDecision rule
Output safetyData remains data in its destination contextUse safe APIs and context-correct encoding
Type narrowingRuntime evidence refines a static unionValidate unknown input before treating it as domain data
CI gateAutomated checks protect the main branchRun types, tests, lint, security, and build on every change

Professional workflow

Build the behavior in small, observable steps. Each step should leave something you can inspect or test.

  1. Describe the secure typed delivery workflow boundary: inputs, outputs, state, timing, and expected failures.
  2. Implement the smallest correct path with names that expose intent.
  3. Add edge cases and failure handling before introducing abstractions.
  4. Verify behavior with realistic data and one deliberately adversarial example.
  5. Refactor only after the observable behavior is protected.

Make behavior observable

Before optimizing or abstracting, make inputs, outputs, state changes, timing, and failure paths visible. JavaScript becomes much easier to reason about when hidden work is exposed.

Guided code lab

Narrow unknown API data

The type guard performs runtime validation before TypeScript grants a trusted shape.

course.ts
type Course = { id: string; title: string };

function isCourse(value: unknown): value is Course {
  if (typeof value !== "object" || value === null) return false;
  const record = value as Record<string, unknown>;
  return typeof record.id === "string" && typeof record.title === "string";
}

const value: unknown = JSON.parse(payload);
if (!isCourse(value)) throw new TypeError("Invalid course payload");

Keep untrusted text as text

The DOM API preserves the code/data boundary and avoids HTML parsing.

safe-output.js
function renderComment(container, comment) {
  const article = document.createElement("article");
  const body = document.createElement("p");
  body.textContent = comment.body;
  article.append(body);
  container.append(article);
}

Production practice

Contract

Write down the secure typed delivery workflow quality target, ownership boundary, evidence, and acceptable tradeoffs.

Verification

Use repeatable automated checks plus a realistic end-to-end scenario; include failure and recovery behavior.

Operations

Track a small set of user-centered signals and revisit the decision when evidence changes.

Common failure mode

TypeScript types disappear at runtime; they do not validate JSON, stop XSS, authorize requests, or replace dependency review.

Independent workshop

Migrate one application slice to TypeScript and harden its data path.

Your finished workshop must include:

  • unknown at the external boundary plus runtime validation
  • No unsafe HTML sink
  • CI checks for types, tests, build, and dependency risk

Definition of done

Demonstrate the happy path and at least two edge cases, keep responsibilities separated, and add a short note explaining one design choice.

Recap & quick check

Key takeaways

  • Keep code and data separate
  • Validate every trust boundary
  • TypeScript models compile-time guarantees
  • CI makes quality repeatable

Quick check

1. What type best represents unvalidated external data?

2. Does TypeScript validate JSON at runtime?

3. Which DOM API safely renders ordinary text?

Keep the workshop. Later modules deliberately build on these decisions, so each exercise can become part of your final portfolio architecture.