Bridging the Gap: TypeScript's `declare` for External Variables and APIs
Here's an example of how to use declare
to provide type information for a global variable:
declare var $: JQuery;
$(document).ready(function() {
$("#message").text("Hello, world!");
});
In this example, we are telling the TypeScript compiler that a global variable named $
exists and that it has the type JQuery
. This allows us to use the jQuery library in our TypeScript code without getting compiler errors.
This example shows how to use declare
to provide type information for the jQuery library:
// This file is typically named jquery.d.ts (declaration file)
declare var $: JQuery;
interface JQuery {
(selector: string): JQuery;
ready(fn: () => void): void;
text(text: string): JQuery;
}
$(document).ready(function() {
$("#message").text("Hello, world with type checking!");
});
Explanation:
- We create a separate file named
jquery.d.ts
(convention for declaration files). - We use
declare var $: JQuery;
to tell the compiler that a global variable$
exists with the typeJQuery
. - We define an interface
JQuery
that describes the methods available on the jQuery object (selector
,ready
, andtext
). - In our main code, we use the
$
like normal, but now the compiler understands its type and can offer code completion and type checking for jQuery methods.
Using declare for a global variable:
This example shows how to use declare
for a global variable defined in another JavaScript file:
global.js:
// This file defines a global variable
window.myGlobalVar = "This is a global variable";
main.ts:
// This file uses the global variable
declare var myGlobalVar: string;
console.log(myGlobalVar); // This will print "This is a global variable"
- We define a global variable
myGlobalVar
inglobal.js
. - In
main.ts
, we usedeclare var myGlobalVar: string;
to tell the compiler that a global variable namedmyGlobalVar
exists and has the typestring
. - Now, we can access
myGlobalVar
in our TypeScript code without errors.
Using declare for DOM APIs:
This example shows how to use declare
for a DOM API (document.getElementById
):
function getElementById(id: string): HTMLElement {
return document.getElementById(id); // This line would normally cause an error
}
const button = getElementById("myButton");
if (button) {
button.addEventListener("click", handleClick);
}
function handleClick() {
console.log("Button clicked!");
}
- Normally, accessing
document.getElementById
in TypeScript would cause an error because the compiler doesn't know the type ofdocument
. - We use
declare
to provide type information for thedocument
object and its methods likegetElementById
. We can achieve this by including a reference to the DOM type definitions file provided by TypeScript. - Now, the compiler understands that
getElementById
returns anHTMLElement
, allowing us to use it safely and with type checking.
- You can use the
any
type to bypass type checking for a variable entirely.
let myLibrary: any;
// Assuming a library with a function doSomething()
myLibrary = window.myLibrary; // No type checking here
myLibrary.doSomething("Hello");
- This allows you to use the library without type safety.
- Drawbacks:
- Loses the benefit of type checking, which can lead to runtime errors.
- Doesn't provide code completion or intellisense for the library methods.
Type Casting (not recommended):
- You can cast a variable to a specific type, essentially telling the compiler to trust you that the variable has that type.
let someVar = window.myLibrary as MyLibraryType; // Assuming you have a MyLibraryType interface
someVar.doSomething("Hello");
- This allows you to use the library with some level of type safety based on your cast.
- Drawbacks:
- Can be error-prone if you cast to the wrong type.
- Doesn't provide the same level of clarity and maintainability as
declare
.
Remember:
declare
is generally the preferred approach for ambient declarations as it offers type safety without actual code generation and improves code clarity.- Use
any
or type casting with caution and only whendeclare
isn't suitable.
typescript typescript2.0