A continuación se muestra cómo estoy usando mi Badge de componente reutilizable hecha por mí. Tiene tipos de accesorios de la siguiente manera, pero esto da algún tipo de error como:
Aquí está el código completo,
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>; };¿Cómo se puede resolver esto de manera adecuada? Me gustaría saber todas las formas si podemos solucionarlo de múltiples formas.
Puede declarar variantsMap un poco diferente
const variantsMap: Record<string, "success" | "info" | "warning" | "error"> = ...Extraería eso en un nuevo tipo para facilitar la lectura.
type Variant = "success" | "info" | "warning" | "error"; const variantsMap: Record<string, Variant> = ... interface IBadgeProps { variant: Variant; children: string; }Una buena solución simple y limpia es usar as const :
const variantsMap = { done: "success", processing: "info", suspened: "warning", cancelled: "error", } as const; Ahora variantsMap se escribe como:
{ readonly done: "success"; // ... } lo que significa que acceder a las propiedades da como resultado tipos literales, no una string , que fue la causa del error.
Aquí hay una forma de hacerlo: TypeScript Playground
El código completo se ve así:
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>; };