#21329·eslint

Change Request: Allow `SourceCode#getText()` types to accept tokens and comments

Author: electrohyunCreated Sep 16, 2026Updated Sep 17, 2026
Labelsenhancementcoreaccepted

ESLint version

v10.10.0

What problem do you want to solve?

I found this while looking through a rule file in the eslint-community. The file uses @ts-expect-error when passing a comment to SourceCode#getText().

The type definition of SourceCode#getText() only accepts an ESTree.Node.

typescript
getText(
    node?: ESTree.Node,
    beforeCount?: number,
    afterCount?: number,
): string;

Other SourceCode methods return AST.Token and ESTree.Comment values.

typescript
const token = sourceCode.getFirstToken(node);
// AST.Token | null

const comments = sourceCode.getCommentsBefore(node);
// ESTree.Comment[]

Despite this type definition, getText() can also accept these values because its implementation only reads the provided object's range.

javascript
getText(node, beforeCount, afterCount) {
    if (node) {
        return this.text.slice(
            Math.max(node.range[0] - (beforeCount || 0), 0),
            node.range[1] + (afterCount || 0),
        );
    }

    return this.text;
}

So, this causes valid runtime code to fail type checking.

typescript
const token = sourceCode.getFirstToken(node);

if (token) {
  // Argument of type 'Token' is not assignable to parameter of type 'Node | undefined'.
  sourceCode.getText(token);
}

for (const comment of sourceCode.getCommentsBefore(node)) {
  // Argument of type 'Comment' is not assignable to parameter of type 'Node | undefined'.
  sourceCode.getText(comment);
}

This means that values returned by SourceCode itself cannot be passed back to getText() without a type error, even though they are handled at runtime.


I also found examples of this usage in ESLint.

  • The curly rule passes a token returned by getTokenBefore() to getText().
  • A SourceCode test passes a shebang comment returned by getAllComments() to getText().

And found similar usages in ecosystem plugins.

  • eslint-plugin-n passes a comment to getText() and uses @ts-expect-error to suppress the resulting type error.
  • eslint-plugin-typescript-sort-keys passes a comment to getText() using comment as any. removing the type assertion reproduces the same error.
  • eslint-plugin-es passed a token to getText() as part of an Espree compatibility workaround.
  • eslint-stylistic also passes a token to getText() (without a type error because it uses @typescript-eslint's SourceCode type that already accepts Node | Token).

What do you think is the correct solution?

I think we can update SourceCode#getText() to accept nodes, tokens, and comments.

typescript
getText(
    syntaxElement?: ESTree.Node | AST.Token | ESTree.Comment,
    beforeCount?: number,
    afterCount?: number,
): string;

This would be a type widening and would not require a runtime implementation change.

Type tests can cover all three supported inputs.

typescript
sourceCode.getText(AST);
sourceCode.getText(TOKEN);
sourceCode.getText(COMMENT);

The documentation and implementation JSDoc can also be updated to describe the parameter as a node, token, or comment.

Participation

  • I am willing to submit a pull request for this change.

AI acknowledgment

  • I did not use AI to generate this issue report.
  • (If the above is not checked) I have reviewed the AI-generated content before submitting.

Additional comments

No response


Disclosure: I'm a participant of open source contribution program OSSCA