Skip to content

Commit 1599ee2

Browse files
author
Andy
authored
Always return a defined result from getTypeFromTypeNode (microsoft#26108)
1 parent 9277ec0 commit 1599ee2

File tree

3 files changed

+12
-15
lines changed

3 files changed

+12
-15
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,7 +1839,7 @@ namespace ts {
18391839
if (symbol.flags & SymbolFlags.Variable) {
18401840
const typeAnnotation = (<VariableDeclaration>symbol.valueDeclaration).type;
18411841
if (typeAnnotation) {
1842-
return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name)); // TODO: GH#18217
1842+
return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name));
18431843
}
18441844
}
18451845
}
@@ -6865,11 +6865,7 @@ namespace ts {
68656865
return obj.properties.some(property => {
68666866
const name = property.name && getTextOfPropertyName(property.name);
68676867
const expected = name === undefined ? undefined : getTypeOfPropertyOfType(contextualType, name);
6868-
if (expected && typeIsLiteralType(expected)) {
6869-
const actual = getTypeOfNode(property);
6870-
return !!actual && !isTypeIdenticalTo(actual, expected);
6871-
}
6872-
return false;
6868+
return !!expected && typeIsLiteralType(expected) && !isTypeIdenticalTo(getTypeOfNode(property), expected);
68736869
});
68746870
}
68756871

@@ -9841,7 +9837,7 @@ namespace ts {
98419837
case SyntaxKind.Identifier:
98429838
case SyntaxKind.QualifiedName:
98439839
const symbol = getSymbolAtLocation(node);
9844-
return (symbol && getDeclaredTypeOfSymbol(symbol))!; // TODO: GH#18217
9840+
return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
98459841
default:
98469842
return errorType;
98479843
}
@@ -19414,7 +19410,7 @@ namespace ts {
1941419410
}
1941519411

1941619412
const typeArgumentNodes: ReadonlyArray<TypeNode> = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments || emptyArray : emptyArray;
19417-
const typeArguments = typeArgumentNodes.map(n => getTypeOfNode(n) || anyType);
19413+
const typeArguments = typeArgumentNodes.map(getTypeOfNode);
1941819414
while (typeArguments.length > typeParameters.length) {
1941919415
typeArguments.pop();
1942019416
}
@@ -27267,7 +27263,7 @@ namespace ts {
2726727263
grandParent.kind === SyntaxKind.ObjectBindingPattern &&
2726827264
node === (<BindingElement>parent).propertyName) {
2726927265
const typeOfPattern = getTypeOfNode(grandParent);
27270-
const propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, (<Identifier>node).escapedText);
27266+
const propertyDeclaration = getPropertyOfType(typeOfPattern, (<Identifier>node).escapedText);
2727127267

2727227268
if (propertyDeclaration) {
2727327269
return propertyDeclaration;
@@ -27367,7 +27363,7 @@ namespace ts {
2736727363
if (isPartOfTypeNode(node)) {
2736827364
let typeFromTypeNode = getTypeFromTypeNode(<TypeNode>node);
2736927365

27370-
if (typeFromTypeNode && isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
27366+
if (isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
2737127367
const containingClass = getContainingClass(node)!;
2737227368
const classType = getTypeOfNode(containingClass) as InterfaceType;
2737327369
typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType);
@@ -27385,8 +27381,8 @@ namespace ts {
2738527381
// extends clause of a class. We handle that case here.
2738627382
const classNode = getContainingClass(node)!;
2738727383
const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode)) as InterfaceType;
27388-
const baseType = getBaseTypes(classType)[0];
27389-
return baseType && getTypeWithThisArgument(baseType, classType.thisType);
27384+
const baseType = firstOrUndefined(getBaseTypes(classType));
27385+
return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType;
2739027386
}
2739127387

2739227388
if (isTypeDeclaration(node)) {

src/harness/typeWriter.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ class TypeWriterWalker {
8383

8484
// Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions
8585
// let type = this.checker.getTypeAtLocation(node);
86-
const type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node);
87-
const typeString = type ? this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType) : "No type information available!";
86+
let type = ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) ? this.checker.getTypeAtLocation(node.parent) : undefined;
87+
if (!type || type.flags & ts.TypeFlags.Any) type = this.checker.getTypeAtLocation(node);
88+
const typeString = this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType);
8889
return {
8990
line: lineAndCharacter.line,
9091
syntaxKind: node.kind,

tests/cases/fourslash/typeCheckAfterResolve.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ goTo.eof();
1111
edit.insertLine("");
1212

1313
// Attempt to resolve a symbol
14-
verify.quickInfoAt("IPointRef", ""); // not found
14+
verify.quickInfoAt("IPointRef", "any"); // not found
1515

1616
// trigger typecheck after the partial resolve, we should see errors
1717
verify.errorExistsAfterMarker("IPointRef");

0 commit comments

Comments
 (0)