question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allowing duplicated identifiers on importing, but not duplicated declaration type.

See original GitHub issue

Suggestion

🔍 Search Terms

  • Duplicate Identifer
  • Typescript data type and instance name duplicate
  • React Typescript Component and type duplicate identifier

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn’t be a breaking change in existing TypeScript/JavaScript code
  • This wouldn’t change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript’s Design Goals.

⭐ Suggestion

Typescript allows duplicated identifier declarations in a single ts file, if duplicated identifiers have different declaration types. But it doesn’t work to import identifiers from multiple files even though you know each imported identifiers have different declaration types. Let’s allow import statement duplicate identifiers, but check whether duplicated identifiers have a same declaration or not.

📃 Motivating Example

// Page.ts
type Page = {
  id: string;
  ...
}

const Page: React.Component ... = () => { ... }

export default Page;  // Yes, this works.

But sometime we put types in one file, like types.ts, right?

// types.ts
export type Page = {
  id: string;
  ...
}

// Page.tsx
export const Page: React.Component<...> = (...) => { ... }

// App.tsx
import { Page } from './types.ts'; //<--- Duplicate identifier 'Page'. ts(2300)
import { Page } from './Page.tsx'; //<--- Duplicate identifier 'Page'. ts(2300)

const App = () => {
  const page: Page = {
    id: 'hello-world',
  };
  return <Page page={page}>;
}

Importing same name identifiers makes error ‘Duplicate identifier’, but with this suggestion, it allows it.

💻 Use Cases

What workarounds are you using in the meantime?

  • Importing types using import * as types from ‘…/types’ – I find that having types. makes it a bit messy, especially for more complicated components.
  • Importing just the conflicted types with an alias (import { Bookshelf as BookshelfType } from ‘…/types’) – This works in some places, but when I have a type I called BookshelfType that I want to import then it becomes a problem.
  • Giving all components the suffix Component or View (e.g. BookshelfComponent or BookshelfView)
  • Giving only problematic components the suffix Component or View – Component names would then be inconsistent.

Reference

What do you want to use this for?

Removing meaningless, long suffix like Data, Component, Info, etc to avoid identifier duplication.

What shortcomings exist with current approaches?

System should let programmer know that identifier they imported has same declaration types. I think it would be enough with new error message like Duplicate declaration.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:7
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
RyanCavanaughcommented, Nov 22, 2021
import { Page } from './types.ts';
import { Page } from './Page.tsx';

This is illegal JavaScript; depending on the import being removed is a really big code smell (Babel et all cannot handle this) and we would prefer people not be relying on this.

import type { Page } from "./types" // explicitly only import the type!
import { Page } from "./Page"

This is not illegal JS but:

  • The second Page might still bring along a type (e.g. if it’s a class), so this pattern is fragile at best. Changes to “./Page” that seem innocuous could break this file
  • Both import statements bring in the namespace meaning:
// Page.foo is ambiguous between the export from
// "./types" and the export from "./Page"
const t: Page.foo = ...
3reactions
tadhgmistercommented, Nov 21, 2021

I can’t imagine this being useful when both are regular import statements but at the same time I’m quite surprised this doesn’t work:

import type { Page } from "./types" // explicitly only import the type!
import { Page } from "./Page"

If Page.tsx only exports a value called Page typescript is still unhappy about multiple imports even though one is clearly only the type and the other is only a value.

That said, why are you putting your type declarations in a separate file anyway? If the Page type is related to the Page value then exporting them both in the same file is allowed and works as you’d expect.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Duplicate identifier error in TypeScript | bobbyhadz
If your file does not contain at least 1 import or export statement, it is considered a global legacy script, which is a...
Read more >
Duplicate identifier when declaring types with same name in ...
I have a simple TypeScript 'snippets' project, and I've run into an issue where multiple .ts ...
Read more >
no-duplicate-imports - ESLint - Pluggable JavaScript Linter
A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease.
Read more >
Importing: Avoiding duplicate records - Claris Community
The problem appears to be that the records are imported from files within a specified folder. I think I forgot to delete previous...
Read more >
How to resolve duplicate transactions – Help Center - Wave
This occurs because the transaction ID (a back-end identifier) is changing, even though the date, amount, and description (front-end identifiers) ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found