Skip to content
NewBun 1.4.5 is out. Release notes
AphrodyBun

Linter · Rules

@typescript-eslint/restrict-template-expressions

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

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

Reported:

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]

Not reported:

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:

function greet(name?: string) {
  return `Hello ${name}`;
}

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

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" }]:

class Money {
  constructor(private cents: number) {}
  toString() {
    return `$${this.cents / 100}`;
  }
}

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