[Bug] PrivateIdentifier nodes are omitted from 2020 semantic classifications

Open Beginner friendly
#64,322 2 comments 1 reaction 2 assignees View on GitHub

@jakebailey is already working on this.

Since Sep 19, 2026.

  • #64349 by @copilot-swe-agent — merged

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
88/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript, vscode

Research direction

Start in src/services/classifier2020.ts at collectTokens and review the existing declaration-kind mapping for identifier nodes. Add the relevant fourslash regression test covering private field and method declarations and references, then verify that the nodes receive property or method classifications and declaration modifiers.

Written by the indexing model from the issue text.

Description

Bug Report

🔎 Search Terms

semantic highlighting, semantic token, PrivateIdentifier, private field, private method, encodedSemanticClassifications

🕗 Version & Regression Information
  • TypeScript 6.0.3 (bundled with VS Code)
  • Also present in the v5.9 classifier implementation
  • This is not a theme-specific issue
💻 Code
class Foo {
    field = 1;
    #privateField = 1;

    method() {}
    #privateMethod() {}

    test() {
        this.field;
        this.#privateField;

        this.method();
        this.#privateMethod();
    }
}
🙁 Actual behavior

In VS Code's Developer: Inspect Editor Tokens and Scopes:

  • field and method receive semantic token types.
  • #privateField and #privateMethod receive no semantic token and fall back to TextMate scopes.
  • As a result, editor.semanticTokenColorCustomizations rules for property and method do not apply to ECMAScript private members.
Image Image
🙂 Expected behavior
  • #privateField should be classified as property.
  • #privateMethod should be classified as method.
  • Declarations should also receive the declaration modifier.
Root cause

VS Code requests encodedSemanticClassifications-full with format "2020".

In src/services/classifier2020.ts, collectTokens only enters the semantic-classification path for isIdentifier(node):

if (isIdentifier(node) && ...) {
    let symbol = typeChecker.getSymbolAtLocation(node);
    // ...
}

ECMAScript private names are separate SyntaxKind.PrivateIdentifier nodes, so they are skipped before getSymbolAtLocation is called.

Relevant source:
https://github.com/microsoft/TypeScript/blob/050880ce59e30b356b686bd3144efe24f875ebc8/src/services/classifier2020.ts#L121-L203

Proposed fix
+    isPrivateIdentifier,
     isPropertyAccessExpression,
-        if (isIdentifier(node) && ...) {
+        if ((isIdentifier(node) || isPrivateIdentifier(node)) && ...) {

The existing declaration-kind mapping already classifies private fields and methods correctly once these nodes reach the symbol-classification path.

I tested the equivalent change against TypeScript 6.0.3:

  • #privateField declaration/reference → property
  • #privateMethod declaration/reference → member internally, mapped by VS Code to method
  • declaration occurrences receive the declaration modifier
  • added fourslash regression test passes
Related issue

https://github.com/microsoft/TypeScript/issues/44483 requests new private/protected semantic modifiers. This report is different: ECMAScript PrivateIdentifier nodes currently receive no semantic classification at all.

Dominant language
Go
Stars
111k
Forks
14.4k
Avg merge
1d 15h
Merged PRs (30d)
106

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/TypeScript

All issues in microsoft/TypeScript

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.