liveBook · Manning

Type checking

As explained in Essential TypeScript 5, Third Edition

Type checking is the analysis of program values and expressions to determine whether their types satisfy language rules.

Type checking analyzes values and expressions to determine whether their types satisfy language rules. TypeScript can check explicit annotations and inferred types, making JavaScript behavior more predictable before execution. section 7.8

TypeScript supports type checking through:

  • Annotations that declare permitted types, including any, unknown, and never. section 7.8
  • Unions, assertions, and guards that describe or narrow the possible types of a value. section 7.8
  • Object shapes, optional properties, unions, and intersections that compare required properties and methods. section 10.4
  • Compiler configuration such as strictNullChecks, which changes whether null and undefined are accepted broadly. section 7.8

Checking JavaScript boundaries

A JavaScript costFormatter function may receive an unvalidated string because the compiler infers any for missing type information. Calling costFormatter("Cart", `${cart.totalPrice}`) then compiles, but cost.toFixed(2) fails at runtime because strings do not provide the expected method. Supplying type information for the JavaScript code closes this hole. section 15.3

Listing 15.15 Using the wrong type in the index.ts file in the src folder
import { SportsProduct, SPORT } from "./product.js";
import { Cart } from "./cart.js";
import { sizeFormatter, costFormatter } from "./formatters.js";

let kayak = new SportsProduct(1, "Kayak", 275, SPORT.Watersports);
let hat =  new SportsProduct(2, "Hat", 22.10, SPORT.Running, 
    SPORT.Watersports);
let ball = new SportsProduct(3, "Soccer Ball", 19.50, SPORT.Soccer);

let cart = new Cart("Bob");
cart.addProduct(kayak, 1);
cart.addProduct(hat, 1);
cart.addProduct(hat, 2);

sizeFormatter("Cart", cart.itemCount);
costFormatter("Cart", `${cart.totalPrice}`);

Use the cart example to inspect a complete call site where incorrect argument types bypass checking and produce a runtime error. section 15.3

{
 "compilerOptions": {
   "target": "es5",
   "lib": [
     "dom",
     "dom.iterable",
     "esnext"
   ],
   "allowJs": true,
   "skipLibCheck": true,
   "esModuleInterop": true,
   "allowSyntheticDefaultImports": true,
   "strict": true,
   "forceConsistentCasingInFileNames": true,
   "noFallthroughCasesInSwitch": true,
   "module": "esnext",
   "moduleResolution": "node",
   "resolveJsonModule": true,
   "isolatedModules": true,
   "noEmit": true,
   "jsx": "react-jsx"
 },
 "include": [
   "src"
 ]
}

Inspect a React tsconfig showing strict checking with noEmit, separating error detection from JavaScript generation. section 20.2

How Essential TypeScript 5, Third Edition covers it

How deep it goes
Explains annotations, inference, unions, narrowing, object shapes, and configuration, while stopping short of compiler implementation internals.
Examples
Uses a cart formatter receiving strings, an ensuing toFixed runtime error, and a React tsconfig with strict and noEmit.
What it assumes
Assumes JavaScript familiarity, while teaching explicit types, inference, unions, assertions, guards, and object-shape comparisons.
What you can do after
Diagnose/debug with it by identifying unchecked JavaScript boundaries and separating TypeScript type errors from Babel transformation.
How it connects
Connects type checking with static types, type inference, type unions, type guards, object shapes, JavaScript, Babel, and React.

Also explained in

Compare how 5 books explain type checking →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential TypeScript 5, Third Edition. The section links point to the parts of the book it draws on.