error TS8006: 'interface' declarations can only be used in TypeScript files. is reported for interface, enum and namespace (or module) declarations in a .js file. The {0} in the message is the keyword.
An interface only describes a shape, so in JavaScript it becomes a @typedef. An enum also creates a value at run time, so it becomes a real object: a frozen object for the values, plus @enum or a union of string literals for the type.
At a glance
| Code | TS8006 |
|---|---|
| Message | '{0}' 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 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
interface LineItem {error TS8006: 'interface' declarations can only be used in TypeScript files.
sku: string;
quantity: number;
}
enum Status {error TS8006: 'enum' declarations can only be used in TypeScript files.
Pending,
Shipped,
}
export const placed = Status.Pending;jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} What causes it
- TypeScript declarations were pasted into a
.jsfile.
How to fix it
A @typedef for the shape, an object for the values
Write the interface as @typedef {object} LineItem with one @property per field. For the enum, export const Status = Object.freeze({ ... }) with /** @enum {string} */ gives a value you can import and a type for the members. A string literal union (@typedef {"pending" | "shipped"} Status) is often simpler when the values are only compared.
/**
* @typedef {object} LineItem
* @property {string} sku
* @property {number} quantity
*/
/** @enum {string} */
export const Status = Object.freeze({
Pending: "pending",
Shipped: "shipped",
});
/** @type {LineItem} */
export const item = { sku: "TEE-01", quantity: 2 };
export const placed = Status.Pending;jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Gotchas
@enumtypes each member as the type in its tag (stringhere), not as the literal value; use a union@typedefwhen you need the exact strings checked.- A namespace in JavaScript is just an object; see the @namespace page for what the checker reads.
Sources
- JSDoc Reference: @typedef, @callback, and @param · TypeScript handbook
- JSDoc Reference: @enum · TypeScript handbook
- diagnosticMessages.json (TypeScript 5.9.3) · TypeScript on GitHub
Last reviewed 20 October 2026.