liveBook · Manning

TypeScript

As explained in React in Depth

TypeScript is a statically typed programming language that extends JavaScript with type syntax and compiles to JavaScript.

TypeScript extends JavaScript with static typing and type-safety checks. It transpiles to JavaScript, leaving its additional type information behind; the payoff comes before execution, when mismatches can surface in the editor or during compilation. In a React codebase, types can document contracts across components, hooks, functions, and libraries—not just component props. section 5.1 section 4.3.2

A practical React setup moves from file conventions to reusable contracts:

  • Use .ts for TypeScript without JSX and .tsx for files containing JSX; many setups reject JSX in .ts files. section 5.2.1
  • Define component props with types or interfaces. Optional properties, unions, generics, discriminated unions, and utility types let contracts describe more than a fixed list of fields. section 5.4
  • Prefer inference where it is clear, but supply types when context disappears or an initial value is too narrow. React contexts, reducers, refs, and callbacks can need explicit type arguments or annotations. section 6.1.3 section 6.5
type ButtonProps = ComponentPropsWithoutRef<"button">;
type RequireSome<T, K extends keyof T> = T & Required<Pick<T, K>>
type HoverButtonProps = RequireSome<
  ButtonProps,
  "onMouseOver" | "onMouseMove" | "onMouseOut"
>;

This utility type makes selected button props required without copying their existing definitions. It illustrates how combining Pick, Required, and an intersection can turn a recurring prop constraint into a reusable contract. section 5.3.6

Typing a context

A context created with a Boolean default infers a Boolean value, so useContext needs no extra hint. For an object initialized to null, declare an interface and pass the expected value type, including null, to createContext. A wrapper hook can reject a missing provider before returning the value. section 6.1.3

When inference changes

An inline callback passed to a playlist item can infer its argument types from the item's move prop. Move that callback into useCallback to share it across memoized items, and those arguments need annotations because the prop no longer supplies context. By contrast, effects usually need no type hints; an effect returning false instead of nothing or a cleanup function produces a type error. section 6.1.6 section 6.1.4

Adoption is a trade-off, not a free upgrade: expect a learning curve, more code, and more time spent writing it. The case is strongest when earlier feedback and discoverable contracts reduce maintenance and help teammates work in unfamiliar parts of a codebase. If a team cannot fund that upfront investment, delaying adoption is reasonable. In a Remix expense-tracker project, TypeScript is also a practical requirement: Remix typing and Prisma-generated types supply part of the contract. section 6.3 section 12.0

How React in Depth covers it

How deep it goes
Works through component props and React-hook typing, including utility types and generics, without attempting exhaustive coverage of TypeScript.
Examples
Uses required button props, a dark-mode context, playlist callbacks, and an invalid effect return to expose typing decisions.
What it assumes
Assumes JavaScript and React familiarity while introducing TypeScript files, static types, and their use in React.
What you can do after
Apply it via React to type component contracts and hooks, interpret type errors, and weigh adoption costs.
How it connects
Connects TypeScript to React props, context, effects, reducers, memoization, and runtime property-type validation.

Also explained in

Compare how 4 books explain TypeScript →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React in Depth. The section links point to the parts of the book it draws on.