0

I try to find a way to avoid racking my brains to think out a name without breaking elegant with suffix or prefix to diff declaration and component name.

I'm inspired by this linkAvoid duplicate identifier between objects and interfaces in TypeScript to use declaration merging. But it seems everything just mess up after merging. It neither detects type nor value.

Sample files:


//Player.tsx
interface Player {
  id: number
  name: string
  status: string
  avatar: string
}

const Player: React.FC<Player> = ({name, status, avatar}) => (
  <div className="flex">
    <span className="block w-20 h-20 rounded-full bg-green-200">{avatar}</span>
    <span className="pl-5 flex flex-col justify-center">
      <p className="text-lg">{name}</p>
      <p>{status}</p>
    </span>
  </div>
)

export default Player

In this way, I got error:

//ListPlayer.tsx
import Player from './Player';

export interface Props {
  items: Player[]  //'Player' refers to a value, but is being used as a type here. Did you mean 'typeof Player'?
}
const ListPlayer: React.FC<Props> = ({ items }) => (
  <>
    {items.map((item) => (
      <Player {...item} />
    ))}
  </>
);
export default ListPlayer;

If I use typeof, upper error will be fixed but, got another error:

//ListPlayer.tsx
import Player from './Player';

export interface Props {
   items: typeof Player[]
}
const ListPlayer: React.FC<Props> = ({ items }) => (
  <>
    {items.map((item) => (
      <Player {...item} /> //Type '{ propTypes?: WeakValidationMap<Player> | undefined; contextTypes?: ValidationMap<any> | undefined; defaultProps?: Partial<Player> | undefined; displayName?: string | undefined; }' is missing the following properties from type 'Player': id, name, status, avatarts(2739)
    ))}
  </>
);
export default ListPlayer;

I wonder what's the problem in my codes?

June Wenston
  • 124
  • 10

1 Answers1

1

You confuses items props with Player component.

Define PlayerProps interface and export it:

import React from 'react'
export interface PlayerProps {
  id: number
  name: string
  status: string
  avatar: string
}

const Player: React.FC<PlayerProps> = ({name, status, avatar}) => (
  <div className="flex">
    <span className="block w-20 h-20 rounded-full bg-green-200">{avatar}</span>
    <span className="pl-5 flex flex-col justify-center">
      <p className="text-lg">{name}</p>
      <p>{status}</p>
    </span>
  </div>
)

export default Player

For ListPlayer you should define props using interface PlayerPros like so:

import React from 'react'
import Player, {PlayerProps} from './Player';

export interface Props {
  items: PlayerProps[]
}
const ListPlayer: React.FC<Props> = ({ items }) => (
  <>
    {items.map((item) => (
      <Player {...item} />
    ))}
  </>
);
export default ListPlayer;
  • Your way works and I do adapt this way in my project.However, I'm not sure whether you read the link I post (I edit my question to stress that link) which give me an idea to avoid struggle in naming the component and declaration. Unluckily I failed. I want to know any chance I can make it? – June Wenston Feb 19 '21 at 09:01