Skip to content

imported symbol that is shadowed with a local symbol does not errorΒ #55584

Closed
@bradzacher

Description

@bradzacher

πŸ”Ž Search Terms

imported symbol shadowed

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play?isolatedModules=true#code/JYWwDg9gTgLgBAbzgYQuCA7Aph+BfOAMyjTgHIosBDAYxjIG44B6ZuAFQGU4soSoAznExwYAC2BCqQ4PSlwAblQA2AVywAoZVnip02XAC4UaSAfgAfOBlXLlcALzXbyhho2hIsRHABiyOAJiUgpqOkYWNi44FWUIAHchcUkYmTkY0QBPME1teH9jfzgrGztHZzs3IA

πŸ’» Code

import { Component } from 'react';
let Component: Component | null = null;

import { FC } from 'react';
let FC: FC | null = null;

πŸ™ Actual behavior

The first case correctly errors:

Import declaration conflicts with local declaration of 'Component'. (2440)

The second case is allowed, even under isolatedModules.

πŸ™‚ Expected behavior

Both cases should error

Additional information about the issue

Looking at this from two perspectives - isolatedModules: true and false

For isolatedModules: false - this looks like it's working as expected. In a fully type-aware build TS can tell that the local value symbol shadows an imported type symbol - which is valid - and it can handle it just fine and knows it 100% can elide the import.

However for isolatedModules: true - I'd expect that TS acts stricter here. Without type information it's not really safe to assume that the imported name is a type.

From TS's POV I believe that when it transpiles the code it sees the imported symbol is never used as a value (due to the local symbol), so it elides the import.
This accidentally makes the code runtime-valid so it won't crash.

I'm of the opinion here that TS should always error on this case or else it's possible to write some really cooked looking code like

import { FC } from 'react';
let FC: FC | null = null;
   FC = null;
// ^^ assigning to an import... but also not technically

Metadata

Metadata

Assignees

Labels

Breaking ChangeWould introduce errors in existing codeExperience EnhancementNoncontroversial enhancementsFix AvailableA PR has been opened for this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions