Skip to content

File altered by before transform does not remove new unused imports #17552

Closed

Description

Description of the bug:

When using a before transform that makes an import unused, the import will not be removed by TypeScript.

So if I have:

import { unused } from 'unused-module';
import { something } from 'some-module';
const value = something;

And replace const value = something with

import { somethingElse } from 'some-other-module';
const value = somethingElse;

The import { unused } from 'unused-module'; statement will be removed, but import { something } from 'some-module'; will remain:

import { something } from 'some-module';
import { somethingElse } from 'some-other-module';
const value = somethingElse;

TypeScript Version: 2.4.2

Code

import { unused } from 'unused-module';
import { something } from 'some-module';
const value = something;

Reproduction of this bug requires using the transforms API.

I have prepared a repository with a simple reproduction that runs this file: https://github.com/filipesilva/ts-transform-import-bug/blob/master/test.ts

git clone https://github.com/filipesilva/ts-transform-import-bug
cd ts-transform-decorator-bug
npm install
npm test

Expected behavior:
All unused imports are removed.

import { somethingElse } from 'some-other-module';
const value = somethingElse;

Actual behavior:
Only imports there were unused before the transformed are removed.

import { something } from 'some-module';
import { somethingElse } from 'some-other-module';
const value = somethingElse;

/cc Ron Buckton (@rbuckton)

Activity

  1. modified the milestones: , TypeScript 2.5 on Aug 16, 2017
  2. rbuckton commented on Aug 23, 2017

    @rbuckton
    Contributor

    Currently, whether or not an import is referenced is determined by the checker at check time, prior to emit. We do not re-bind or re-check the AST between transformations, so all check-time state will always be based on the originally parsed AST.

    The only way to elide an import in this case would be to have the "before" transformer explicitly elide the import. This is currently the intended behavior. We are considering ways of opening up the checker (and our internal EmitResolver) to custom transformations to allow more control, but that likely won't be ready in the 2.5 release timeframe.

  3. arciisine commented on Aug 26, 2017

    @arciisine

    I'm actually facing the inverse of this problem. Something is being marked as unused (and so the import is elided) but I would like that import to stay. Is there anyway to manage this without checking the entire file and adding the import back in (if it truly is unused)

  4. RyanCavanaugh commented on Aug 26, 2026

    @RyanCavanaugh
    Member

    This is not a compiler bug. In TypeScript 2.4.2, import usage is determined during checking, before before transformers run. A transformer can replace something with somethingElse, but that does not cause the checker to re-bind or re-check the transformed tree, so the original something import remains classified as used for emit.

    A before transformer that makes an import unused must explicitly remove that import as part of its transformation. Automatically rechecking arbitrary transformed ASTs during emit is not supported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: APIRelates to the public API for TypeScriptDomain: API: TransformsRelates to the public transform API

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions