Home > Mobile >  NextJS How to solve "Type 'string' is not assignable to type '...' " e
NextJS How to solve "Type 'string' is not assignable to type '...' " e

Time:12-02

In my nextjs-app I have a Button component:

interface IButton {
   text: string
   theme: 'primary' | 'secondary'
   size: 'small' | 'medium' | 'large'
   onClick?: () => void
}

const Button = ({ theme, text, size, onClick }: IButton) => {
   return (
      <button
        onClick={onClick}
        className={cn(styles.btn, {
          [styles.primary]: theme === 'primary',
          [styles.secondary]: theme === 'secondary',
          [styles.medium]: size === 'small',
          [styles.small]: size === 'medium',
          [styles.large]: size === 'large',
        })}
      >
        {text}
      </button>
  )
}

export default Button

And I use it like this:

<Button text="Click me" theme="primary" size="large" onClick={clickHandler} />

When I try to do npm run build I get the error:

Type 'string' is not assignable to type '"primary" | "secondary"'.

Can someone help me out?

CodePudding user response:

The error message is telling you that the theme property of the Button component is being passed a string value that is not one of the two allowed values, which are "primary" and "secondary".

To fix this, you need to make sure that the theme property of the Button component is only being passed one of those two values. You can do this by either modifying the code that calls the Button component to only pass one of those two values, or by providing a default value for the theme property in the Button component itself.

Here's an example of how you could provide a default value for the theme property:

interface IButton {
   text: string
   theme: 'primary' | 'secondary'
   size: 'small' | 'medium' | 'large'
   onClick?: () => void
}

const Button = ({ theme = 'primary', text, size, onClick }: IButton) => {
   // The theme property now has a default value of 'primary'
   return (
      <button
        onClick={onClick}
        className={cn(styles.btn, {
          [styles.primary]: theme === 'primary',
          [styles.secondary]: theme === 'secondary',
          [styles.medium]: size === 'small',
          [styles.small]: size === 'medium',
          [styles.large]: size === 'large',
        })}
      >
        {text}
      </button>
  )
}

export default Button

With this change, the Button component will always have a theme property with a value of either "primary" or "secondary", so the error will no longer occur. You can still override the default value by passing a different value for the theme property when you call the Button component, but if you don't provide a value, the default value of "primary" will be used.

CodePudding user response:

You should use Enum like this:

enum ITheme {
  PRIMARY = 'primary',
  SECONDARY = 'secondary'
};

enum ISize {
  SMALL = 'small',
  MEDIUM = 'medium',
  LARGE = 'large'
};

interface IButton {
   text: string
   theme: ITheme.PRIMARY | ITheme.SECONDARY
   size: ISize.SMALL | ISize.MEDIUM | ISize.LARGE
   onClick?: () => void
}
  • Related