015 — Interfaces (contracts that enforce object shape)
Full companion narrative for TypeScript Tutorial - Interfaces: declaring an interface, object compliance, excess property checks, and interfaces as function parameter types
Video: 015 · TypeScript Tutorial - Interfaces · watch · 7:18 · Net Ninja TypeScript tutorial series
Source: this is a written companion to the video. Part of the Favorite TypeScript Videos curated path, module 05 (objects and interfaces). The first interfaces lesson: what a contract is, how objects satisfy it, and how functions can demand it.
contracts that never create objects
An interface describes what properties and methods a class or object must have — property types plus method signatures (parameter types and return types). It is not a class: it has no constructor and it never generates objects. It only declares a contract that future variables, objects, and function parameters must satisfy.
Interfaces are a TypeScript-only tool. There is no interface keyword or equivalent in JavaScript, and no interface code is emitted at runtime — the compiler checks compliance, then erases the interface.

Naming note: the instructor says and writes IsPerson / IPerson interchangeably for the same contract. Both spellings refer to one interface. This narrative uses IsPerson in code blocks, except where quoting a frame verbatim (IPerson in the declaration shot below).
the IsPerson declaration
Keyword interface, then a name, then a body in curly braces listing each required member and its type:
interface IsPerson {
name: string;
age: number;
speak(a: string): void;
spend(a: number): number;
}

What each member means:
| member | meaning |
|---|---|
name: string | every person object has a name, and it is a string |
age: number | every person object has an age, and it is a number |
speak(a: string): void | every person object has a speak method taking one string, returning nothing (void) |
spend(a: number): number | every person object has a spend method taking one number, returning a number |
Parameter names are not part of the contract. The interface calls the first parameter a; the implementing object below calls it text and amount. That is allowed — parameter types, count, and return types must match; names need not.
every member present, or it errors
Annotate a variable with the interface as its type, then initialize it:
const me: IsPerson = {
name: "shaun",
age: 30,
speak(text: string): void {
console.log(text);
},
spend(amount: number): number {
console.log("I spent", amount);
return amount;
},
};
console.log(me);
Behavior demonstrated in the video, in order:
- Annotating
measIsPersonwith an empty object initializer errors immediately — the object does not yet comply. - Adding each property and method clears the error only once all four members are present with matching signatures. Commenting any one member back out brings the error back.
- With all members present the error is gone and
console.log(me)prints the object with all properties and methods (confirmed in the browser console on screen).
Return-type annotations on the methods (: void, : number) are written explicitly here for teaching clarity. TypeScript could infer them from the function bodies; the explicit form is optional.
undeclared extras are rejected
Adding a member not listed in the interface fails:
const me: IsPerson = {
name: "shaun",
age: 30,
speak(text: string): void {
console.log(text);
},
spend(amount: number): number {
console.log("I spent", amount);
return amount;
},
skills: [], // ERROR: 'skills' is not part of IsPerson
};
The object must match the interface structure exactly — no missing members (previous section), no undeclared extras. Removing skills clears the error.

many objects, one contract
Any number of objects can be typed IsPerson with different values and different method bodies, as long as each method keeps the same signature (same parameter types, same return type). What the function does inside can differ completely; the shape cannot.
A second variable declared later is held to the same rules at the point of assignment:
let someone: IsPerson;
// ...later, whatever is assigned to `someone` must satisfy IsPerson
demanding the contract in a function parameter
A function can require that its argument satisfy the interface:
const greetPerson = (person: IsPerson) => {
console.log("hello", person.name);
};

Two consequences shown on screen:
- IntelliSense: inside
greetPerson, typingperson.offersname,age,speak,spendautomatically, because TypeScript knows the argument follows the interface. - Call-site enforcement: passing a bare
{ name: '...' }object is rejected — it does not satisfy the full contract. Passingme, which is typedIsPerson, is accepted. Saving and running printshello shaun.
contract only, no constructor
- A class is a blueprint plus a constructor: it creates objects.
- An interface is a contract only: no constructor, no instantiation, no runtime code emitted. It describes required properties, method signatures, and their types, and the compiler checks compliance.
The instructor’s closing preview applies interfaces to classes — a class declaring that it implements an interface contract — 016 — Interfaces with Classes.
Prev: 014 — Modules · Next: 016 — Interfaces with Classes
Transcript notes: string (not “satring” — code on screen is correct); IsPerson / IPerson are one contract, spellings unified except where quoting a frame; greetPerson. Frames 1 and 3 show the Finance Logger page as background context only — no transaction logic is taught here. Interfaces are TypeScript-only: erased at runtime, no code emitted.