error TS2304: Cannot find name 'gtag'. is reported when code uses a name that is not declared anywhere the checker can see: not in the file, not imported, not a global from the libraries the config loads. When a declared name is close in spelling, the checker reports TS2552 with a suggestion instead.
In a JavaScript project the name usually exists at run time but comes from outside the code: an analytics or map library loaded with a <script> tag, a constant a bundler substitutes (__APP_VERSION__), or a global from a runtime whose types are not installed.
At a glance
| Code | TS2304 |
|---|---|
| Message | Cannot find name '{0}'. |
| TypeScript's category | error |
| Listed under | Unknown names and members |
| Turned on by | No option: every checked file reports it |
| In .js files | Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file |
The message is TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} is filled in by tsc for each error.
What it looks like
export function trackCheckout() {
gtag("event", "begin_checkout");error TS2304: Cannot find name 'gtag'.
}
export const version = __APP_VERSION__;error TS2304: Cannot find name '__APP_VERSION__'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} What causes it
- A page script or a bundler provides the global, and nothing tells the checker it exists.
- The global belongs to a runtime or library whose types the config does not load. For Node.js names such as
processandBufferthe checker says so with TS2580 or TS2591, and forconsoleanddocumentwith TS2584. - The name is defined in a file that is not part of the program (outside
include).
How to fix it
Declare the globals in a .d.ts file
Create a file such as globals.d.ts with a declare line for each global, typed as precisely as you like, and make sure include matches it. A declaration file holds types only, so it adds nothing to your JavaScript at run time.
export function trackCheckout() {
gtag("event", "begin_checkout");
}
export const version = __APP_VERSION__;jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js", "*.d.ts"]
} Or install the library's types
If the global comes from a library with published types, install them (for example @types/google.maps) and, if your config has a types list, add the package to it. For a few well-known libraries the checker suggests the package itself: $ without jQuery's types is reported as TS2581 (TS2592 when the config has a types list), and both name @types/jquery.
A JSDoc-only alternative
If you would rather not add a .d.ts file, read the global through globalThis or window with a cast: const gtag = /** @type {(...args: unknown[]) => void} */ (/** @type {any} */ (window).gtag);. It works, but it has to be repeated in every file, which is why the declaration file is the usual answer.
Gotchas
- A
.d.tsfile only counts when the program includes it. With"include": ["src/**/*.js"]asrc/globals.d.tsis not matched; add"src/**/*.d.ts"or list the file. - With
skipLibCheckon (thejsconfig.jsondefault), mistakes inside your own.d.tsfiles are not reported, so keep the declarations simple.
Sources
- Declaration Reference: Global Variables · TypeScript handbook
- Type Checking JavaScript Files · TypeScript handbook
- diagnosticMessages.json (TypeScript 5.9.3) · TypeScript on GitHub
Last reviewed 20 October 2026.