Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

for-in rejects records that may be null or undefined

Cerrado
#2,403 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Ya se ha fusionado un pull request relacionado.

  • #2406 de @MathurAditya724 — cerrado sin fusionar
  • #2534 de @ctate — fusionado

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
25/100
Tipo de issue
Nueva funcionalidad
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
node.js, typescript
Área
compilers

Línea de trabajo

A pull request (#2406) already proposes a fix, so pick this up from that branch rather than starting fresh. Read lowerForIn in packages/compiler/src/frontend/lowering/lower-stmts.ts and note how it dispatches on the receiver's IR kind before reaching the unsupported-receiver branch that emits SC1052; the approach is to bind the receiver once, branch on the present record tag and reuse the existing typed record walk. Reproduce with the repro.ts snippet and node packages/cli/dist/main.js coverage repro.ts --print diagnostics, and check that coverage treats the loop as a runtime fence rather than a preflight error. Done means null and undefined iterate zero times, a side-effecting receiver evaluates once, and the listed regression cases (deletion during enumeration, labels, shared cursor bindings, per-iteration closures) pass with unchanged codegen for existing typed loops.

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

Descripción

We are trying to compile a complete Node.js CLI and its existing JavaScript dependencies with scriptc. One remaining language gap is a loop over an object that may be missing.

JavaScript allows for-in over null or undefined: the loop simply runs zero times. scriptc can already enumerate the object itself, but rejects a parameter whose type also allows either missing value.

Reproduction

Save as repro.ts:

function keys(value: { a: number } | null | undefined): string {
  let result = "";
  for (const key in value) result += key;
  return result;
}
console.log("[" + keys(null) + "] [" + keys(undefined) + "] [" + keys({ a: 1 }) + "]");

Node executes it successfully:

$ node repro.ts
[] [] [a]

After building the scriptc workspace, run:

node packages/cli/dist/main.js coverage repro.ts --print diagnostics

The loop reports:

SC1052: for-in over '{ a: number; } | null | undefined' receivers (records, index-signature shapes, arrays, and globalThis enumerate) are not supported yet

The same refusal occurs with { a: number } | null and { a: number } | undefined. Coverage can report this as a runtime fence rather than a preflight error, so a successful frontend result alone does not mean the loop will execute.

Expected behavior

Null and undefined should perform zero iterations. A present record should use the existing record enumeration behavior. The receiver expression must be evaluated exactly once, including when it returns a nullish value.

Where the boundary occurs

lowerForIn in packages/compiler/src/frontend/lowering/lower-stmts.ts dispatches directly on the receiver's IR kind. It handles records, arrays and checked-dynamic values, but a union with one record arm and only nullish alternatives reaches the unsupported-receiver branch.

A narrow fix can bind the receiver once, branch on the present record tag, then reuse the existing typed record walk. That would preserve live deletion checks, loop binding forms, labels and per-iteration captures without introducing new runtime semantics. Tuples and other unsupported union families can retain their current fences.

Scope and regression coverage

This reproduction uses an explicitly typed parameter. It does not depend on hoisted locals or widening a JavaScript binding after assignment, the neighboring work in #1907.

Useful regression cases include null/undefined no-ops, a side-effecting receiver expression, fixed and index-signature records, deletion/addition during enumeration, shared cursor bindings, labeled break/continue, and closures capturing each iteration's key. Existing typed loops should retain the same generated code.

Proposed fix and regression tests: #2406.

Tested environment

Reproduced with a source build from scriptc’s main development branch on macOS arm64, using Node 24.22.0 and matching native compiler/runtime packages. The source build reports version 0.4.5. The original gap was also checked against later main changes before opening the linked PR.

Source revision used for the reproduction.

Lenguaje dominante
TypeScript
Estrellas
6.4k
Forks
201
Merge medio
6 h 56 min
PR fusionados (30 d)
916

Preparar el entorno

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.

Más de vercel-labs/scriptc

Todos los issues de vercel-labs/scriptc

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.