Tengo dos tipos, uno que contiene una propiedad llamada monto y otro que no.
Quiero desestructurar esa propiedad de uno u otro proporcionando un valor predeterminado en caso de que no exista (el tipo que no lo contiene).
Este es un código JS válido, sin embargo, Typecript se queja de que dicha propiedad no existe en uno de los tipos, lo cual es correcto, pero para eso está el valor predeterminado.
Aquí está el código:
interface A {
amount: number;
name: string;
}
type notA = {
name: string
}
const values = new Map<string, A>()
values.set('test', {name: 'test', amount: 0})
const defaultValue = {name: 'no-test'}
const { amount = 0 } = values.get('tust') || defaultValue
console.log(name, amount)
Entiendo que Typecript intenta protegerme de que dicha propiedad exista con un tipo incorrecto, pero, para empezar, eso no debería ser posible.
Probablemente esto se deba a que el mecanografiado no tiene tipos exactos y permitirá adjuntar accesorios adicionales a tipos que no los definen. Entonces, ¿cómo puedo hacer lo anterior?¿Has compilado?
busque "guardias tipo" typescriptlang.org/docs/handbook/advanced-types.html
- alquitrán
27/03/2021 a las 15:54
------------------------------------
Me inclinaría mucho a refactorizar algo como lo siguiente:
const { amount } = values.get('tust') || { name: "no-test", amount: 0 };
ya que su intención es presumiblemente que debería haber un valor predeterminado de tipo A, especialmente si va a utilizar 0 como valor predeterminado para la cantidadt propiedad.
Pero, asumiendo que no puedes cambiarlo, sugiero darle a defaultValue un tipo anotado explícitamente. Cuando dejas que el compilador infiera su tipo, se convierte en {nombre: cadena}. Este tipo es correcto hasta donde llega, pero no implica nada en absoluto sobre la propiedad de cantidad (como observará, los tipos de objetos en TypeScript no son exactos). Si desea que el compilador comprenda que a defaultValue le puede faltar una propiedad de cantidad, debe anotarla como tal tipo. Por ejemplo:
interface MaybeA {
amount?: number;
name: string;
}
const defaultValue: MaybeA = { name: 'no-test' }
He declarado una interfaz MaybeA que es una versión más amplia de A donde la propiedad cantidad es opcional, por lo que su tipo es número o indefinido. Esto entonces funcionará como se desea:
const { amount = 0 } = values.get('tust') || defaultValue // no error
También podrías escribir el tipo NotA al que definitivamente le falta la cantidad adecuadatipo:
interface NotA {
amount?: undefined;
name: string;
}
const defaultValue: NotA = { name: 'no-test' }
const { amount = 0 } = values.get('tust') || defaultValue // also okay
Y, por supuesto, nada requiere que le des nombres a estos tipos, especialmente si solo los usas una vez:
const defaultValue: { name: string, amount?: undefined } = { name: 'no-test' }
const { amount = 0 } = values.get('tust') || defaultValue // okay
Enlace al código del patio de recreo
------------------------------------
Existen múltiples formas de abordar esta situación. Aquí tienes una forma rápida
const defaultValue = { name: 'no-test' } as A
Consultar enlace: Zona de juegos mecanografiada