Home > Enterprise >  Type 'string' is not assignable to type 'SOME TYPE', small confusion when passin
Type 'string' is not assignable to type 'SOME TYPE', small confusion when passin

Time:04-27

Below is how I am using my reusable component Badge made by me. It has types of props as follows but this gives some kind of error as:

enter image description here

Here is full code,

const variantsMap = {
  done: "success",
  processing: "info",
  suspened: "warning",
  cancelled: "error",
};

interface ITransactionProps {
  status: "done" | "processing" | "suspened" | "cancelled";
  label: string;
}

const MyComponent = ({ status, label }: ITransactionProps) => {
  return <Badge variant={variantsMap[status]}>{label}</Badge>;
};

interface IBadgeProps {
  variant: "success" | "info" | "warning" | "error";
  children: string;
}

const Badge = ({ variant, children }: IBadgeProps) => {
  return <div className={`badge bordered circular ${variant}`}>{children}</div>;
};

How can this be solved in proper way? I would like to know all the ways if we can solve it in multiple ways.

CodePudding user response:

You can declare variantsMap a bit differently

const variantsMap: Record<string, "success" | "info" | "warning" | "error"> = ...

I would extract that into a new type for readability.

type Variant = "success" | "info" | "warning" | "error";

const variantsMap: Record<string, Variant> = ...

interface IBadgeProps {
  variant: Variant;
  children: string;
}

CodePudding user response:

A nice simple and clean solution is to use as const:

const variantsMap = {
  done: "success",
  processing: "info",
  suspened: "warning",
  cancelled: "error",
} as const;

Now variantsMap is typed as:

{
    readonly done: "success";
    // ...
}

which means accessing properties results in literal types, not string which was the cause of the error.

CodePudding user response:

Here's one way to do it: TypeScript Playground

The full code looks like this:

import React from 'react';

type Variant = "done" | "processing" | "suspened" | "cancelled";

const variantsMap: Record<Variant, string> = {
  done: "success",
  processing: "info",
  suspened: "warning",
  cancelled: "error",
};

interface ITransactionProps {
  status: Variant;
  label: string;
}

const MyComponent = ({ status, label }: ITransactionProps) => {
  return <Badge variant={variantsMap[status]}>{label}</Badge>;
};

interface IBadgeProps {
  variant: string;
  children: JSX.Element | string;
}

const Badge = ({ variant, children }: IBadgeProps) => {
  return <div className={`badge bordered circular ${variant}`}>{children}</div>;
};
  • Related