Búsqueda de sitios web

Tipado de TypeScript para la propagación de Array como Objeto


Estoy expandiendo un Array en un objeto para extender algunas propiedades... el problema que estoy encontrando es básicamente el siguiente:

const arr = [1, 2]
const obj = {...arr};

// TypeScript fails to catch this error
obj.forEach(v => console.log(v))

Enlace del parque

El obj resultante contendrá las claves del arreglo, por ejemplo, '0', '1', y cualquier otra propiedad enumerable del arreglo (por ejemplo, un arreglo RegExp.prototype.exec tendría propiedades enumerables adicionales index e input)

TypeScript todavía verá el objeto obj como un Array, y intellisense/auto-complete pensará que todos los métodos del Array, como forEach, todavía están disponibles. ¿Hay alguna manera de hacer esto seguro en cuanto a tipos?

Un caso de uso del mundo real:

export const matchAll = (re: RegExp, str: string): Array<any> => {
  const matches = [];
  let match: RegExpExecArray | null;
  let lastIndex = 0;
  while ((match = re.exec(str))) {
    matches.push({...match, lastIndex});
    lastIndex = re.lastIndex;
  }
  
  // the implicit type of `matches` items will have a lot of 
  // methods that are not accessible
  return matches;
};

Respuesta #1

¿Puede ser que precisar el tipo sea una solución en su caso?

Como esto: Enlace al patio de juegos

const arr = [1, 2];
const obj : Object = {...arr};

Respuesta #2

La propagación solo clonará propiedades que no existan en el prototipo. Desafortunadamente, TypeScript no lo ve de esta manera.

Sugiero anotar obj por lo que realmente es.

const obj: Record<number, number> = { ...arr };

También puedes hacer la conversión explícita abstraiéndola en una función.

function toObject<T>(arr: T[]): Record<number, T> {
    return { ...arr };
}