Allowing duplicated identifiers on importing, but not duplicated declaration type.
See original GitHub issueSuggestion
đ 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
- https://www.reddit.com/r/reactjs/comments/kto2ll/conventions_for_react_component_naming_when/
- https://www.reddit.com/r/reactjs/comments/hxseh3/naming_convention_for_data_type_vs_component/
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:
- Created 2 years ago
- Reactions:7
- Comments:5 (1 by maintainers)
Top GitHub Comments
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.
This is not illegal JS but:
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 fileI 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:
If
Page.tsx
only exports a value calledPage
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 thePage
value then exporting them both in the same file is allowed and works as youâd expect.