Bird
Raised Fist0
Typescriptprogramming~30 mins

How structural typing differs from nominal typing in Typescript - Try It Yourself

Choose your learning style10 modes available
How structural typing differs from nominal typing
📖 Scenario: Imagine you are organizing a party and you want to check if guests have the right invitation. Invitations can be different but if they have the same important details, they are accepted.
🎯 Goal: You will create two types of invitations using TypeScript: one using structural typing and one using nominal typing. You will see how TypeScript treats them differently when checking if a guest's invitation is valid.
📋 What You'll Learn
Create two interfaces with the same structure
Create two variables with these interfaces
Show how TypeScript allows assignment with structural typing
Show how nominal typing prevents assignment
Print results to demonstrate the difference
💡 Why This Matters
🌍 Real World
Understanding how TypeScript checks types helps you write safer code that avoids bugs caused by mixing incompatible data.
💼 Career
Many software jobs require knowledge of TypeScript's type system to build reliable web applications and APIs.
Progress0 / 4 steps
1
Create two interfaces with the same structure
Create two interfaces called InvitationA and InvitationB. Both should have a name property of type string and a date property of type string.
Typescript
Hint

Interfaces define the shape of an object. Both interfaces should look exactly the same.

2
Create variables with these interfaces
Create a variable called inviteA of type InvitationA with name set to "Alice" and date set to "2024-07-01". Create another variable called inviteB of type InvitationB with name set to "Bob" and date set to "2024-07-02".
Typescript
Hint

Use const to create variables with the given types and values.

3
Show structural typing allows assignment
Assign inviteB to a new variable called structuralTest of type InvitationA. This should work because TypeScript uses structural typing.
Typescript
Hint

Assign inviteB directly to a variable typed as InvitationA.

4
Show nominal typing prevents assignment
Create a type called NominalInvitationA that adds a unique brand to InvitationA to simulate nominal typing. Then try to assign inviteB to a variable nominalTest of type NominalInvitationA. Print structuralTest and nominalTest to show the difference.
Typescript
Hint

Use a branded type to simulate nominal typing. Assigning inviteB directly to NominalInvitationA is not allowed. Print both variables to see the difference.

Practice

(1/5)
1. Which of the following best describes structural typing in TypeScript?
easy
A. Types are compatible if their properties and types match, regardless of their names.
B. Types must have the exact same name to be compatible.
C. Types are only compatible if they come from the same class.
D. Types are checked only at runtime for compatibility.

Solution

  1. Step 1: Understand structural typing concept

    Structural typing means compatibility depends on the shape (properties and types) of objects, not their names.
  2. Step 2: Compare with nominal typing

    Nominal typing requires exact type names or declarations to match, which is not how TypeScript works by default.
  3. Final Answer:

    Types are compatible if their properties and types match, regardless of their names. -> Option A
  4. Quick Check:

    Structural typing = shape-based compatibility [OK]
Hint: Think about shape, not names, for structural typing [OK]
Common Mistakes:
  • Confusing structural typing with nominal typing
  • Thinking type names must match for compatibility
  • Assuming runtime checks for type compatibility
2. Which TypeScript code snippet correctly demonstrates structural typing compatibility?
easy
A. const a: {name: string} = {name: 'Alice'}; const b: {name: string} = a;
B. class A {} class B extends A {} const a: A = new B();
C. type A = {id: number}; type B = {name: string}; const a: A = {id: 1}; const b: B = a;
D. interface A {name: string;} interface B {name: number;} const a: A = {name: 'Bob'}; const b: B = a;

Solution

  1. Step 1: Check property shapes for compatibility

    const a: {name: string} = {name: 'Alice'}; const b: {name: string} = a; assigns an object with a matching property name: string to another variable with the same shape, which is allowed.
  2. Step 2: Analyze other options for incompatibility

    A mismatches properties (id vs name), B uses classes (nominal typing), D mismatches property types.
  3. Final Answer:

    const a: {name: string} = {name: 'Alice'}; const b: {name: string} = a; -> Option A
  4. Quick Check:

    Matching shapes = compatible [OK]
