Skip to content

feat(eslint-plugin): [no-useless-template-literals] rename to no-useless-template-expression (deprecate no-useless-template-literals) #8821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6 changes: 3 additions & 3 deletions packages/eslint-plugin/docs/rules/no-throw-literal.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ This rule restricts what can be thrown as an exception.

:::warning
This rule is being renamed to [`only-throw-error`](./only-throw-error.mdx).
When it was first created, it only prevented literals from being thrown (hence the name), but it has now been expanded to only allow expressions which have a possibility of being an `Error` object.
With the `allowThrowingAny` and `allowThrowingUnknown` options, it can be configured to only allow throwing values which are guaranteed to be an instance of `Error`.
The current name, `no-throw-literal`, will be removed in a future major version of typescript-eslint.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this PR changes multiple rules, maybe we should also change its title?
(so it'll also be squashed with the proper commit message)

or maybe split tp multiple PRs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comes out of #8821 (comment).
I think it makes sense to include in this change set since it's such a small (and related) change.


The current name `no-throw-literal` will be removed in a future major version of typescript-eslint.
When it was first created, this rule only prevented literals from being thrown (hence the name), but it has now been expanded to only allow expressions which have a possibility of being an `Error` object.
With the `allowThrowingAny` and `allowThrowingUnknown` options, it can be configured to only allow throwing values which are guaranteed to be an instance of `Error`.
:::

{/* Intentionally Omitted: When Not To Use It */}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
description: 'Disallow unnecessary template expressions.'
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/no-useless-template-expression** for documentation.

This rule reports template literals that contain substitution expressions (also variously referred to as embedded expressions or string interpolations) that are unnecessary and can be simplified.

:::info[Migration from `no-useless-template-literals`]

This rule was formerly known as [`no-useless-template-literals`](./no-useless-template-literals.mdx).
We encourage users to migrate to the new name, `no-useless-template-expression`, as the old name will be removed in a future major version of typescript-eslint.

The new name is a drop-in replacement with identical functionality.

:::

## Examples

<Tabs>
<TabItem value="❌ Incorrect">

```ts
// Static values can be incorporated into the surrounding template.

const ab1 = `${'a'}${'b'}`;
const ab2 = `a${'b'}`;

const stringWithNumber = `${'1 + 1 = '}${2}`;

const stringWithBoolean = `${'true is '}${true}`;

// Some simple expressions that are already strings
// can be rewritten without a template at all.

const text = 'a';
const wrappedText = `${text}`;

declare const intersectionWithString: string & { _brand: 'test-brand' };
const wrappedIntersection = `${intersectionWithString}`;
```

</TabItem>
<TabItem value="✅ Correct">

```ts
// Static values can be incorporated into the surrounding template.

const ab1 = `ab`;
const ab2 = `ab`;

const stringWithNumber = `1 + 1 = 2`;

const stringWithBoolean = `true is true`;

// Some simple expressions that are already strings
// can be rewritten without a template at all.

const text = 'a';
const wrappedText = text;

declare const intersectionWithString: string & { _brand: 'test-brand' };
const wrappedIntersection = intersectionWithString;
```

</TabItem>
</Tabs>

:::info
This rule does not aim to flag template literals without substitution expressions that could have been written as an ordinary string.
That is to say, this rule will not help you turn `` `this` `` into `"this"`.
If you are looking for such a rule, you can configure the [`@stylistic/ts/quotes`](https://eslint.style/rules/ts/quotes) rule to do this.
:::
Comment on lines +74 to +78
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like it!


## When Not To Use It

When you want to allow string expressions inside template literals.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, it's not only for strings, it's also for other literals such as numbers, booleans, null, etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, true. That part of the PR is just unchanged code moved from the existing page, though. See on main:

## When Not To Use It
When you want to allow string expressions inside template literals.

I don't feel strongly about it, so I would prefer not to bother changing it in this PR 🙃. Feel free to submit a separate PR to change that line if you like! 🙂


## Related To

- [`restrict-template-expressions`](./restrict-template-expressions.mdx)
- [`@stylistic/ts/quotes`](https://eslint.style/rules/ts/quotes)
58 changes: 10 additions & 48 deletions packages/eslint-plugin/docs/rules/no-useless-template-literals.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: 'Disallow unnecessary template literals.'
description: 'Disallow unnecessary template expressions.'
---

import Tabs from '@theme/Tabs';
Expand All @@ -9,53 +9,15 @@ import TabItem from '@theme/TabItem';
>
> See **https://typescript-eslint.io/rules/no-useless-template-literals** for documentation.

This rule reports template literals that can be simplified to a normal string literal.
This rule reports template literals that contain substitution expressions (also variously referred to as embedded expressions or string interpolations) that are unnecessary and can be simplified.

## Examples
:::warning
This rule is being renamed to [`no-useless-template-expression`](./no-useless-template-expression.mdx).
The current name, `no-useless-template-literals`, will be removed in a future major version of typescript-eslint.

<Tabs>
<TabItem value="❌ Incorrect">
After the creation of this rule, it was realized that the name `no-useless-template-literals` could be misleading, seeing as this rule only targets template literals with substitution expressions.
In particular, it does _not_ aim to flag useless template literals that look like `` `this` `` and could be simplified to `"this"`.
If you are looking for such a rule, you can configure the [`@stylistic/ts/quotes`](https://eslint.style/rules/ts/quotes) rule to do this.
:::

```ts
const ab1 = `${'a'}${'b'}`;
const ab2 = `a${'b'}`;

const stringWithNumber = `${'1 + 1 = '}${2}`;

const stringWithBoolean = `${'true is '}${true}`;

const text = 'a';
const wrappedText = `${text}`;

declare const intersectionWithString: string & { _brand: 'test-brand' };
const wrappedIntersection = `${intersectionWithString}`;
```

</TabItem>
<TabItem value="✅ Correct">

```ts
const ab1 = 'ab';
const ab2 = 'ab';

const stringWithNumber = `1 + 1 = 2`;

const stringWithBoolean = `true is true`;

const text = 'a';
const wrappedText = text;

declare const intersectionWithString: string & { _brand: 'test-brand' };
const wrappedIntersection = intersectionWithString;
```

</TabItem>
</Tabs>

## When Not To Use It

When you want to allow string expressions inside template literals.

## Related To

- [`restrict-template-expressions`](./restrict-template-expressions.mdx)
{/* Intentionally Omitted: When Not To Use It */}
9 changes: 9 additions & 0 deletions packages/eslint-plugin/docs/rules/only-throw-error.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ The fundamental benefit of `Error` objects is that they automatically keep track

This rule restricts what can be thrown as an exception.

:::info[Migration from `no-throw-literal`]

This rule was formerly known as [`no-throw-literal`](./no-throw-literal.mdx).
We encourage users to migrate to the new name, `only-throw-error`, as the old name will be removed in a future major version of typescript-eslint.

The new name is a drop-in replacement with identical functionality.

:::

## Examples

This rule is aimed at maintaining consistency when throwing exception by disallowing to throw literals and other expressions which cannot possibly be an `Error` object.
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/configs/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export = {
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-useless-empty-export': 'error',
'@typescript-eslint/no-useless-template-literals': 'error',
'@typescript-eslint/no-useless-template-expression': 'error',
'@typescript-eslint/no-var-requires': 'error',
'@typescript-eslint/non-nullable-type-assertion-style': 'error',
'no-throw-literal': 'off',
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/configs/disable-type-checked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export = {
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-unary-minus': 'off',
'@typescript-eslint/no-useless-template-expression': 'off',
'@typescript-eslint/no-useless-template-literals': 'off',
'@typescript-eslint/non-nullable-type-assertion-style': 'off',
'@typescript-eslint/only-throw-error': 'off',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export = {
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
'@typescript-eslint/no-useless-template-literals': 'error',
'@typescript-eslint/no-useless-template-expression': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
'@typescript-eslint/prefer-includes': 'error',
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/configs/strict-type-checked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export = {
'@typescript-eslint/no-unused-vars': 'error',
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 'error',
'@typescript-eslint/no-useless-template-literals': 'error',
'@typescript-eslint/no-useless-template-expression': 'error',
'@typescript-eslint/no-var-requires': 'error',
'no-throw-literal': 'off',
'@typescript-eslint/only-throw-error': 'error',
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ import noUnusedVars from './no-unused-vars';
import noUseBeforeDefine from './no-use-before-define';
import noUselessConstructor from './no-useless-constructor';
import noUselessEmptyExport from './no-useless-empty-export';
import noUselessTemplateExpression from './no-useless-template-expression';
import noUselessTemplateLiterals from './no-useless-template-literals';
import noVarRequires from './no-var-requires';
import nonNullableTypeAssertionStyle from './non-nullable-type-assertion-style';
Expand Down Expand Up @@ -242,6 +243,7 @@ export default {
'no-use-before-define': noUseBeforeDefine,
'no-useless-constructor': noUselessConstructor,
'no-useless-empty-export': noUselessEmptyExport,
'no-useless-template-expression': noUselessTemplateExpression,
'no-useless-template-literals': noUselessTemplateLiterals,
'no-var-requires': noVarRequires,
'non-nullable-type-assertion-style': nonNullableTypeAssertionStyle,
Expand Down
Loading
Loading