Avoid duplicate identifier between objects and interfaces in TypeScript

Viewed 1731

I'm currently working on a React project using TypeScript and I come across a very stupid problem and on top of that very annoying...

For example I create a dummy component called Page that need a page of type Page as props:

interface Props {
  page: Page
}

export interface Page {
  id: number
  category: PageCategory
  path: string
  name: string
}

const Page: React.FunctionComponent<Props> = (props) => {
  ...
  return (
    ...
    <h1>{ props.page.name }<h1/>
    ...


export default Page

So far no problem but they're coming as soon as I decide to import the component with the type:

import Page, { Page } from './component/Page'  // ts-error: 'Duplicate identifier 'Page''

So in order to avoid this problem I added the prefix I to all my interfaces like IPage but I'm sure there's a more elegant way to do it. How do you handle that?

3 Answers

Your solution is close. Just use the same export "style" for both objects, so that you can import them together. Page will be an alias for both the Value and the Type.

./component/Page.ts

interface Page { ... }
const Page: ...

export default Page

./App.ts

import Page from './component/Page'

const pageData: Page = { id: ... }
const pageComponent = Page 

The main problem is because you have same name for your interface and component and you're both exporting it.

The easiest solution would be to rename your interface/type. Just add the word Props to it for it to still make sense (or any postfix you like)

interface Props {
  page: PageProps
}

export interface PageProps {
  id: number
  category: PageCategory
  path: string
  name: string
}

const Page: React.FunctionComponent<Props> = (props) => {
  ...
  return (
    ...
    <h1>{ props.page.name }<h1/>
    ...


export default Page

So wont have problem in importing it like this

import Page, { PageProps } from './component/Page'

you can do it using a namespace, but it will add a layer of complexity.

Create Types.ts file

export namespace Types {
    export interface Page {
         id: number
         category: PageCategory
         path: string
         name: string
     }
}

and use it with Types.Page.

for example

const getName = (page: Types.Page) : string = page.name
Related