Difference between 'interface' and 'declare interface'

declare keyword is usually used in type definitions to describe existing classes or variables that are defined externally in JavaScript code.

There's no difference between declare interface and interface because:

  • there's no code generation for interfaces and they exist only in Typescript code so you can not declare interface that's defined in JavaScript code;
  • interface in Typescript by its nature is declaration only, it has no method bodies, properties values, etc. so both declare interface and interface are syntactically equal.

What also will be helpful to understand in order to answer the question is the concept of Interface Declaration Merging. In TS Interface Declaration Merging works as follows:

Whenever we declare an interface multiple times (with or without declare keyword), they get merged together. This means the interface now has the properties of both interfaces merged together. This is best understood via an example:

// Usually this interface would be defined in another file
// or package already
interface foo { num1: number }

// Because the interface foo is already defined TS will apply 
// interface declaration merging
declare interface foo{num2: number}
// Declare keyword makes it more explicit that is was defined
// somewhere else, it adds n


let fooObj: foo = { num1: 1 }
// Typescript will give the following error:
// Property 'num2' is missing in type '{ num1: number; }' 
// but required in type 'foo'.(2741)

// It requires the property num2 because after the interface merging 
// the interface contains both num1: number, and num2: number properties


// This interface declaration merging functionally similar to 
// the foo interface above, just without the declare keyword
interface bar{ string1: string }
interface bar{ string2: string }

let barObj: bar = { string1: 'hi', string2: 'hithere' }

declare keyword before an interface

Note that declare interface makes it just more explicit that the interface was defined somewhere else (other file, package, etc.) nothing more. i.e. it adds no extra functionality at all.

Also note that interfaces are just there to give additional type information to the TS compiler and do not exists in the compiled JS. The above code gets compiled to the following JS:

"use strict";
let fooObj = { num1: 1 };
let barObj = { string1: 'hi', string2: 'hithere' };

Tags:

Typescript