Home > Mobile >  Typescript/React - Multiple types for one prop not working
Typescript/React - Multiple types for one prop not working

Time:08-15

I have the following types defined. CurrencyStat and ScoreStat extend Stat.

export interface Stat {
  value: number;
  change?: number;
}

type Currency = "USD" | "RMB";

export interface CurrencyStat extends Stat {
  currency: Currency;
}

export interface ScoreStat extends Stat {
 outof: number;
}

Now I am trying to define a component StatDisplay, to display the stat regardless of which Stat type it is. I am getting the following error: Property 'currency' does not exist on type 'Stat | CurrencyStat'. Property 'currency' does not exist on type 'Stat'.ts(2339), even though I am using a union type on the prop stat.

I was these [reading typescript docs][1] that say "If we have a value that is a union type, we can only access members that are common to all types in the union." This explains why a union type might not work here, but now I am having trouble finding a way to make this work.

I know that it would be possible to delete CurrencyStat and just add currency as an optional property on Stat, but there will be more stat types later on and I would like to have them separate if possible.

import { CurrencyStat, ScoreStat, Stat } from "../../../../types/types";
export const StatDisplay = ({
  label,
  stat,
}: {
  label: string;
  stat: Stat | CurrencyStat;
}) => {
  return (
    <div className="flex flex-col items-center">
      <div className="flex items-center">
        <div className="">{stat?.currency}</div>
        <div className="text-2xl font-semibold">{stat.value}</div>
      </div>
      <div className="">{label}</div>
    </div>
  );
};

CodePudding user response:

CurrencyStat already implements the Stat interface since you're extending it with it.

To fix your issue, all you need to do is change your component function params stat variable to be either just CurrenyStat or Stat & Partial<CurrencyStat>

The Partial means that you can pass an object with Stat keys but CurrencyStat aren't guarenteed.

Here's example:

export const StatDisplay = ({
  label,
  stat,
}: {
  label: string;
  stat: Stat & Partial<CurrencyStat>;
}) => { ... }
  • Related