Purpose of declare keyword in TypeScript

Typescripttypescript2.0

Typescript Problem Overview


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.

Typescript Solutions


Solution 1 - Typescript

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.

Solution 2 - Typescript

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 fooSdk 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.

Solution 3 - Typescript

From Typescript docs:

Typescript - Working with Other JavaScript Libraries

> To describe the shape of libraries not written in TypeScript, we need to declare the API that the library exposes. Because most JavaScript libraries expose only a few top-level objects, namespaces are a good way to represent them. > > We call declarations that don’t define an implementation “ambient”. Typically these are defined in .d.ts files. If you’re familiar with C/C++, you can think of these as .h files. Let’s look at a few examples. > > ### Ambient Namespaces > > The popular library D3 defines its functionality in a global object called d3. Because this library is loaded through a

Solution 4 - Typescript

You can use declare to tell the compiler about types before you write any implementation code and TypeScript will be happy.

declare function foo(name: string): string

Solution 5 - Typescript

Consider this scenario: You have a Typescript project. Then you decide to write a module in JavaScript for whatever reason and use it in your Typescript code.

// getMyName.js
module.exports = function getMyName(name) {
    return name;
}

Then you import it into your typescript code

// myCode.ts
import getMyName from 'getMyName'; //getMyName is a JS module not typescript

When importing that JS module(allowJs compiler option should be set to false otherwise, JS files will be resolved without any type definitions), Typescript's compiler complains about that module not being a module at all!

Could not find a declaration file for module '/absolute/path/to/getMyName.ts'

This is because Typescript doesn’t resolve to JS code by its own. To circumvent this problem we should provide type definition (filename.d.ts) for our JS module. To do so you can use declare and export.

// getMyName.d.ts
declare function getMyName(name: string): string;

export default getMyName;

After that when we import our JS module, typescript doesn't complain about anything because it now has access to the types.

Solution 6 - Typescript

delcare key words use when you import some library not have the declare type files,such as *.d.ts

after that vs eslint not check the syntax and context , will let you pass, if you default use tsc compiler, that the good reason to declare to remove syntax error

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlexander MillsView Question on Stackoverflow
Solution 1 - TypescriptSean BradleyView Answer on Stackoverflow
Solution 2 - Typescriptuser1852503View Answer on Stackoverflow
Solution 3 - TypescriptcbdeveloperView Answer on Stackoverflow
Solution 4 - TypescriptAndy CoupeView Answer on Stackoverflow
Solution 5 - TypescriptShahin GhasemiView Answer on Stackoverflow
Solution 6 - Typescriptjinjun SuView Answer on Stackoverflow