Skip to content

Commit

Permalink
fix: support typeof this
Browse files Browse the repository at this point in the history
  • Loading branch information
Zzzen committed Jan 1, 2022
1 parent ccee1a2 commit 3caf3c5
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
9 changes: 9 additions & 0 deletions packages/eslint-plugin/tests/eslint-rules/no-undef.test.ts
Expand Up @@ -248,6 +248,15 @@ class Foo {}
`
export type AppState = typeof import('./src/store/reducers').default;
`,
`
const obj = {
foo: '',
bar() {
let self: typeof this;
let foo: typeof this.foo;
},
};
`,
],
invalid: [
{
Expand Down
11 changes: 10 additions & 1 deletion packages/scope-manager/src/referencer/TypeVisitor.ts
Expand Up @@ -258,11 +258,20 @@ class TypeVisitor extends Visitor {
protected TSTypeQuery(node: TSESTree.TSTypeQuery): void {
if (node.exprName.type === AST_NODE_TYPES.Identifier) {
this.#referencer.currentScope().referenceValue(node.exprName);
} else if (
(node.exprName.type as unknown) === AST_NODE_TYPES.ThisExpression
) {
// technically exprName is either Identifier or QualifiedName, but eslint does not recognize `typeof this`,
// so we have translated it to ThisExpression.
return;
} else {
let expr = node.exprName.left;
while (expr.type !== AST_NODE_TYPES.Identifier) {
while (expr.type === TSESTree.AST_NODE_TYPES.TSQualifiedName) {
expr = expr.left;
}
if ((expr.type as unknown) === AST_NODE_TYPES.ThisExpression) {
return;
}
this.#referencer.currentScope().referenceValue(expr);
}
}
Expand Down
9 changes: 9 additions & 0 deletions packages/typescript-estree/src/convert.ts
Expand Up @@ -20,6 +20,7 @@ import {
isComputedProperty,
isESTreeClassMember,
isOptional,
isThisInTypeQuery,
TSError,
unescapeStringLiteralText,
} from './node-utils';
Expand Down Expand Up @@ -787,6 +788,14 @@ export class Converter {
}

case SyntaxKind.Identifier: {
if (isThisInTypeQuery(node)) {
return this.createNode<TSESTree.ThisExpression>(
node as unknown as ts.ThisExpression,
{
type: AST_NODE_TYPES.ThisExpression,
},
);
}
return this.createNode<TSESTree.Identifier>(node, {
type: AST_NODE_TYPES.Identifier,
name: node.text,
Expand Down
24 changes: 24 additions & 0 deletions packages/typescript-estree/src/node-utils.ts
Expand Up @@ -663,3 +663,27 @@ export function firstDefined<T, U>(
}
return undefined;
}

export function identifierIsThisKeyword(id: ts.Identifier): boolean {
return id.originalKeywordKind === SyntaxKind.ThisKeyword;
}

export function isThisIdentifier(node: ts.Node | undefined): boolean {
return (
!!node &&
node.kind === SyntaxKind.Identifier &&
identifierIsThisKeyword(node as ts.Identifier)
);
}

export function isThisInTypeQuery(node: ts.Node): boolean {
if (!isThisIdentifier(node)) {
return false;
}

while (ts.isQualifiedName(node.parent) && node.parent.left === node) {
node = node.parent;
}

return node.parent.kind === SyntaxKind.TypeQuery;
}

0 comments on commit 3caf3c5

Please sign in to comment.