Skip to content

New rule: disallow empty named blocks #2538

@bradzacher

Description

@bradzacher

Spinning this off of our discussion here #2473 (comment)

According to the ES6 spec an empty named import block import {} from 'mod' is valid syntax:

NamedImports :
    { }
    { ImportsList }
    { ImportsList , }

Because it's valid - all ESLint parsers allow it for value imports.

Parsers that handle type-only imports (flow/hermes/typescript/babel) also allow an empty named import block: import type {} from 'mod', (flow only) import typeof {} from 'mod'.

I suggest we build a new rule, no-empty-named-blocks, which bans these empty import blocks entirely.

Examples

✅ Valid

import 'mod';

import Default from 'mod';
import { Named } from 'mod';
import Default, { Named } from 'mod';
import * as Namespace from 'mod';

import type Default from 'mod';
import type { Named } from 'mod';
import type Default, { Named } from 'mod'; // note - invalid TS but valid Flow
import type * as Namespace from 'mod';     // note - valid TS but invalid Flow

// flow only
import typeof Default from 'mod';
import typeof { Named } from 'mod';
import typeof Default, { Named } from 'mod';

❌ Invalid

import {} from 'mod';
import Default, {} from 'mod';

import type {} from 'mod';
import type Default, {} from 'mod'; // note - invalid TS but valid Flow

// flow only
import typeof {} from 'mod';
import typeof Default, {} from 'mod';

Fixer

There are 3 cases for us to consider here:

First, an import with a default and an empty named block (either value, type, or typeof).
This can always be safely fixed to remove the empty block:

- import Default, {} from 'mod';
+ import Default from 'mod';

// flow only
- import type Default, {} from 'mod';
+ import type Default from 'mod';

// flow only
- import typeof Default, {} from 'mod';
+ import typeof Default from 'mod';

Second, a type-/typeof-only import with just an empty named block.
This can always be removed in its entirety as type-/typeof-only imports never have side-effects

- import type {} from 'mod';
+ 

Finally a value import with just an empty block.
This cannot be safely deleted because even without any specifiers the import will still trigger side-effects. Instead of an autofixer, we can use a suggestion fixer with two suggestions:

  1. Delete the import (fix by deleting the entire statement)
    - import {} from 'mod';
    + 
  2. Convert to a side-effect import (fix by deleting the {} from)
    - import {} from 'mod';
    + import 'mod';

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions