Learn how to use ambient declarations in TypeScript to describe APIs available in the global scope. Understand the use of the declare keyword and how to structure ambient declarations in .d.ts files.
As we delve deeper into TypeScript, we encounter situations where we need to describe APIs that exist in the global scope but are not inherently part of our TypeScript code. This is where ambient declarations come into play. In this section, we’ll explore how to use the declare
keyword to create ambient declarations, understand when they are necessary, and learn how to structure them effectively in .d.ts
files.
Ambient declarations are a way to tell TypeScript about the existence of variables, functions, or other entities that are defined elsewhere, such as in a JavaScript library or a global script. These declarations do not provide implementations; instead, they describe the shape of the entities so that TypeScript can understand and type-check them.
declare
KeywordThe declare
keyword is used to create ambient declarations. It tells TypeScript that the declared entity exists somewhere else, and TypeScript should not expect to find its implementation within the current codebase.
// Declare a global variable
declare var myGlobalVariable: string;
// Declare a global function
declare function myGlobalFunction(param: number): void;
In the above examples, we declare a global variable myGlobalVariable
of type string
and a global function myGlobalFunction
that takes a number
as a parameter and returns void
.
Ambient declarations are particularly useful in the following scenarios:
Interfacing with JavaScript Libraries: When using a JavaScript library that does not have TypeScript type definitions, ambient declarations can help you define the types for the library’s API.
Working with Global Scripts: If your project includes scripts that define global variables or functions, ambient declarations allow you to describe these globals to TypeScript.
Legacy Codebases: In projects with legacy JavaScript code, ambient declarations can be used to gradually introduce TypeScript by providing type information for existing global entities.
.d.ts
FilesTo keep your TypeScript code organized, it’s a good practice to place ambient declarations in separate .d.ts
files. These files contain only type declarations and no implementations. They help TypeScript understand the types of global entities without cluttering your main codebase.
.d.ts
FileLet’s create a .d.ts
file for a hypothetical JavaScript library that provides a global function calculateArea
and a global variable PI
.
// globals.d.ts
// Declare a global variable
declare var PI: number;
// Declare a global function
declare function calculateArea(radius: number): number;
By placing these declarations in a globals.d.ts
file, we inform TypeScript about the existence and types of PI
and calculateArea
, allowing us to use them in our TypeScript code with proper type checking.
While ambient declarations are powerful, they come with the risk of polluting the global namespace. It’s essential to be cautious and deliberate when declaring global entities to avoid naming conflicts and unintended side effects.
// globals.d.ts
declare namespace MyLibrary {
var PI: number;
function calculateArea(radius: number): number;
}
Limit Global Declarations: Only declare global entities when absolutely necessary. Prefer module-based imports and exports to keep your code modular and maintainable.
Document Your Declarations: Provide comments and documentation for your ambient declarations to help other developers understand their purpose and usage.
Let’s see how we can use ambient declarations in a TypeScript project. We’ll assume we have a JavaScript library that provides a global function greet
and a global variable appName
.
.d.ts
FileCreate a file named externalLib.d.ts
with the following content:
// externalLib.d.ts
// Declare a global variable
declare var appName: string;
// Declare a global function
declare function greet(name: string): string;
Now, we can use the declared global entities in our TypeScript code:
// main.ts
console.log(`Welcome to ${appName}!`);
function welcomeUser(userName: string) {
console.log(greet(userName));
}
// Assuming appName and greet are defined in an external script
To get hands-on experience with ambient declarations, try the following exercise:
version
and a global function getVersion
..d.ts
file to declare these global entities.To better understand how ambient declarations fit into the TypeScript ecosystem, let’s visualize the process using a diagram.
flowchart TD A[JavaScript Library] -->|Defines| B[Global Variables/Functions] B -->|Ambient Declarations| C[.d.ts File] C -->|Type Information| D[TypeScript Code] D -->|Uses| B
Diagram Description: This flowchart illustrates how a JavaScript library defines global variables/functions, which are then described using ambient declarations in a .d.ts
file. The TypeScript code uses these declarations to access the globals with type safety.
To reinforce your understanding of ambient declarations, consider the following questions:
In this section, we’ve explored the concept of ambient declarations in TypeScript. We’ve learned how to use the declare
keyword to describe global entities, when ambient declarations are necessary, and how to structure them in .d.ts
files. Remember to use ambient declarations judiciously to avoid polluting the global namespace and to keep your TypeScript code organized and maintainable.