Typecript no permite desestructurar propiedades no existentes con un valor predeterminado

CorePress2024-01-24  8

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

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare