Storybook: String literal types with React Typescript

Created on 5 Aug 2020  路  6Comments  路  Source: storybookjs/storybook

I want to use String literal types in my component and I want to able to select any of those strings in my story using Storybook.

The component can only receive 3 types of strings: LATER | IMMEDIATELY | FCFS

But, I have this error:

Type 'string' is not assignable to type '"LATER" | "INMEDIATELY" | "FCFS"'.ts(2322) index.tsx(4, 3): The expected type comes from property 'type' which is declared here on type 'IntrinsicAttributes & LotteryCardInterface & { children?: ReactNode; }'

Component:

interface LotteryCardInterface {
  type: 'LATER' | 'INMEDIATELY' | 'FCFS'
}

const LotteryCard: React.FC<LotteryCardInterface> = (props: LotteryCardInterface) => 
(<p>
    {props.type}
  </p>)

export default LotteryCard;

Story:

export default {
  title: 'organism|LotteryCard',
  component: LotteryCard,
  decorators: [withKnobs]
}

const label = 'type';
const options = {
  LATER: 'LATER',
  INMEDIATELY: 'INMEDIATELY',
  FCPS: 'FCPS',
};
const defaultValue = 'LATER';

export const Summary = () => {
  const value = radios(label, options, defaultValue);
  return (
    <LotteryCard
      type={value}
    />
  )
}

Any idea how to fix it?

Thanks

inactive question / support typescript

Most helpful comment

Sorry, kinda busy today so I don't have much time to explain, but this should look something like this:

To have a variable match a series of string in Typescript, you have to use enum.
The enum value can then be used directly in your code.

enum CardStatus {  // placeholder name
  LATER = "LATER",
  INMEDIATELY = "INMEDIATELY",
  FCFS = "FCFS",
}

interface LotteryCardInterface {
  type: CardStatus
}

const options = CardStatus
const defaultValue = CardStatus.LATER

export const Summary = () => {
  const value = radios(label, options, defaultValue);
  return (
    <LotteryCard
      type={value}
    />
)

I'm not sure what is the radio methods doing, so you might need to change it a bit, but this should probably works.

All 6 comments

const options = {
  LATER: 'LATER',
  INMEDIATELY: 'INMEDIATELY',
  FCPS: 'FCPS',
} : ;

The properties inside the object are instantiated as strings instead of LotteryCardInterface.
You'll need to define them as LotteryCardInterface.

Thanks for the advice. I still don't get 100% how can I do that?

Sorry, kinda busy today so I don't have much time to explain, but this should look something like this:

To have a variable match a series of string in Typescript, you have to use enum.
The enum value can then be used directly in your code.

enum CardStatus {  // placeholder name
  LATER = "LATER",
  INMEDIATELY = "INMEDIATELY",
  FCFS = "FCFS",
}

interface LotteryCardInterface {
  type: CardStatus
}

const options = CardStatus
const defaultValue = CardStatus.LATER

export const Summary = () => {
  const value = radios(label, options, defaultValue);
  return (
    <LotteryCard
      type={value}
    />
)

I'm not sure what is the radio methods doing, so you might need to change it a bit, but this should probably works.

thanks 馃槂, is working.

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

Was this page helpful?
0 / 5 - 0 ratings