Tengo un proyecto de reacción iniciado con Typescript y recibo el siguiente error
Type 'string' is not assignable to type 'Color | undefined'.
Cuando tengo algo así...
const foo = {stuff:"success"} <MuiAlert onClose={handleSnackbarClose} severity={foo.stuff} > Words </MuiAlert>Sin embargo, el código funciona bien si const foo es una cadena...
const foo = "success" <MuiAlert onClose={handleSnackbarClose} severity={foo} > Words </MuiAlert>¿Hay alguna diferencia entre invocar una variable que es una cadena e invocar una cadena que está dentro de un objeto?
Los tipos subyacentes se manejan de manera diferente en los ejemplos que compartió. Con más detalle:
const foo = "success" El tipo de foo ahora es literalmente "success" . Typescript sabe que se configuró en "success" y que, debido a que es una constante, nunca cambiará.
Sin embargo, esto:
const foo = { stuff: "success"} ... se resuelve en el tipo {stuff: string} . Typescript sabe que es un objeto con la clave "cosas", pero debido a que los objetos son mutables, no sabe que bar.stuff siempre será "success" . Se recurre al tipo string más genérico.
El error que está recibiendo, entonces, se debe a que el tipo de Color que definió en algún lugar acepta el valor "success" , pero no acepta ninguna cadena. Entonces, el primer ejemplo es aceptable para el compilador, pero no sabe que el segundo debe ajustarse al mismo conjunto de valores.
Una alternativa sería hacer algo como esto:
const foo: {stuff: Color} = {stuff: "success"} De esa manera, Typescript sabrá que el campo de stuff de foo siempre será Color . Como beneficio adicional, obtiene autocompletar cuando comienza a escribir la cadena que almacenará en foo.stuff .
Esto se debe a que la gravedad se escribe como un Literal Type en MUI.
Definieron la severidad para aceptar solo una unión de varias cadenas.
El problema con su código se describe en el manual de TypeScript en Inferencia literal .
foo.stuff es solo de tipo cadena y no un tipo literal de 'éxito', pero si asigna foo al valor directamente, puede representar tanto el tipo de cadena como el tipo literal 'éxito', que es lo que acepta la propiedad de gravedad.
O más genérico: foo es constante, pero foo.stuff no lo es. foo.stuff puede cambiar en cualquier momento y ya no contener el valor que acaba de asignarle. Como no escribiste foo explícitamente, cualquier valor de cadena es aceptable para foo.stuff, no solo la cadena literal que acabas de asignar.