Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#1,079 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
68/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
typescript
Ambito
tooling

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.

Lingua principale
TypeScript
Stelle
471
Fork
150
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/TypeScript-TmLanguage

Tutte le issue di microsoft/TypeScript-TmLanguage

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.