Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

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

オープン
#73 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
68/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
typescript
領域
tooling

調査の方向性

src/parsers/script-parser.ts の extractAttributes() から始め、parseAttributes() を経由して到達するこの処理で、test/utils.ts に記載されている方法で playcanvas 型を読み込んだ状態で 3 つのスニペットを再現します。隣接する ParsingError パスを追跡し、タプル型、空のオブジェクト初期化子、解決できない @type 参照について回帰テストを追加します。これらのケースで処理が中断したり暗黙的に消えたりせず、有効な属性が引き続き解析されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

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.

主要言語
TypeScript
スター
1
フォーク
3
PR マージ指標
30日以内にマージされた PR はありません

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

playcanvas/attribute-parser のほかの issue

playcanvas/attribute-parser の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。