Hint: Match property names and types exactly for compatibility [OK]
Common Mistakes:
  • Assuming different property names are compatible
  • Ignoring property type mismatches
  • Confusing class inheritance with structural typing
3. What will be the output of this TypeScript code?
interface Point { x: number; y: number; }
interface Named { name: string; }

const p: Point = { x: 10, y: 20 };
const n: Named = { name: 'Origin' };

function printPoint(point: Point) {
  console.log(`x=${point.x}, y=${point.y}`);
}

printPoint(p);
printPoint(n as unknown as Point);
medium
A. x=10, y=20 x=0, y=0
B. x=10, y=20 x=undefined, y=undefined
C. x=10, y=20 x=Origin, y=undefined
D. Type error at compile time

Solution

  1. Step 1: Understand structural typing and casting

    The object p matches Point shape, so printPoint(p) prints x=10, y=20. The object n does not have x or y, but is forced cast to Point.
  2. Step 2: Predict output for forced cast

    At runtime, n lacks x and y, so accessing them prints undefined.
  3. Final Answer:

    x=10, y=20 x=undefined, y=undefined -> Option B
  4. Quick Check:

    Forced cast ignores shape, runtime undefined properties [OK]
Hint: Casting doesn't add missing properties, they stay undefined [OK]
Common Mistakes:
  • Expecting runtime type errors
  • Assuming cast adds missing properties
  • Confusing property names with values
4. Identify the error in this TypeScript code related to structural typing:
interface A { id: number; }
interface B { id: number; name: string; }

const a: A = { id: 1 };
const b: B = a;
medium
A. Error because interfaces cannot be assigned to each other.
B. Error because a and b have different interface names.
C. No error, assignment is allowed due to structural typing.
D. Error because a lacks property name required by B.

Solution

  1. Step 1: Check property requirements for assignment

    Variable b expects an object with id and name. Variable a only has id.
  2. Step 2: Understand structural typing rules

    Structural typing requires the assigned object to have at least the required properties. Here, a is missing name, so assignment fails.
  3. Final Answer:

    Error because a lacks property name required by B. -> Option D
  4. Quick Check:

    Missing required properties cause assignment error [OK]
Hint: Check all required properties exist before assignment [OK]
Common Mistakes:
  • Ignoring missing properties in assignment
  • Thinking interface names must match for compatibility
  • Assuming partial property match is enough
5. Given these TypeScript classes, which assignment is allowed due to structural typing?
class Person { name: string; constructor(name: string) { this.name = name; } }
class Employee { name: string; salary: number; constructor(name: string, salary: number) { this.name = name; this.salary = salary; } }

let p: Person = new Person('Alice');
let e: Employee = new Employee('Bob', 50000);

// Which assignment is valid?
// 1) p = e;
// 2) e = p;
hard
A. Both assignments are allowed due to structural typing.
B. Only assignment 2) e = p; is allowed because Person has all Employee properties.
C. Only assignment 1) p = e; is allowed because Employee has all Person properties.
D. Neither assignment is allowed because classes use nominal typing.

Solution

  1. Step 1: Compare properties of Person and Employee

    Person has name. Employee has name and salary. Employee has all Person properties plus more.
  2. Step 2: Apply structural typing rules for assignment

    Assigning e (Employee) to p (Person) is allowed because e has at least the properties of p. The reverse is not allowed because p lacks salary.
  3. Final Answer:

    Only assignment 1) p = e; is allowed because Employee has all Person properties. -> Option C
  4. Quick Check:

    Subtype with extra properties can assign to supertype [OK]
Hint: Assign subtype to supertype, not vice versa [OK]
Common Mistakes:
  • Assuming both assignments are allowed
  • Confusing nominal typing with structural typing here
  • Ignoring extra properties in assignment compatibility
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard