Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

Type after `as` or `satisfies` at end of line is tokenized as an expression

Offen
#1,079 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
68/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
typescript
Bereich
tooling

Rechercherichtung

Start with TypeScript.YAML-tmLanguage around lines 1755-1761 and line 62, then run repro.mjs with the listed vscode-textmate and vscode-oniguruma versions. Compare scopes for the inline and multiline as and satisfies examples; done means the next-line type receives the same type scopes without breaking the semicolonless single-line case.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

When a line ends with as or satisfies, the type on the next line gets expression scopes instead of type scopes.

JavaScript and TypeScript Nightly version: not tested in the extension. Reproduced with TypeScript.tmLanguage at eeeb0dc4daa8793b8227bb3b34ddfc267c85fd81 (current master), vscode-textmate 9.3.2, vscode-oniguruma 2.0.1, Node 26.7.0, macOS arm64.

Code

const a = b as A | undefined

const a = b as
  A | undefined

const a = b satisfies
  A | undefined

Prettier 3.9.8 emits this layout when an as expression exceeds the print width, e.g.:

const inlineSourceMap = convertSourceMap.fromSource(content)?.toObject() as
  SourceMap | undefined

Actual

Token Same line Next line
A entity.name.type.ts variable.other.constant.ts
| keyword.operator.type.ts keyword.operator.bitwise.ts
undefined support.type.builtin.ts constant.language.undefined.ts

A type on the line after satisfies gets the same scopes as a type on the line after as.

Expected

The same scopes on both layouts, because TypeScript parses both as a type assertion with the type A | undefined.

Repro script
npm install [email protected] [email protected]
curl -sLO https://raw.githubusercontent.com/microsoft/TypeScript-TmLanguage/eeeb0dc4daa8793b8227bb3b34ddfc267c85fd81/TypeScript.tmLanguage
node repro.mjs
// repro.mjs
import { readFileSync } from "node:fs";
import { createRequire } from "node:module";
import vsctm from "vscode-textmate";
import oniguruma from "vscode-oniguruma";

const require = createRequire(import.meta.url);
await oniguruma.loadWASM(
  readFileSync(require.resolve("vscode-oniguruma/release/onig.wasm")).buffer,
);
const registry = new vsctm.Registry({
  onigLib: Promise.resolve({
    createOnigScanner: (patterns) => new oniguruma.OnigScanner(patterns),
    createOnigString: (s) => new oniguruma.OnigString(s),
  }),
  loadGrammar: async () =>
    vsctm.parseRawGrammar(
      readFileSync("TypeScript.tmLanguage", "utf8"),
      "TypeScript.tmLanguage",
    ),
});
const grammar = await registry.loadGrammar("source.ts");

const tokenize = (code) => {
  let state = vsctm.INITIAL;
  for (const line of code.split("\n")) {
    const { tokens, ruleStack } = grammar.tokenizeLine(line, state);
    state = ruleStack;
    for (const { startIndex, endIndex, scopes } of tokens) {
      const text = line.slice(startIndex, endIndex);
      if (text.trim())
        console.log(JSON.stringify(text).padEnd(10), scopes.at(-1));
    }
  }
  console.log();
};

tokenize("const a = b as A | undefined");
tokenize("const a = b as\n  A | undefined");
tokenize("const a = b satisfies\n  A | undefined");

Possible cause (unverified)

The as/satisfies rule's end includes $ through lookAheadEndOfType, so the type ends at the line break right after the keyword:

https://github.com/microsoft/TypeScript-TmLanguage/blob/eeeb0dc4daa8793b8227bb3b34ddfc267c85fd81/TypeScript.YAML-tmLanguage#L1755-L1761
https://github.com/microsoft/TypeScript-TmLanguage/blob/eeeb0dc4daa8793b8227bb3b34ddfc267c85fd81/TypeScript.YAML-tmLanguage#L62

The $ is presumably what ends the type at the end of a line without a semicolon (x as T followed by a new statement), so dropping it could break that case.

Vorherrschende Sprache
TypeScript
Sterne
471
Forks
150
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Entwicklungsumgebung

Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus microsoft/TypeScript-TmLanguage

Alle Issues in microsoft/TypeScript-TmLanguage

Ähnliche Issues

Weitere Issues zu TypeScript

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.