TypeScript Keywords List: Reserved, Strict and Contextual

The TypeScript keywords list has 84 words in three groups: 36 reserved words you can never use as names, 9 strict-mode reserved words, and 39 contextual keywords like type and keyof that are only special in certain spots. Here’s the rule in one line:

const class = "Economy";   // error TS1389
const type = "admin";      // fine: contextual keyword

I pulled the three groups straight from the compiler’s own token ranges, then checked every word with TypeScript 7.0.2 and Node.js v22.22.2.

The full TypeScript keywords list

This file holds all 84 words. It also asks the JavaScript engine whether each one can be a variable name in strict code:

const reserved = ["break", "case", "catch", "class", "const", "continue", "debugger", "default",
  "delete", "do", "else", "enum", "export", "extends", "false", "finally", "for", "function", "if",
  "import", "in", "instanceof", "new", "null", "return", "super", "switch", "this", "throw", "true",
  "try", "typeof", "var", "void", "while", "with"];
const strictMode = ["implements", "interface", "let", "package", "private", "protected", "public",
  "static", "yield"];
const contextual = ["abstract", "accessor", "any", "as", "assert", "asserts", "async", "await",
  "bigint", "boolean", "constructor", "declare", "defer", "from", "get", "global", "infer",
  "intrinsic", "is", "keyof", "module", "namespace", "never", "number", "object", "of", "out",
  "override", "readonly", "require", "satisfies", "set", "string", "symbol", "type", "undefined",
  "unique", "unknown", "using"];

// Ask the JavaScript engine: can this word be a variable name in strict code?
function canBeVariable(word: string): boolean {
  try {
    new Function(`"use strict"; let ${word} = 1;`);
    return true;
  } catch {
    return false;
  }
}

for (const [group, words] of [["reserved", reserved], ["strict-mode", strictMode],
                              ["contextual", contextual]] as const) {
  const blocked = words.filter((w) => !canBeVariable(w)).length;
  console.log(`${group.padEnd(12)} ${String(words.length).padStart(2)} words, ${blocked} blocked as names`);
}
console.log("total:", reserved.length + strictMode.length + contextual.length);

Output:

reserved     36 words, 36 blocked as names
strict-mode   9 words, 9 blocked as names
contextual   39 words, 0 blocked as names
total: 84
Command Prompt output counting the TypeScript keywords list: 36 reserved, 9 strict-mode and 39 contextual keywords
Every reserved and strict-mode word is blocked; no contextual keyword is.

Most of the reserved words come from JavaScript. enum is reserved there too, even though only TypeScript uses it; see TypeScript enums for how it works.

Reserved words: never valid as names

Use one of the 36 reserved words as a variable or parameter and the compiler stops right there:

const class = "Economy";
function setPrice(new: number) {}

Output:

reserved_words.ts(1,7): error TS1389: 'class' is not allowed as a variable declaration name.
reserved_words.ts(1,13): error TS1005: '{' expected.
reserved_words.ts(2,19): error TS1359: Identifier expected. 'new' is a reserved word that cannot be used here.
reserved_words.ts(2,22): error TS1138: Parameter declaration expected.
TypeScript compiler errors TS1389 and TS1359 for reserved keywords class and new used as names
One bad name confuses the parser, so it reports follow-up errors on the same line.

Fix the first error and the rest usually vanish. The same goes for for, break and continue, which you’ll meet in the TypeScript for loop.

Strict-mode reserved words in TypeScript

implements, interface, let, package, private, protected, public, static and yield are only reserved in strict mode. Modules are always strict, and TypeScript 7 won’t let you switch it off:

let package = "Ground shipping";
const interface = "web";
export {};

Output:

strict_words.ts(1,5): error TS1214: Identifier expected. 'package' is a reserved word in strict mode. Modules are automatically in strict mode.
strict_words.ts(2,7): error TS1214: Identifier expected. 'interface' is a reserved word in strict mode. Modules are automatically in strict mode.
error TS5108: Option 'alwaysStrict=false' has been removed. Please remove it from your configuration.
TypeScript TS1214 error for strict-mode reserved words package and interface, and TS5108 for alwaysStrict false
TS1214 for both names, then TS5108: the alwaysStrict=false option has been removed.

So treat these nine exactly like reserved words. interface and implements drive classes and interfaces in TypeScript.

Contextual keywords you can still use as names

The other 39 only mean something in a specific position, such as type before an alias or of inside a loop. Elsewhere they’re ordinary identifiers, and any keyword works as a property name:

const type = "admin";
const of = 3;
const string = "Austin, TX";
const from = "Denver";

// Reserved words are fine as property names
const fare = { class: "Economy", new: true, default: 249.99 };
console.log(type, of, string, from);
console.log(fare.class, fare.new, fare.default.toFixed(2));

Output:

admin 3 Austin, TX Denver
Economy true 249.99

They’re blocked as type names, though, because they’d clash with built-in types:

type string = number;
interface any { id: number }
class number {}

Output:

type_names.ts(1,6): error TS2457: Type alias name cannot be 'string'.
type_names.ts(2,11): error TS2427: Interface name cannot be 'any'.
type_names.ts(3,7): error TS2414: Class name cannot be 'number'.

await is the one exception for variables: it’s reserved at a module’s top level (TS1262) and inside async functions.

What do the TypeScript-only keywords do?

KeywordsUsed for
type, interface, enum, namespace, declareDeclaring types and ambient code
any, unknown, never, number, string, boolean, bigint, symbol, objectBuilt-in types
keyof, infer, is, asserts, unique, readonlyType operators and predicates
as, satisfiesAssertions and checks on values
public, private, protected, abstract, override, accessorClass members
in, outVariance on generic type parameters

is builds the type guards you write for narrowing; I cover it in the is keyword in TypeScript. For as versus satisfies, read satisfies vs as in TypeScript.

You’ll also see keyof and readonly together all the time in mapped types in TypeScript.

TypeScript identifier rules

  • Start with a letter, _ or $; digits are allowed after that (2ndQuarter fails with TS1351).
  • No spaces or hyphens: firstName, not first-name.
  • Names are case-sensitive, so Class is a valid name while class isn’t.
  • Skip all reserved and strict-mode words; avoid shadowing undefined.

Once the keywords feel familiar, these type-system guides are a good next read:

Frequently asked questions

How many keywords does TypeScript have?

84: 36 reserved words, 9 strict-mode reserved words and 39 contextual keywords, matching the compiler’s own token list.

Is type a reserved word in TypeScript?

No. type is contextual, so const type = "admin" compiles. You can’t name a type alias string or any, though.

Can I use a keyword as an object property?

Yes. fare.class and { new: true } are valid because property names may be any keyword.

Why is let reserved in TypeScript?

let is reserved in strict mode, and TypeScript modules are always strict, so you get error TS1214.

What’s the difference between a reserved word and a contextual keyword?

A reserved word can never be an identifier. A contextual keyword is only special in one position and works as a normal name elsewhere.

Where are the JavaScript reserved words documented?

MDN keeps the full JavaScript keywords list that TypeScript builds on.