Purpose of declare keyword in TypeScript
What is the purpose of the declare
keyword?
type Callback = (err: Error | String, data: Array<CalledBackData>) => void;
vs.
declare type Callback = (err: Error | String, data:Array<CalledBackData>) => void;
Cannot find docs that explain the purpose of the declare
keyword in TS.
Here is a real world example.
I have a TypeScript React app that uses the Webpack Hot Middleware. The Webpack Hot Middleware is not written in TypeScript, but in good old-fashioned JavaScript. So it has no type declarations that the TypeScript compiler can check against.
When I run my code, the object module
from the Webpack Hot Middleware exists, and I can console.log it despite it being good old-fashioned JavaScript hiding in my fancy new TypeScript React app.
The module
object also has keys, such as module.hot
, and the keys can have values. But the TypeScript design time compiler (in VSCode at least) draws a red squiggly under it saying property 'hot' does not exist
. But it does exist!
To make the TypeScript compiler agree, declare it like this:
declare let module: any
The existing module
object, now has a type of any
, which makes the TypeScript compiler happy now, red squiggly gone and now I can continue to compile and write my other code.
If you remove the keyword declare
, and just write let module: any
, it will not compile, instead saying that 'module' already exists
. That's what "ambient" in the accepted answer means.
TL;DR
declare
is used to tell the compiler "this thing (usually a variable) exists already, and therefore can be referenced by other code, also there is no need to compile this statement into any JavaScript".
Common Use Case:
You add a reference to your web page to a JavaScript file that the compiler knows nothing about. maybe it is a script coming from some other domain like 'foo.com'. when evaluated the script will create an object with some useful API methods and assign it to the identifier 'fooSdk' on the global scope.
You want your TypeScript code to be able to call fooSdk.doSomething()
but since your compiler does not know this variable exists you will get a compilation error.
You then use the declare
keyword as a way of telling the compiler "trust me, this variable exists and has this type". The compiler will use this statement to statically check other code but will not trans-compile it into any JavaScript in the output.
declare const fooSdk = { doSomething: () => boolean }
In the same vein, you can add the declare keyword to class properties to tell the compiler not to emit any code that would create this property, assuming you have your own code that would create it that the compiler does not know about or does not understand.
Your specific example is different since you are declaring a type, not a variable, types already do not compile into any JavaScript. I do not know if there is any reason to declare a type.