48

What is the difference (if any) between:

declare interface SomeInterface {
    //members here
}

and:

interface SomeInterface {
    //members here
}

?

John Montgomery
  • 6,739
  • 9
  • 52
  • 68
Rapid Here
  • 483
  • 4
  • 8
  • 2
    All -- I've cleaned up some comments here. Please refrain from editing tags into the title of questions and from repeatedly making the same suggested edit. – josliber Jan 03 '20 at 02:09
  • @josliber the suggested edit came because when i was creating the question I couldn't find this one. This question had no reference to TypeScript in the question. The question got edited from the OP original posting to take out the word typescript. Again, the word TypeScript is "organic to the conversational tone" It's simply readable do you not agree? – Christian Matthew Jan 03 '20 at 04:45
  • 2
    @ChristianMatthew the question is tagged with typescript; that should be sufficient. If you want to discuss this further, I would suggest posting on meta.stackoverflow.com instead of getting into an edit war here. – josliber Jan 04 '20 at 14:36

2 Answers2

37

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.
mixel
  • 25,177
  • 13
  • 126
  • 165
  • 19
    `declare interface` and `interface` are obviously syntactically different (one is 2 words the other one), but are **semantically** equal. – Mike Lischke Apr 27 '17 at 13:31
  • 1
    This is not correct. Declared interface values are not minified / renamed while regular interface will get removed in final JS file. Furthermore if interface is not declared properties inside undeclared interface can be minified/renamed. – Luke Nov 05 '21 at 15:56
  • 1
    @Luke What you're describing is demonstrably incorrect (just try it out on TS Playground: **all** interface types in TypeScript experience type-erasure, not just `interface` but also `declare interface`. Do you have a source or citation for your claim that "declared interfaces are not minified"? Are you thinking of the `declare interface` that appears in `.d.ts` output files (as opposed to `.js` output files)? If so, then you'll find that both `declare interface` and `interface` types will appear in `.d.ts` files. The removal of unused types is not done by TypeScript at all, but elsewhere. – Dai Jan 19 '22 at 17:31
3

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' };
Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155