Type expression

Literal types

  • Basics
  • Tested with TypeScript 5.9

A literal type allows exactly one value: the type "GET" accepts only the string "GET". On their own they are rarely useful; joined into a union, {"GET" | "POST" | "DELETE"}, they list every value a parameter may take, and TypeScript rejects anything else at the call site.

String, number and boolean literals all work, and editors offer the allowed strings as completions while you type the argument.

At a glance

Use JSDoc in a .js file TypeScript in a .ts file
String literals /** @param {"GET" | "POST"} method */ (method: "GET" | "POST")
Number literals /** @typedef {1 | 2 | 3 | 4 | 5} Stars */ type Stars = 1 | 2 | 3 | 4 | 5;
A boolean literal /** @param {true} verified */ (verified: true)

Examples

request.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: request.js(11,9): error TS2345: Argument of type '"PATCH"' is not assignable to parameter of type '"GET" | "POST" | "DELETE"'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. request.js(11,9): error TS2345: Argument of type '"PATCH"' is not assignable to parameter of type '"GET" | "POST" | "DELETE"'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. request.js(11,9): error TS2345: Argument of type '"PATCH"' is not assignable to parameter of type '"DELETE" | "GET" | "POST"'. checked 21 October 2026
/**
 * @param {"GET" | "POST" | "DELETE"} method
 * @param {string} url
 */
export function request(method, url) {
  return fetch(url, { method });
}

request("GET", "/api/cart");
request("PATCH", "/api/cart");error TS2345: Argument of type '"PATCH"' is not assignable to parameter of type '"GET" | "POST" | "DELETE"'.
A union of string literals as a parameter type.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
request.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: request.js(11,9): error TS2345: Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. request.js(11,9): error TS2345: Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. request.js(11,9): error TS2345: Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'. checked 21 October 2026
/** @param {"GET" | "POST"} method */
export function request(method) {
  return method;
}

const fixed = "GET";
request(fixed);

let changing = "GET";
request(changing);error TS2345: Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.

/** @type {"GET" | "POST"} */
let typed = "GET";
request(typed);

export { changing, typed };
A let holding a literal is widened to string.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
rating.js rating.ts Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: rating.js(13,12): error TS2345: Argument of type '6' is not assignable to parameter of type 'Stars'. rating.ts(9,12): error TS2345: Argument of type '6' is not assignable to parameter of type 'Stars'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. rating.js(13,12): error TS2345: Argument of type '6' is not assignable to parameter of type 'Stars'. rating.ts(9,12): error TS2345: Argument of type '6' is not assignable to parameter of type 'Stars'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. rating.js(13,12): error TS2345: Argument of type '6' is not assignable to parameter of type 'Stars'. rating.ts(9,12): error TS2345: Argument of type '6' is not assignable to parameter of type 'Stars'. checked 21 October 2026
/** @typedef {1 | 2 | 3 | 4 | 5} Stars */

/**
 * @param {Stars} stars
 * @param {true} verified only verified reviews are shown
 */
export function showReview(stars, verified) {
  return `${"★".repeat(stars)} ${verified ? "(verified)" : ""}`;
}

showReview(4, true);
showReview(6, true);error TS2345: Argument of type '6' is not assignable to parameter of type 'Stars'.
type Stars = 1 | 2 | 3 | 4 | 5;

export function showReview(stars: Stars, verified: true) {
  return `${"★".repeat(stars)} ${verified ? "(verified)" : ""}`;
}

showReview(4, true);
showReview(6, true);error TS2345: Argument of type '6' is not assignable to parameter of type 'Stars'.
Number and boolean literal types.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

When a value stops being a literal

TypeScript infers a literal type for a const (const fixed = "GET" is "GET"), but a let is widened to string, because it could be reassigned to any string. Passing that let to a parameter of type "GET" | "POST" fails with TS2345, as the second example shows.

Give the let the union type with @type, or use const. For object properties, which are widened the same way, a const assertion keeps the literals: /** @type {const} */ ({ method: "GET" }).

Naming a set of literals

Give a union of literals a name with @typedef when more than one function uses it: /** @typedef {"draft" | "live"} Status */. The name shows up in hovers and error messages, which reads better than the expanded union.

Gotchas

  • Literal types are checked only when TypeScript can see the value. Data from JSON or a form is a plain string until you check it against the allowed values.
  • Template literal types extend the idea to patterns of strings, such as every string that ends in px.

Questions

How do I restrict a JSDoc parameter to a few strings?

Write the allowed values as a union of string literals: @param {"small" | "medium" | "large"} size.

Sources

Last reviewed 20 October 2026.