Fix getTypeAtLocation for dotted implements clauses (#39363)

* Fix getTypeAtLocation for dotted implements clauses

* Fix typo
This commit is contained in:
Andrew Branch
2020-07-07 16:17:07 -07:00
committed by GitHub
parent b7193a6a44
commit 2d6d5db33a
2 changed files with 30 additions and 1 deletions

View File

@@ -14387,11 +14387,12 @@ namespace ts {
return getTypeFromInferTypeNode(<InferTypeNode>node);
case SyntaxKind.ImportType:
return getTypeFromImportTypeNode(<ImportTypeNode>node);
// This function assumes that an identifier or qualified name is a type expression
// This function assumes that an identifier, qualified name, or property access expression is a type expression
// Callers should first ensure this by calling `isPartOfTypeNode`
// TODO(rbuckton): These aren't valid TypeNodes, but we treat them as such because of `isPartOfTypeNode`, which returns `true` for things that aren't `TypeNode`s.
case SyntaxKind.Identifier as TypeNodeSyntaxKind:
case SyntaxKind.QualifiedName as TypeNodeSyntaxKind:
case SyntaxKind.PropertyAccessExpression as TypeNodeSyntaxKind:
const symbol = getSymbolAtLocation(node);
return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
default:

View File

@@ -77,3 +77,31 @@ describe("unittests:: Public APIs:: isPropertyName", () => {
assert.isTrue(ts.isPropertyName(prop), "PrivateIdentifier must be a valid property name.");
});
});
describe("unittests:: Public APIs:: getTypeAtLocation", () => {
it("works on PropertyAccessExpression in implements clause", () => {
const content = `namespace Test {
export interface Test {}
}
class Foo implements Test.Test {}`;
const host = new fakes.CompilerHost(vfs.createFromFileSystem(
Harness.IO,
/*ignoreCase*/ true,
{ documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" }));
const program = ts.createProgram({
host,
rootNames: ["/file.ts"],
options: { noLib: true }
});
const checker = program.getTypeChecker();
const file = program.getSourceFile("/file.ts")!;
const classDeclaration = file.statements.find(ts.isClassDeclaration)!;
const propertyAccess = classDeclaration.heritageClauses![0].types[0].expression as ts.PropertyAccessExpression;
const type = checker.getTypeAtLocation(propertyAccess);
assert.ok(!(type.flags & ts.TypeFlags.Any));
assert.equal(type, checker.getTypeAtLocation(propertyAccess.name));
});
});