# @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.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

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

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

Every option, set to its default:

```toml 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" }],
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad {"count": 2} */}
```ts
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:

{/* good */}
```ts
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

| Option | Default | What it does |
| --- | --- | --- |
| `allowAny` | `true` | Allow `any`. |
| `allowArray` | `false` | Allow an array if its element type is allowed. |
| `allowBoolean` | `true` | Allow `boolean`. |
| `allowNever` | `false` | Allow `never`. |
| `allowNullish` | `true` | Allow `null` and `undefined`. |
| `allowNumber` | `true` | Allow `number` and `bigint`. |
| `allowRegExp` | `true` | Allow `RegExp`. |
| `allow` | `Error`, `URL`, `URLSearchParams` | Other 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`:

{/* bad {"options": [{"allowNullish": false}]} */}
```ts
function greet(name?: string) {
  return `Hello ${name}`;
}
```

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

{/* good {"options": [{"allowArray": true}]} */}
```ts
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" }]`:

{/* good {"options": [{"allow": [{"from": "file", "name": "Money"}]}]} */}
```ts
class Money {
  constructor(private cents: number) {}
  toString() {
    return `$${this.cents / 100}`;
  }
}

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