TypeScript Deep Dive
  • README
  • Getting Started
    • Why TypeScript
  • JavaScript
    • Equality
    • References
    • Null vs. Undefined
    • this
    • Closure
    • Number
    • Truthy
  • Future JavaScript Now
    • Classes
      • Classes Emit
    • Arrow Functions
    • Rest Parameters
    • let
    • const
    • Destructuring
    • Spread Operator
    • for...of
    • Iterators
    • Template Strings
    • Promise
    • Generators
    • Async Await
  • Project
    • Compilation Context
      • tsconfig.json
      • Which Files?
    • Declaration Spaces
    • Modules
      • File Module Details
      • global.d.ts
    • Namespaces
    • Dynamic Import Expressions
  • Node.js QuickStart
  • Browser QuickStart
  • Library QuickStart
  • TypeScript's Type System
    • JS Migration Guide
    • @types
    • Ambient Declarations
      • Declaration Files
      • Variables
    • Interfaces
    • Enums
    • lib.d.ts
    • Functions
    • Callable
    • Type Assertion
    • Freshness
    • Type Guard
    • Literal Types
    • Readonly
    • Generics
    • Type Inference
    • Type Compatibility
    • Never Type
    • Discriminated Unions
    • Index Signatures
    • Moving Types
    • Exception Handling
    • Mixins
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • Errors in TypeScript
    • Interpreting Errors
    • Common Errors
  • NPM
  • Testing
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • ESLint
    • Changelog
  • TIPs
    • String Based Enums
    • Nominal Typing
    • Stateful Functions
    • Currying
    • Type Instantiation
    • Lazy Object Literal Initialization
    • Classes are Useful
    • Avoid Export Default
    • Limit Property Setters
    • outFile caution
    • JQuery tips
    • static constructors
    • singleton pattern
    • Function parameters
    • Build Toggles
    • Barrel
    • Create Arrays
    • Typesafe Event Emitter
  • StyleGuide
  • TypeScript Compiler Internals
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
Powered by GitBook
On this page
  • Interfaces
  • Classes can implement interfaces
  • TIPs
  • Not every interface is implementable easily
  1. TypeScript's Type System

Interfaces

Interfaces

Interfaces have zero runtime JS impact. There is a lot of power in TypeScript interfaces to declare the structure of variables.

The following two are equivalent declarations, the first uses an inline annotation, the second uses an interface:

// Sample A
declare var myPoint: { x: number; y: number; };

// Sample B
interface Point {
    x: number; y: number;
}
declare var myPoint: Point;

However, the beauty of Sample B is that if someone authors a library that builds on the myPoint library to add new members, they can easily add to the existing declaration of myPoint:

// Lib a.d.ts
interface Point {
    x: number; y: number;
}
declare var myPoint: Point;

// Lib b.d.ts
interface Point {
    z: number;
}

// Your code
var myPoint.z; // Allowed!

This is because interfaces in TypeScript are open ended. This is a vital tenet of TypeScript that it allows you to mimic the extensibility of JavaScript using interfaces.

Classes can implement interfaces

If you want to use classes that must follow an object structure that someone declared for you in an interface you can use the implements keyword to ensure compatibility:

interface Point {
    x: number; y: number;
}

class MyPoint implements Point {
    x: number; y: number; // Same as Point
}

Basically in the presence of that implements, any changes in that external Point interface will result in a compile error in your code base so you can easily keep it in sync:

interface Point {
    x: number; y: number;
    z: number; // New member
}

class MyPoint implements Point { // ERROR : missing member `z`
    x: number; y: number;
}

Note that implements restricts the structure of the class instances i.e.:

var foo: Point = new MyPoint();

And stuff like foo: Point = MyPoint is not the same thing.

TIPs

Not every interface is implementable easily

Interfaces are designed to declare any arbitrarily crazy structure that might be present in JavaScript.

Consider the following interface where something is callable with new:

interface Crazy {
    new (): {
        hello: number
    };
}

You would essentially have something like:

class CrazyClass implements Crazy {
    constructor() {
        return { hello: 123 };
    }
}
// Because
const crazy = new CrazyClass(); // crazy would be {hello:123}

You can declare all the crazy JS out there with interfaces and even use them safely from TypeScript. Doesn't mean you can use TypeScript classes to implement them.

PreviousVariablesNextEnums

Last updated 5 years ago