@typescript-eslint/restrict-template-expressions

Disallow values in template literals that do not turn into a useful string

needs types

Also called typescript-eslint/restrict-template-expressions, typescript/restrict-template-expressions

A template literal turns whatever you put in ${} into a string. A plain object becomes "[object Object]", a promise becomes "[object Promise]", and a function becomes its source code. These end up in log lines, URLs, and messages shown to users.

By default strings, numbers, bigints, booleans, null, undefined, any, regular expressions, Error, URL, and URLSearchParams are allowed. Tagged templates aren't checked.

bun lint --type-aware turns this rule on in TypeScript files.

Configure#

Off by default. This rule needs types, so turning it on makes bun lint type check your code first.

bunfig.toml
[lint.rules]
"@typescript-eslint/restrict-template-expressions" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"@typescript-eslint/restrict-template-expressions" = ["error", {
  allowAny = true,
  allowArray = false,
  allowBoolean = true,
  allowNever = false,
  allowNullish = true,
  allowNumber = true,
  allowRegExp = true,
  allow = [{ name = ["Error", "URL", "URLSearchParams"], from = "lib" }],
}]

Examples#

example.ts2 problems
async function loadName(): Promise<string> {
  return "Ada";
}

const user = { name: "Ada" };
console.log(`Hello ${user}`); // Hello [object Object]
console.log(`Hello ${loadName()}`); // Hello [object Promise]
example.tsNo problems
async function loadName(): Promise<string> {
  return "Ada";
}

const user = { name: "Ada" };
console.log(`Hello ${user.name}`);
console.log(`Hello ${await loadName()}`);
console.log(`Open ${new URL("https://bun.com")}`);

Options#

OptionDefaultWhat it does
allowAnytrueAllow any.
allowArrayfalseAllow an array if its element type is allowed.
allowBooleantrueAllow boolean.
allowNeverfalseAllow never.
allowNullishtrueAllow null and undefined.
allowNumbertrueAllow number and bigint.
allowRegExptrueAllow RegExp.
allowError, URL, URLSearchParamsOther types to allow. Your list replaces the default one.

null and undefined print as the words "null" and "undefined", which is rarely what a user should see. Reported with allowNullish: false:

example.tswith { "allowNullish": false }1 problem
function greet(name?: string) {
  return `Hello ${name}`;
}

An array is joined with commas and no spaces. Not reported with allowArray: true:

example.tswith { "allowArray": true }No problems
const tags = ["a", "b"];
console.log(`Tags: ${tags}`); // Tags: a,b

Each allow entry is a name, or an object that also says where the type comes from: "lib" for TypeScript's built-in types, "file" for your own code, "package" for an npm package. Not reported with allow: [{ "from": "file", "name": "Money" }]:

example.tswith { "allow": [{ "from": "file", "name": "Money" }] }No problems
class Money {
  constructor(private cents: number) {}
  toString() {
    return `$${this.cents / 100}`;
  }
}

console.log(`Total: ${new Money(1250)}`);