Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

211
Vistas
Type guard not working properly even though equivalent conditional type works

Consider the following declaration and uses of a conditional type:

type IsIterable<T> = T extends Iterable<infer X> ? Iterable<X> : never
export function isIterableAny(val: any): val is IsIterable<typeof val> {
    return hasValue(val) && typeof (val as any)[Symbol.iterator] === "function"
}
export function isIterableUnknown(val: unknown): val is IsIterable<typeof val> {
    return hasValue(val) && typeof (val as any)[Symbol.iterator] === "function"
}

const num = 1 // 1
const arr = [1, 2, 3] // number[]

type TestNumber = IsIterable<typeof num> // never
type TestArray = IsIterable<typeof arr> // Iterable<number>

if (isIterableAny(num)) { num /* 1 & Iterable<unknown> */ }
if (isIterableUnknown(num)) { num /* never */ }

if (isIterableAny(arr)) { arr /* number[] */ }
if (isIterableUnknown(arr)) { arr /* never */ }

Why do the results of the isIterable type guard not correspond to the results of the test types, even though they all use the same conditional type IsIterable?

I notice that the two versions of the type guard work and fail in different/complementary ways, but of course i need a single type guard that works for all inputs

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

type IsIterable<T> = T extends Iterable<infer X> ? Iterable<X> : never;

By using this, you're discarding all type information related to T other than its iterable attributes. Instead, you just need to exclude from the union T all members which don't extend the Iterable type:

TS Playground

export function isIterable<T>(value: T): value is T extends Iterable<any> ? T : never  {
  try { return typeof (value as any)[Symbol.iterator] === 'function'; }
  catch { return false; }
}

declare const num: 1;
isIterable(num) && num; // never

declare const arr: number[];
isIterable(arr) && arr; // number[]

declare const union: null | string[] | Generator<bigint> | Iterator<number> | Record<'a' | 'b', boolean>;
isIterable(union) && union; // string[] | Generator<bigint>
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda