microsoft / microsoft/TypeScript

Type inference lost after spreading array with `ArrayLike`

Abierto
#58,286 2 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Domain: check: Type Inference Help Wanted Possible Improvement
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
1 d 19 h
PR fusionados (30 d)
117

Descripción

🔎 Search Terms

array inference, type inference, ArrayLike, lodash compact, _.compact

🕗 Version & Regression Information
  • This changed between versions 4.9.5 and 5.0.4
⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.0.4#code/C4TwDgpgBAsiAq4IB55QgD2BAdgEwGcoBXHAaxwHsB3HAPigF4oBvAKCigFsQBpCEAC4o8ANwduIAGKkAxsACWlHMIAUAQwBOAcwCMw+AEomDAG6UFecQF9xbWcoLAo23BE3rsTKKsPCAgpoeIMhwiJDITpoKONp0DIwM7JyaEMDEmjhQgcEAdABmmpRcqixQADa42sAAFsIArFDWhrlc6mChCEiRwNGx8aqqAPoANFAxeJjGiawSKWkZWcmcKzz8QlAABgAkLBOY1psjc6vScorKalp600knK1Cp6ZniD5zWxw+2Es02dg44JxQLTBAAyCjIEAAkjh8u5cLIIDIcPIlFlmKh0FhcIQSOQqLQ6KoJCCAkF1CBwZDMQAfKA4YjlcpQOmkSb5GIQPAsqD5dTlAjQOkAImFPIADAw6QymTy2RAOTguWw-CIANoAXRMs3mzyymr+bHsjmcIIpVOhsPcqRR0GYZspEMtcJtiORqOUqjVEjKawEwmFugATABmYVjHjui4qHymfnECC3VjWJqfKC9BNQABkWdYknWAYALPUAGzhyRRtFqOPlBNJlgpj4SPkC6A5vN+jbC4tliNnFHR6vxxPahupiS5SeuJUebC+NMAegX6aQ4ytQQgiKglHyFfOaPGRHKlCcEgzbdzvr4-qg3dL5cj+8useH9cbaZbguzl-zN7vvb3AcqxfWsRxmMcm04K8C1vHsH37D0Y1UGs61Hd82A1Qx-hNYFyRAGEXQRJEn3RKBMUwbB8CIUgKBoehiU4Ulsjw2l6UZZlWXwBVOW5OlPyFW8xTpSUeRlDi8XZHiVQMTVRwkJ5FigA02G+Y1AVNPCCPhW1vAdLTXWIoDPW9KDfy7YMwz7Stn2Q180PHThz2-Dtry7OCrJIodQLfBzeX5L922gv93MAxCvNQ8D0M4SdcmndxPAgecJCXFdIDXF1Ui3HdQujQ8oEhMBgDPTRM0Csyi3vDyjKQlCwKSKK-NbZygrcyqcuA2zvPsyCXJg-94Osmq7Mi8dMPEIA

💻 Code
type MyType<T extends unknown> = {
  myKey: T;
  myFunction: (arg1: T) => void;
};

const generate = (): Array<MyType<string>> => {
  return Array.from({ length: 5 }).map<MyType<string>>((_, index) => {
    return {
      myKey: `${index}`,
      myFunction: (arg1) => {
        return;
      },
    };
  });
};

const arrayLikeInferenceFunction = <T extends unknown>(
  arr: ArrayLike<T | null | undefined | false | "" | 0> | null | undefined
): T[] => {
  return [];
};

const arrayLikeInference = arrayLikeInferenceFunction([
  { myKey: "123", myFunction: (value) => {} }, // value is correctly inferred as string
  true && { myKey: "456", myFunction: (value) => {} },
  false && { myKey: "456", myFunction: (value) => {} },
  ...generate(),
  // type inference of myFunction is lost
  true && { myKey: "456", myFunction: (value) => {} }, // value is inferred as any
  false && { myKey: "456", myFunction: (value) => {} },
  { myKey: "456", myFunction: (value) => {} },
]);

const arrayInferenceFunction = <T extends unknown>(
  arr: Array<T | null | undefined | false | "" | 0> | null | undefined
): T[] => {
  return [];
};

const arrayInference = arrayInferenceFunction([
  { myKey: "123", myFunction: (value) => {} }, // value is correctly inferred as string
  true && { myKey: "456", myFunction: (value) => {} },
  false && { myKey: "456", myFunction: (value) => {} },
  ...generate(),
  // type inference of myFunction is kept
  true && { myKey: "456", myFunction: (value) => {} }, // value is correctly inferred as string
  false && { myKey: "456", myFunction: (value) => {} },
  { myKey: "456", myFunction: (value) => {} },
]);
🙁 Actual behavior

The typings of the arguments of myFunction are lost after the array spread when using ArrayLike. When using Array, the type inference is kept.

🙂 Expected behavior

The arguments of myFunction should be inferred as string

Additional information about the issue

I have opened a similar issue in the DefinitelyTyped repository for the lodash typings and they suggested opening an issue in this repository. https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/69410

The issue originated from using lodash.compact() with code similar to the code below:

import _ from "lodash";

type MyType<T extends unknown> = {
  myKey: T;
  myFunction: (arg1: T) => void;
};

const generate = (): Array<MyType<string>> => {
  return Array.from({ length: 5 }).map<MyType<string>>((_, index) => {
    return {
      myKey: `${index}`,
      myFunction: (arg1) => {
        return;
      },
    };
  });
};

const lodashInferred = _.compact([
  { myKey: "123", myFunction: (value) => {} }, // infers value as string
  true && { myKey: "456", myFunction: (value) => {} },
  false && { myKey: "456", myFunction: (value) => {} },
  ...generate(),
  { myKey: "123", myFunction: (value) => {} },  // infers value as any
  true && { myKey: "456", myFunction: (value) => {} },
  false && { myKey: "456", myFunction: (value) => {} },
]);

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con la reproducción enlazada en Playground usando TypeScript 5.0.4 y compara los casos ArrayLike y Array en torno al spread de generate(). Traza el comportamiento de inferencia de tipos para los parámetros del callback; se considera terminado cuando los argumentos de myFunction se infieren como string después del spread de ArrayLike, con la regresión indicada cubierta por una prueba.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.