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:
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>;
};