One of the confusing part of TypeScript is a file behave differently depends if you use the import
, export
syntax in the file.
For example, take the following example in my previous TIL:
ts
declare global {interface Array<T> {fly: () => void;}}
ts
declare global {interface Array<T> {fly: () => void;}}
If there is any export
/import
in the file, that snippet could correctly define a fly
method on Array.prototype
correctly.
However, if you remove the export
statement, suddenly it doesn’t work.
Why?
The problem is when you have an export
/import
statement, TypeScript treat it as a module, else it will be treated as a script.
Script
What is a script in this context?
A script in TypeScript means a file that is supposed to be compiled to a .js
file to be included in a page with a script
tag.
Therefore, variables and declaration in script are global by default, just like any .js
file included with a script
tag.
Which is why, the declare global
in previous snippet need to be removed if your file doesn’t have any export
/import
statement. As script are already global, declare global
doesn’t make sense any more so TypeScript just ignore it.
Module
What is a module?
In some language a module means a package that consists of multiple classes and utilities.
In JavaScript/TypeScript world, a module is just a file that manage its own dependencies and exported members. It specifies its dependencies using the import
keyword while declare its exported members using the export
keyword. Every time you write in any JavaScript/TypeScript file with import React from 'react'
, you’re writing a module.
Since module integrates with others using export
and import
, the variable declared in a module is local by default. (In you want to access global variables (e.g. variable in window
object), you’re encouraged to state it explicitly, e.g. window.jQuery
.)
This is why to overwrite global interface or namespace, you need to add declare global
.