Programming language
TypeScript
TypeScript is a statically checked superset of JavaScript that adds syntax for describing values, APIs, and program states before execution.
What is TypeScript and what does it do?
TypeScript extends JavaScript with syntax for types and a static checker. It can describe object shapes, function contracts, generic relationships, and the possible states of a value. The toolchain reports inconsistencies before the generated JavaScript runs.
Its type system provides design feedback. A useful type explains a real boundary or state transition. It should make the runtime behavior easier to understand, not become a separate puzzle above it.
Types disappear before execution
TypeScript checks source code, then emits JavaScript without its type annotations. The path can be pictured like this:
- Write TypeScript source and type declarations.
- Let the checker compare assignments, calls, and control flow.
- Emit JavaScript for the selected runtime target.
- Validate real external values while the program runs.
The last step is essential. An interface cannot inspect a network response, storage entry, or configuration file after the types have been erased.
Unknown data must earn a type
Untrusted input should start as unknown. A type guard can inspect it and narrow the value for later code.
type User = { id: number; name: string };
function isUser(value: unknown): value is User {
if (typeof value !== "object" || value === null) return false;
const item = value as Record<string, unknown>;
return typeof item.id === "number"
&& typeof item.name === "string";
}
The assertion only gives the temporary record a shape that can be inspected. The returned boolean and type predicate are based on runtime checks.
Model states, not just properties
A union can make invalid combinations harder to express.
| State | Data that belongs to it |
|---|---|
idle |
No result and no error |
loading |
Request identity or progress |
success |
Valid result |
failure |
Error information |
One discriminant with state-specific data is clearer than several optional properties whose combinations need to be guessed. Exhaustive checks then reveal a missing branch when the union grows.
Strictness is a design choice
Compiler options determine how much uncertainty the checker accepts. Strict settings are a strong default for new code because they expose nullability, implicit any, and unchecked assumptions early.
There is still a boundary. Complex conditional or generic types can cost more attention than they save, and an assertion can silence the checker without proving anything. A type should be simplified when its explanation becomes longer than the behavior it protects.