# Ambients { #ambients } Ambient declarations are used to provide static typing over existing JavaScript code. Ambient declarations differ from regular declarations in that no JavaScript code is emitted for them. Instead of introducing new variables, functions, classes, enums, or namespaces, ambient declarations provide type information for entities that exist "ambiently" and are included in a program by external means, for example by referencing a JavaScript library in a <script/> tag. ## Ambient Declarations { #ambients-ambient-declarations } Ambient declarations are written using the `declare` keyword and can declare variables, functions, classes, enums, namespaces, or modules.   *AmbientDeclaration:*    `declare` *AmbientVariableDeclaration*    `declare` *AmbientFunctionDeclaration*    `declare` *AmbientClassDeclaration*    `declare` *AmbientEnumDeclaration*    `declare` *AmbientNamespaceDeclaration* ### Ambient Variable Declarations { #ambient-variable-declarations } An ambient variable declaration introduces a variable in the containing declaration space.   *AmbientVariableDeclaration:*    `var` *AmbientBindingList* `;`    `let` *AmbientBindingList* `;`    `const` *AmbientBindingList* `;`   *AmbientBindingList:*    *AmbientBinding*    *AmbientBindingList* `,` *AmbientBinding*   *AmbientBinding:*    *BindingIdentifier* *TypeAnnotationopt* An ambient variable declaration may optionally include a type annotation. If no type annotation is present, the variable is assumed to have type Any. An ambient variable declaration does not permit an initializer expression to be present. ### Ambient Function Declarations { #ambient-function-declarations } An ambient function declaration introduces a function in the containing declaration space.   *AmbientFunctionDeclaration:*    `function` *BindingIdentifier* *CallSignature* `;` Ambient functions may be overloaded by specifying multiple ambient function declarations with the same name, but it is an error to declare multiple overloads that are considered identical (section [#type-and-member-identity]) or differ only in their return types. Ambient function declarations cannot specify a function bodies and do not permit default parameter values. ### Ambient Class Declarations { #ambient-class-declarations } An ambient class declaration declares a class type and a constructor function in the containing declaration space.   *AmbientClassDeclaration:*    `class` *BindingIdentifier* *TypeParametersopt* *ClassHeritage* `{` *AmbientClassBody* `}`   *AmbientClassBody:*    *AmbientClassBodyElementsopt*   *AmbientClassBodyElements:*    *AmbientClassBodyElement*    *AmbientClassBodyElements* *AmbientClassBodyElement*   *AmbientClassBodyElement:*    *AmbientConstructorDeclaration*    *AmbientPropertyMemberDeclaration*    *IndexSignature*   *AmbientConstructorDeclaration:*    `constructor` `(` *ParameterListopt* `)` `;`   *AmbientPropertyMemberDeclaration:*    *AccessibilityModifieropt* `static`*opt* *PropertyName* *TypeAnnotationopt* `;`    *AccessibilityModifieropt* `static`*opt* *PropertyName* *CallSignature* `;` ### Ambient Enum Declarations { #ambient-enum-declarations } An ambient enum is grammatically equivalent to a non-ambient enum declaration.   *AmbientEnumDeclaration:*    *EnumDeclaration* Ambient enum declarations differ from non-ambient enum declarations in two ways: * In ambient enum declarations, all values specified in enum member declarations must be classified as constant enum expressions. * In ambient enum declarations that specify no `const` modifier, enum member declarations that omit a value are considered computed members (as opposed to having auto-incremented values assigned). Ambient enum declarations are otherwise processed in the same manner as non-ambient enum declarations. ### Ambient Namespace Declarations { #ambient-namespace-declarations } An ambient namespace declaration declares a namespace.   *AmbientNamespaceDeclaration:*    `namespace` *IdentifierPath* `{` *AmbientNamespaceBody* `}`   *AmbientNamespaceBody:*    *AmbientNamespaceElementsopt*   *AmbientNamespaceElements:*    *AmbientNamespaceElement*    *AmbientNamespaceElements* *AmbientNamespaceElement*   *AmbientNamespaceElement:*    `export`*opt* *AmbientVariableDeclaration*    `export`*opt* *AmbientLexicalDeclaration*    `export`*opt* *AmbientFunctionDeclaration*    `export`*opt* *AmbientClassDeclaration*    `export`*opt* *InterfaceDeclaration*    `export`*opt* *AmbientEnumDeclaration*    `export`*opt* *AmbientNamespaceDeclaration*    `export`*opt* *ImportAliasDeclaration* Except for *ImportAliasDeclarations*, *AmbientNamespaceElements* always declare exported entities regardless of whether they include the optional `export` modifier. ## Ambient Module Declarations { #ambient-module-declarations } An *AmbientModuleDeclaration* declares a module. This type of declaration is permitted only at the top level in a source file that contributes to the global namespace (section [#programs-and-source-files]). The *StringLiteral* must specify a top-level module name. Relative module names are not permitted.   *AmbientModuleDeclaration:*    `declare` `module` *StringLiteral* `{`  *DeclarationModule* `}` An *ImportRequireDeclaration* in an *AmbientModuleDeclaration* may reference other modules only through top-level module names. Relative module names are not permitted. If an ambient module declaration includes an export assignment, it is an error for any of the declarations within the module to specify an `export` modifier. If an ambient module declaration contains no export assignment, entities declared in the module are exported regardless of whether their declarations include the optional `export` modifier. Ambient modules are "open-ended" and ambient module declarations with the same string literal name contribute to a single module. For example, the following two declarations of a module 'io' might be located in separate source files. ```TypeScript declare module "io" { export function readFile(filename: string): string; } declare module "io" { export function writeFile(filename: string, data: string): void; } ``` This has the same effect as a single combined declaration: ```TypeScript declare module "io" { export function readFile(filename: string): string; export function writeFile(filename: string, data: string): void; } ```