Always return a defined result from getTypeFromTypeNode (#26108)

This commit is contained in:
Andy 2018-07-31 17:28:15 -07:00 committed by GitHub
parent 9277ec08d7
commit 1599ee2805
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 12 additions and 15 deletions

View File

@ -1839,7 +1839,7 @@ namespace ts {
if (symbol.flags & SymbolFlags.Variable) {
const typeAnnotation = (<VariableDeclaration>symbol.valueDeclaration).type;
if (typeAnnotation) {
return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name)); // TODO: GH#18217
return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name));
}
}
}
@ -6865,11 +6865,7 @@ namespace ts {
return obj.properties.some(property => {
const name = property.name && getTextOfPropertyName(property.name);
const expected = name === undefined ? undefined : getTypeOfPropertyOfType(contextualType, name);
if (expected && typeIsLiteralType(expected)) {
const actual = getTypeOfNode(property);
return !!actual && !isTypeIdenticalTo(actual, expected);
}
return false;
return !!expected && typeIsLiteralType(expected) && !isTypeIdenticalTo(getTypeOfNode(property), expected);
});
}
@ -9841,7 +9837,7 @@ namespace ts {
case SyntaxKind.Identifier:
case SyntaxKind.QualifiedName:
const symbol = getSymbolAtLocation(node);
return (symbol && getDeclaredTypeOfSymbol(symbol))!; // TODO: GH#18217
return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
default:
return errorType;
}
@ -19414,7 +19410,7 @@ namespace ts {
}
const typeArgumentNodes: ReadonlyArray<TypeNode> = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments || emptyArray : emptyArray;
const typeArguments = typeArgumentNodes.map(n => getTypeOfNode(n) || anyType);
const typeArguments = typeArgumentNodes.map(getTypeOfNode);
while (typeArguments.length > typeParameters.length) {
typeArguments.pop();
}
@ -27267,7 +27263,7 @@ namespace ts {
grandParent.kind === SyntaxKind.ObjectBindingPattern &&
node === (<BindingElement>parent).propertyName) {
const typeOfPattern = getTypeOfNode(grandParent);
const propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, (<Identifier>node).escapedText);
const propertyDeclaration = getPropertyOfType(typeOfPattern, (<Identifier>node).escapedText);
if (propertyDeclaration) {
return propertyDeclaration;
@ -27367,7 +27363,7 @@ namespace ts {
if (isPartOfTypeNode(node)) {
let typeFromTypeNode = getTypeFromTypeNode(<TypeNode>node);
if (typeFromTypeNode && isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
if (isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
const containingClass = getContainingClass(node)!;
const classType = getTypeOfNode(containingClass) as InterfaceType;
typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType);
@ -27385,8 +27381,8 @@ namespace ts {
// extends clause of a class. We handle that case here.
const classNode = getContainingClass(node)!;
const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode)) as InterfaceType;
const baseType = getBaseTypes(classType)[0];
return baseType && getTypeWithThisArgument(baseType, classType.thisType);
const baseType = firstOrUndefined(getBaseTypes(classType));
return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType;
}
if (isTypeDeclaration(node)) {

View File

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

View File

@ -11,7 +11,7 @@ goTo.eof();
edit.insertLine("");
// Attempt to resolve a symbol
verify.quickInfoAt("IPointRef", ""); // not found
verify.quickInfoAt("IPointRef", "any"); // not found
// trigger typecheck after the partial resolve, we should see errors
verify.errorExistsAfterMarker("IPointRef");