Búsqueda de sitios web

typescript - Función con genérico devuelve un tipo IterableIterator<> extraño


Tengo un tipo

type Fruit = {
    name: string;
    color: string;
};

y datos que contienen frutas que pueden tener dos formatos ligeramente diferentes. El primero es

const fruits: Fruit[] = [
    {
        name: "Banana",
        color: "yellow",
    },
    {
        name: "Apple",
        color: "green",
    },
];

y el segundo es

const fruits2: { entries: Fruit[] } = {
    entries: [
        {
            name: "Banana",
            color: "yellow",
        },
        {
            name: "Apple",
            color: "green",
        },
    ],
};

Me gustaría crear una función que reciba un objeto en cualquiera de estos dos formatos y lo devuelva en el primer formato. En otras palabras:

  1. Si la función recibe fruit, simplemente debería devolver lo que se pasó.
  2. Si la función recibe fruit2 debería "eliminar" las entradas de la clave y devolver una lista con tipo Fruit[]

Aquí está mi intento:

function maybeConvertToFormatOne<T extends object>(data: T | { entries: T }): T {
    return "entries" in data ? data.entries : data;
}

const converted = maybeConvertToFormatOne(fruits);
// Expected type: Fruit[]
// Actual type: () => IterableIterator<[number, Fruit]>

const converted2 = maybeConvertToFormatOne(fruits2);
// Expected type: Fruit[]
// Actual type: Fruit[]

¿De dónde proviene este tipo () => IterableIterator<[number, Fruit]> y cómo puedo solucionarlo?

Respuesta #1

Esto está funcionando para mí:

function maybeConvertToFormatOne<T>(data: T[] | { entries: T[] }) {
    if (Array.isArray(data)) {
      return data as T[];
    } else {
      return (data as { entries: T }).entries as T[];
    }
  }

Debes decir que tu T es un arreglo.

Respuesta #2

Porque Array.prototype.entries() en realidad existe.

Escribe de esta manera en su lugar.

function maybeConvertToFormatOne(data: Fruit[] | { entries: Fruit[] }): Fruit[] {
    return Array.isArray(data) ? data : data.entries;
}

No veo el sentido de usar genéricos aquí, pero puedes cambiarlo de nuevo si lo necesitas.