Why TypeScript? Basic
TypeScript is a superset of JavaScript: every JS file is already valid TS. It adds static types, which are checked before your code runs. Browsers can't run TS, so it is compiled to plain JavaScript first.
Types exist only at compile time. They are completely removed in the output.
Setup Basic
create-next-app sets up TypeScript for you. Rename a file to .ts or .tsx and it just works. Recent Node.js versions can also run .ts files directly by stripping the types.Basic types & inference Basic
| Type | Meaning | Use? |
|---|---|---|
any | Turns type checking off | Avoid. It hides bugs. |
unknown | "Could be anything, so check it before use" | Use for untrusted data (JSON, catch errors) |
void | The function returns nothing | Return type of handlers |
never | A value that can never exist | Exhaustive checks, functions that always throw |
Arrays, tuples & objects Basic
Type aliases & interfaces Basic
Give a shape a name so you can reuse it.
| Feature | type | interface |
|---|---|---|
| Object shapes | β | β |
| Unions / primitives / tuples | β | β |
| Extend | & | extends |
| Declaration merging | β | β |
| Mapped / conditional types | β | β |
interface for object/class shapes and type for everything else.Functions Basic
Union & literal types Basic
A union (A | B) means "either A or B". A literal type allows only exact values.
Only the highlighted values are allowed. Typos like "sucess" are caught right away.
Enums vs union of literals
Narrowing & type guards Intermediate
Narrowing is how TS works out a more specific type inside an if block, based on the checks you write.
Discriminated unions (very common!)
Generics Intermediate
Generics are type parameters. They let one function or type work with many types without losing type information.
Box<T> is a box whose label you fill in later. Box<Shoe> holds shoes and Box<Book> holds books. It's the same box design, and you always know what's inside.Utility types Intermediate
Built-in helpers that transform existing types, so you don't have to rewrite them.
Partial<User>
all fields optional β great for PATCH updates
Required<User>
all fields required
Pick<User, "id" | "name">
only id, name
Omit<User, "password">
everything except password β safe public user
Readonly<User>
no field can be reassigned
Record<K, V>
object with keys K and values V
keyof, typeof & indexed access Intermediate
Classes Intermediate
| Modifier | Accessible from |
|---|---|
public (default) | Anywhere |
protected | The class and its subclasses |
private / #field | Only the class (# is also enforced at runtime) |
readonly | Set once in the constructor |
Mapped types Advanced
A mapped type loops over the keys of a type and builds a new one. This is how Partial and Readonly are built.
Conditional types & infer Advanced
The syntax is T extends U ? X : Y, which works like a ternary operator for types. With infer you can pull a type out of another type.
Template literal types Advanced
Modules & declaration files Advanced
npm i -D @types/pg. They come from the DefinitelyTyped project.tsconfig.json essentials Advanced
strict enables⦠| Catches |
|---|---|
strictNullChecks | Using a value that may be null/undefined |
noImplicitAny | Parameters with no type |
strictFunctionTypes | Unsafe function assignments |
strictPropertyInitialization | Class fields never set |
TypeScript with React & Next.js Advanced
z.infer. The same type then covers the form (frontend), the validation (backend) and the DB insert. One source of truth.Interview questions
Which type should you give to JSON.parse() results from an API?
You want a User type without the password field. Useβ¦
type can also express unions, tuples, primitives, mapped types and conditional types. interface supports declaration merging and extends. Choose one and be consistent.first<T>(arr: T[]): T.Cheat sheet
Basics
x: stringannotatea?: ToptionalA | BunionA & BintersectionT[]/[A, B]array / tuple
Utilities
Partial / Requiredoptional-nessPick / Omitselect keysRecord<K,V>mapReturnType / Awaitedextract
Operators
keyof Tkeys uniontypeof xtype of valueT[K]indexedas constliteralsatisfiescheck only
Advanced
<T extends X>constraint[K in keyof T]mappedT extends U ? X : Yconditionalinfer Rextractx is Ttype guard