Utilizando discriminating unions en las props de React con un valor por defecto.
Tengo un componente de React que tiene 3 variantes. Mis props están tipadas de la siguiente manera:
enum VariantType {
VARIANT_1 = "variant1",
VARIANT_2 = "variant2",
VARIANT_3 = "variant3",
}
type BaseProps = {
a: string;
}
type Variant1Props = BaseProps & {
variant: VariantType.VARIANT_1;
b: never;
}
type Variant2Props = BaseProps & {
variant: VariantType.VARIANT_2;
b: number;
}
type Variant3Props = BaseProps & {
variant: VariantType.VARIANT_3;
b: boolean;
}
export const FancyComponent: FunctionComponent<variant1props |="" variant2props="" |="" variant3props=""> = (props) => {
const someNumber = props.variant === VariantType.VARIANT_2 ? props.b : 123;
...
}
En la asignación de someNumber
, TS sabe que b
está definida porque verifiqué la variante. Cuando utilizo el componente, TS se queja cuando b
está presente cuando es VARIANT_1
y se queja cuando b
no está presente/no es un número cuando es VARIANT_2
(lo mismo para VARIANT_3
).
Lo que estoy buscando ahora es una forma de hacer que la opción variant
sea opcional cuando se utiliza el componente y que esta opción tenga un valor predeterminado de VARIANT_1
. Además, me gustaría poder establecerla en VARIANT_2
o VARIANT_3
sin perder la seguridad de tipos que tengo actualmente.
Intenté algunas cosas con genéricos y demás, pero no pude hacer que funcionara.
Estoy utilizando Typescript 4.5.
davy.ai
Para hacer opcional la opción
variant
y establecerla por defecto enVARIANT_1
, puedes modificar el tipoBaseProps
para incluir una propiedadvariant
opcional que tenga como valor por defectoVariantType.VARIANT_1
. Luego, puedes actualizar los tiposVariant1Props
,Variant2Props
yVariant3Props
para que extiendanBaseProps
en lugar deBaseProps & { variant: VariantType }
.Luego, en la definición de
FancyComponent
, puedes utilizar una unión discriminada con un caso por defecto para asegurar que TS conozca el tipo deprops.variant
y garantice el tipo correcto paraprops.b
.De esta manera, puedes utilizar
FancyComponent
tanto especificando como no especificando la propiedadvariant
, y seguir manteniendo la seguridad de tipos. Por ejemplo:Si intentas pasar un valor
variant
que no forma parte del enumVariantType
, TS lanzará un error, asegurando que tu código siga siendo seguro en cuanto a tipos.