error TS7034: Variable 'tags' implicitly has type 'any[]' in some locations where its type cannot be determined. is reported on a declaration such as let tags = []; or let config;, and TS7005 (Variable 'tags' implicitly has an 'any[]' type.) on the places that read it.
The checker can usually follow such a variable: after tags.push("a") in the same function it knows tags holds strings. It loses track when the variable is captured by another function (a callback, an arrow function) or exported, because it cannot know when that other code runs. Then the variable is any, and noImplicitAny reports it.
At a glance
| Code | TS7034 |
|---|---|
| Message | Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined. |
Also on this page: TS7005 | Variable '{0}' implicitly has an '{1}' type. |
| TypeScript's category | error |
| Listed under | Implicit any |
| Turned on by | noImplicitAny, strict |
| In .js files | Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file |
The messages are TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} and {1} are filled in by tsc for each error.
What it looks like
export function collectTags() {
let tags = [];error TS7034: Variable 'tags' implicitly has type 'any[]' in some locations where its type cannot be determined.
const add = (/** @type {string} */ tag) => tags.push(tag);
add("sale");
return tags;error TS7005: Variable 'tags' implicitly has an 'any[]' type.
}
export let lastError;error TS7005: Variable 'lastError' implicitly has an 'any' type.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} What causes it
- A variable is declared with
[],null,undefinedor no value, and it is used inside a nested function or exported (export let lastError;is reported on its own as TS7005). noImplicitAnyis on (part ofstrict).
How to fix it
Annotate the variable
/** @type {string[]} */ above let tags = [];, or /** @type {Error | undefined} */ above export let lastError;. The annotation fixes the declaration and every TS7005 that came from it.
export function collectTags() {
/** @type {string[]} */
let tags = [];
const add = (/** @type {string} */ tag) => tags.push(tag);
add("sale");
return tags;
}
/** @type {Error | undefined} */
export let lastError;jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Gotchas
- Without a closure the same
let list = []; list.push("a"); return list;passes: the checker follows the pushes and typeslistasstring[]. - An empty array assigned to a class field reports TS7008 instead.
Sources
- Type Checking JavaScript Files: null, undefined, and empty array initializers are of type any or any[] · TypeScript handbook
- TSConfig Reference: noImplicitAny · TypeScript
- diagnosticMessages.json (TypeScript 5.9.3) · TypeScript on GitHub
Last reviewed 20 October 2026.