Typescript: El verificador de tipos pierde el tipo de entrada de

Creado en 8 nov. 2016  ·  3Comentarios  ·  Fuente: microsoft/TypeScript

Versión de TypeScript: 2.0.8

Código

// test.ts
interface Type {
  type: number;
}

interface TypeExt extends Type {
  arr: Type[];
}

const guard = (arg: Type): arg is TypeExt => arg.type === 1;
const otherFunc = (arg1: Type, arg2: TypeExt): void => {};

export function y(arg: Type): void {
  if (guard(arg)) {
    for (const ITEM/* error is here */ of arg.arr) {
      if (otherFunc(ITEM, arg)) {
      }
    }
  }
}

Compilado con cmd: tsc --noImplicitAny test.ts

Comportamiento esperado:
Sin errores

Comportamiento real:

test.ts(14,16): error TS7022: 'ITEM' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
Bug Fixed

Comentario más útil

Este es un problema de análisis de flujo de control. Para inferir un tipo para ITEM necesitamos averiguar el tipo de flujo de control de arg.arr . Eso, a su vez, significa que debemos mirar las construcciones que afectan el tipo de arg . Esto incluye la llamada a otherFunc que parece que _ podría_ ser un predicado de tipo definido por el usuario. Para determinar si _es_ un predicado de tipo, resolvemos la expresión de llamada, lo que implica resolver las expresiones de argumento, lo que nos obliga a conocer el tipo de ITEM . Esto crea una circularidad que no podemos resolver, por lo que recurrimos a un tipo any implícito.

Podemos solucionar esto haciendo que la lógica de reconocimiento de predicados de tipo resuelva primero el tipo del objeto de función y examine todas las firmas de llamadas. Si ninguno de ellos son predicados de tipo definidos por el usuario, podemos rescatarnos antes sin resolver las expresiones del argumento de la llamada, lo que evita la circularidad.

Mientras tanto, puede romper la circularidad simplemente agregando paréntesis a arg en la llamada a otherFunc . En otras palabras, cambie la llamada a otherFunc(ITEM, (arg)) . Esto hace que el analizador de flujo de control ya no considere la llamada como una posible invocación de predicado de tipo definido por el usuario.

Todos 3 comentarios

Este es un problema de análisis de flujo de control. Para inferir un tipo para ITEM necesitamos averiguar el tipo de flujo de control de arg.arr . Eso, a su vez, significa que debemos mirar las construcciones que afectan el tipo de arg . Esto incluye la llamada a otherFunc que parece que _ podría_ ser un predicado de tipo definido por el usuario. Para determinar si _es_ un predicado de tipo, resolvemos la expresión de llamada, lo que implica resolver las expresiones de argumento, lo que nos obliga a conocer el tipo de ITEM . Esto crea una circularidad que no podemos resolver, por lo que recurrimos a un tipo any implícito.

Podemos solucionar esto haciendo que la lógica de reconocimiento de predicados de tipo resuelva primero el tipo del objeto de función y examine todas las firmas de llamadas. Si ninguno de ellos son predicados de tipo definidos por el usuario, podemos rescatarnos antes sin resolver las expresiones del argumento de la llamada, lo que evita la circularidad.

Mientras tanto, puede romper la circularidad simplemente agregando paréntesis a arg en la llamada a otherFunc . En otras palabras, cambie la llamada a otherFunc(ITEM, (arg)) . Esto hace que el analizador de flujo de control ya no considere la llamada como una posible invocación de predicado de tipo definido por el usuario.

@ahejlsberg
Gracias por la solución alternativa entre paréntesis.
Quiero resolver esto. Las relaciones públicas son aceptables, ¿no?

@arusakov ¡Arregle ahora en maestro!

¿Fue útil esta página
0 / 5 - 0 calificaciones