AJP
AJP

Reputation: 28463

What does declare in `export declare type Xyz` mean vs `export type Xyz`

In a definition file it is valid to write both:

export declare type Abc = string;
export type Bcd = string;

The declare keyword here serves no purpose, correct?

Upvotes: 35

Views: 15057

Answers (2)

Paul-Sebastian Manole
Paul-Sebastian Manole

Reputation: 2692

declare in TypeScript is analogous to forward declarations in C++, for example.

Forward declarations tell a compiler that a certain thing:

  1. exists,
  2. but is not defined here (thus only declared!)

The declaration could be of anything, like of any type declaration or definition (but, without that definition).

So, it could be a simple type, an object, a function signature, an enum... anything.

In C++, one example of a forward declaration could be this:

int add(int x, int y);

This tells C++ that somewhere, a function that takes two integer arguments and returns an integer, exists, but it's not defined here (you don't see any implementation in this declaration!). Nor is it imported, or needs to be imported, as in languages like C++ you have something called a linker and linking step, that, at compile time, takes care of bringing in the correct implementation for that declaration.

In TypeScript, the semantics are not that different, but the way it works, the way it's implemented, of course, is.

A declaration tells the TypeScript compiler, like it does C++, how something is declared, what types are available, what properties are available, etc., basically everything you can do with all types that you can define otherwise, minus of course the definition: you can declare a function signature or a namespace and its components (functions, variables), but you cannot define the implementation (no function bodies!).

One main aspect to note about TypeScript declare declaration is that:

declare type MyObject = {
  doSomething: () => void,
  // ...
}

and

type MyObject = {
  doSomething: () => void,
  // ...
}

while they may look the same, and function (apparently) the same, the first version only tell the compiler how to statically type check an object of the declared type, but when automatically generating type definition files (d.ts), for example for reusable packages (libraries), only the second version works (assuming the type is also exported), unless you write those definition files manually.

Think of declare as a way to tell the TS compiler how something that is not managed by the current project looks, like something from a third party library that is not typed (JS, JSON, etc.). You could use it to tell the compiler how a JS library that you imported looks like, what it exports, etc.

Upvotes: 5

Erik Cupal
Erik Cupal

Reputation: 2935

Correct. declare keyword is useful when you need to say that there will be a variable or constant at execution time.

Example: Let's say you want to import library someExternalLib, but it is not on npm (you have to manually include it via script tag). You know that it will be accessible as global variable someExternalLib with functions fun1 and fun2. The problem is that Typescript doesn't know - that's why you have to help it by declaring the global someExternalLib:

declare const someExternalLib: { fun1: () => number, fun2: () => number }

This is usually necessary in definition files to declare variables, constants, classes, functions. It is redundant for types and interfaces.

Upvotes: 31

Related Questions