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

Parser throws on tuple `@type` tags and `= {}` initializers, and silently drops unresolvable types

Abierto
#73 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
68/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
typescript
Área
tooling

Línea de trabajo

Comienza en src/parsers/script-parser.ts, en extractAttributes(), al que se llega a través de parseAttributes(), y reproduce los tres snippets con los tipos de playcanvas cargados tal como se describe en test/utils.ts. Sigue las rutas de ParsingError adyacentes y añade cobertura de regresión para los tipos tupla, los inicializadores de objetos vacíos y las referencias @type no resueltas. La tarea estará terminada cuando estos casos ya no provoquen una interrupción ni desaparezcan silenciosamente, y los atributos válidos sigan analizándose.

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

Descripción

Found while investigating a forum report about the Interface Attribute Arrays docs example (docs fix: playcanvas/developer-site#1200). Interface arrays themselves work correctly — these are three separate robustness problems I hit while narrowing it down.

All three reproduce on main (fa36853, v1.11.0) through parseAttributes(), with the playcanvas types loaded as in test/utils.ts. Each snippet below is a complete script file.

1. TypeError when @type is a tuple
import { Script } from 'playcanvas';

class GameLogic extends Script {
    static scriptName = 'gameLogic';

    /**
     * @attribute
     * @type {[number]}
     */
    values;
}

export { GameLogic };
TypeError: Cannot read properties of undefined (reading 'declarations')
    at ScriptParser.extractAttributes
    at JSDocParser.parseAttributes

src/parsers/script-parser.ts:497-498:

const symbol = type.aliasSymbol || type.symbol;
const typeNode = (symbol?.valueDeclaration || symbol.declarations?.[0]) as InternalNode;

A tuple type has no symbol, so symbol?.valueDeclaration is undefined and the second term dereferences undefined. symbol?.declarations?.[0] would fall through to the if (!typeNode) continue guard on the next line. Same for @type {[number, number]}.

2. TypeError when an attribute is initialized with an empty object literal
import { Script } from 'playcanvas';

class GameLogic extends Script {
    static scriptName = 'gameLogic';

    /**
     * @attribute
     */
    data = {};
}

export { GameLogic };
TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
    at Array.from (<anonymous>)
    at ScriptParser.extractAttributes
    at JSDocParser.parseAttributes

src/parsers/script-parser.ts:553-560:

const members: readonly ts.Node[] =
    typeNode.members ??
    typeNode.properties ??
    Array.from(type.symbol.members as unknown as Iterable<[string, ts.Symbol]>).map(
        (entry) => entry[1].declarations[0]
    ) ??
    [];

For = {} both typeNode.members and typeNode.properties are nullish and type.symbol.members is undefined, so Array.from throws. Note the trailing ?? [] can never catch this, since the throw happens while evaluating the operand. data = { x: 1 } is fine — only the empty literal hits it.

This also fires for a member of an /** @interface */ class, e.g. data = {}; inside class Enemy.

Why 1 and 2 matter

Both throw out of extractAttributes, so the consumer gets no attributes and no diagnostics for the whole file instead of one error on the offending member. A half-written type annotation is a normal intermediate state while typing in the Editor's code editor, so these are easy to hit. Reporting a ParsingError for the member (as the neighbouring paths do) would keep the rest of the script parsing.

3. An unresolvable @type is dropped silently
import { Script } from 'playcanvas';

class GameLogic extends Script {
    static scriptName = 'gameLogic';

    /**
     * @attribute
     * @type {Enemy[]}
     */
    enemies;
}

export { GameLogic };

With Enemy undefined (not declared, not imported, or a typo), parseAttributes() returns no attribute and no error; getAttributes() doesn't list the member either. Non-array @type {Enemy} behaves the same, as does @type {{}}.

The type resolves to TypeScript's error type, which has no symbol, so the if (!typeNode) continue at src/parsers/script-parser.ts:500 skips the member before any of the reporting paths below it run. An error type is detectable and could be reported with the existing "…" is not a valid attribute type message.

This is the one that makes a typo'd or missing Interface import hard to diagnose: the attribute just never appears in the Editor, with nothing in the editor's problem list to explain why.

Lenguaje dominante
TypeScript
Estrellas
1
Forks
2
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Aún no hemos revisado los archivos de configuración de este proyecto. Empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

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 playcanvas/attribute-parser

Todos los issues de playcanvas/attribute-parser

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.