error TS8010: Type annotations can only be used in TypeScript files. is reported for every : Type annotation in a .js file: on parameters, return types, variables and class fields. TS8004 is the same for a type parameter list (function first<T>(...)). The code would also fail to run, because JavaScript has no such syntax; Node.js's type stripping only applies to .ts files.
This is what happens when code is copied from a TypeScript project or an answer written for one. Every annotation has a JSDoc spelling, and the checker treats them the same way: @param and @returns for functions, @type for variables, @template for type parameters.
At a glance
| Code | TS8010 |
|---|---|
| Message | Type annotations can only be used in TypeScript files. |
Also on this page: TS8004 | Type parameter declarations can only be used in TypeScript files. |
| TypeScript's category | error |
| Listed under | JavaScript files only |
| 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 messages are TypeScript's own text from its diagnostic messages file (Apache-2.0).
What it looks like
export function cartTotal(prices: number[]): number {error TS8010: Type annotations can only be used in TypeScript files.error TS8010: Type annotations can only be used in TypeScript files.
return prices.reduce((sum, price) => sum + price, 0);
}
export let itemCount: number = 0;error TS8010: Type annotations can only be used in TypeScript files.
export function first<T>(items: T[]): T | undefined {error TS8004: Type parameter declarations can only be used in TypeScript files.error TS8010: Type annotations can only be used in TypeScript files.error TS8010: Type annotations can only be used in TypeScript files.
return items[0];
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} What causes it
- TypeScript code was pasted into a
.jsfile, or a.tsfile was renamed to.js. - The editor is not misconfigured: it checks a
.jsfile as JavaScript, as it should, so the TypeScript syntax is what has to change.
How to fix it
Write the same types in JSDoc
Move each annotation into a comment: @param {number[]} prices and @returns {number} above the function, /** @type {number} */ above the variable, @template T for the type parameter. The fixed example's TypeScript tab shows the original next to it.
/**
* @param {number[]} prices
* @returns {number}
*/
export function cartTotal(prices) {
return prices.reduce((sum, price) => sum + price, 0);
}
/** @type {number} */
export let itemCount = 0;
/**
* @template T
* @param {T[]} items
* @returns {T | undefined}
*/
export function first(items) {
return items[0];
}export function cartTotal(prices: number[]): number {
return prices.reduce((sum, price) => sum + price, 0);
}
export let itemCount: number = 0;
export function first<T>(items: T[]): T | undefined {
return items[0];
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Or make the file TypeScript
If the project is meant to have .ts files, rename the file and make sure a tsconfig.json includes it. A JavaScript project that wants types without a build step keeps .js and JSDoc.
Gotchas
- Other TypeScript-only syntax has its own codes in the same family:
asis TS8016,!is TS8013,interfaceandenumare TS8006,type X =is TS8008,privateandreadonlyare TS8009, parameter properties are TS8012. - A definite assignment annotation (
let total!: number) is TS8010 too; in JSDoc, initialize the variable instead.
Sources
- JSDoc Reference · TypeScript handbook
- Type Checking JavaScript Files · TypeScript handbook
- diagnosticMessages.json (TypeScript 5.9.3) · TypeScript on GitHub
Last reviewed 20 October 2026.