From e89acb6358845b310753e132f5ae692c72d5bb6a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 31 Jul 2019 16:30:54 -0700 Subject: [PATCH 001/100] Reflect effects of assertion calls in control flow analysis --- src/compiler/binder.ts | 22 +++++++++++++ src/compiler/checker.ts | 71 +++++++++++++++++++++++++++++++++++++++++ src/compiler/types.ts | 19 +++++++---- 3 files changed, 106 insertions(+), 6 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index d18ab45a347..16dffe46aad 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -706,6 +706,9 @@ namespace ts { case SyntaxKind.CaseClause: bindCaseClause(node); break; + case SyntaxKind.ExpressionStatement: + bindExpressionStatement(node); + break; case SyntaxKind.LabeledStatement: bindLabeledStatement(node); break; @@ -896,6 +899,11 @@ namespace ts { return flowNodeCreated({ flags: FlowFlags.Assignment, antecedent, node }); } + function createFlowCall(antecedent: FlowNode, node: CallExpression): FlowNode { + setFlowNodeReferenced(antecedent); + return flowNodeCreated({ flags: FlowFlags.Call, antecedent, node }); + } + function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode { setFlowNodeReferenced(antecedent); const res: FlowArrayMutation = flowNodeCreated({ flags: FlowFlags.ArrayMutation, antecedent, node }); @@ -1276,6 +1284,20 @@ namespace ts { activeLabels!.pop(); } + function isDottedName(node: Expression) { + return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression && isQualifiedName((node).expression); + } + + function bindExpressionStatement(node: ExpressionStatement): void { + bind(node.expression); + if (node.expression.kind === SyntaxKind.CallExpression) { + const call = node.expression; + if (isDottedName(call.expression) && call.arguments.length >= 1) { + currentFlow = createFlowCall(currentFlow, call); + } + } + } + function bindLabeledStatement(node: LabeledStatement): void { const preStatementLabel = createLoopLabel(); const postStatementLabel = createBranchLabel(); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3fa9c2da66e..2ed815e8978 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16864,6 +16864,44 @@ namespace ts { return false; } + function getTypeOfDottedName(node: Expression) { + if (node.kind === SyntaxKind.Identifier) { + const symbol = getResolvedSymbol(node); + const nonAliasSymbol = symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol; + return nonAliasSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.ValueModule) ? getTypeOfSymbol(nonAliasSymbol) : undefined; + } + if (node.kind === SyntaxKind.PropertyAccessExpression) { + const type = getTypeOfDottedName((node).expression); + if (type) { + const prop = getPropertyOfType(type, (node).name.escapedText); + return prop && prop.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.ValueModule) ? getTypeOfSymbol(prop) : undefined; + } + } + } + + function getIsAssertCall(node: CallExpression) { + const type = getTypeOfDottedName(node.expression); + if (type) { + const signature = getSingleCallSignature(type); + if (signature && signature.declaration) { + const typeNode = getEffectiveReturnTypeNode(signature.declaration); + if (typeNode && typeNode.kind === SyntaxKind.UnionType) { + const types = (typeNode).types; + return types.length === 2 && types[0].kind === SyntaxKind.VoidKeyword && types[1].kind === SyntaxKind.NeverKeyword; + } + } + } + return false; + } + + function isAssertCall(node: CallExpression) { + const links = getNodeLinks(node); + if (links.isAssertCall === undefined) { + links.isAssertCall = getIsAssertCall(node); + } + return links.isAssertCall; + } + function reportFlowControlError(node: Node) { const block = findAncestor(node, isFunctionOrModuleBlock); const sourceFile = getSourceFileOfNode(node); @@ -16962,6 +17000,13 @@ namespace ts { } } } + else if (flags & FlowFlags.Call) { + type = getTypeAtFlowCall(flow); + if (!type) { + flow = (flow).antecedent; + continue; + } + } else if (flags & FlowFlags.Condition) { type = getTypeAtFlowCondition(flow); } @@ -17057,6 +17102,32 @@ namespace ts { return undefined; } + function narrowTypeByAssertion(type: Type, expr: Expression): Type { + const node = skipParentheses(expr); + if (node.kind === SyntaxKind.BinaryExpression) { + if ((node).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { + return narrowTypeByAssertion(narrowTypeByAssertion(type, (node).left), (node).right); + } + if ((node).operatorToken.kind === SyntaxKind.BarBarToken) { + return getUnionType([narrowTypeByAssertion(type, (node).left), narrowTypeByAssertion(type, (node).right)]); + } + } + return narrowType(type, node, /*assumeTrue*/ true); + } + + function getTypeAtFlowCall(flow: FlowCall): FlowType | undefined { + if (isAssertCall(flow.node)) { + const flowType = getTypeAtFlowNode(flow.antecedent); + const type = getTypeFromFlowType(flowType); + const narrowedType = narrowTypeByAssertion(type, flow.node.arguments[0]); + if (narrowedType === type) { + return flowType; + } + return createFlowType(narrowedType, isIncomplete(flowType)); + } + return undefined; + } + function getTypeAtFlowArrayMutation(flow: FlowArrayMutation): FlowType | undefined { if (declaredType === autoType || declaredType === autoArrayType) { const node = flow.node; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 099f7705f84..aec65b03367 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2550,12 +2550,13 @@ namespace ts { FalseCondition = 1 << 6, // Condition known to be false SwitchClause = 1 << 7, // Switch statement clause ArrayMutation = 1 << 8, // Potential array mutation - Referenced = 1 << 9, // Referenced as antecedent once - Shared = 1 << 10, // Referenced as antecedent more than once - PreFinally = 1 << 11, // Injected edge that links pre-finally label and pre-try flow - AfterFinally = 1 << 12, // Injected edge that links post-finally flow with the rest of the graph + Call = 1 << 9, // Potential assertion call + Referenced = 1 << 10, // Referenced as antecedent once + Shared = 1 << 11, // Referenced as antecedent more than once + PreFinally = 1 << 12, // Injected edge that links pre-finally label and pre-try flow + AfterFinally = 1 << 13, // Injected edge that links post-finally flow with the rest of the graph /** @internal */ - Cached = 1 << 13, // Indicates that at least one cross-call cache entry exists for this node, even if not a loop participant + Cached = 1 << 14, // Indicates that at least one cross-call cache entry exists for this node, even if not a loop participant Label = BranchLabel | LoopLabel, Condition = TrueCondition | FalseCondition } @@ -2574,7 +2575,7 @@ namespace ts { } export type FlowNode = - | AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation; + | AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; export interface FlowNodeBase { flags: FlowFlags; id?: number; // Node id used by flow type cache in checker @@ -2599,6 +2600,11 @@ namespace ts { antecedent: FlowNode; } + export interface FlowCall extends FlowNodeBase { + node: CallExpression; + antecedent: FlowNode; + } + // FlowCondition represents a condition that is known to be true or false at the // node's location in the control flow. export interface FlowCondition extends FlowNodeBase { @@ -3902,6 +3908,7 @@ namespace ts { resolvedSymbol?: Symbol; // Cached name resolution result resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate + isAssertCall?: boolean; enumMemberValue?: string | number; // Constant value of enum member isVisible?: boolean; // Is this node visible containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference From 77f2a412e15a3f3ac2a01d648a64e75670d47204 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 2 Aug 2019 17:57:26 -0700 Subject: [PATCH 002/100] Support 'asserts' type predicates in control flow analysis --- src/compiler/binder.ts | 6 +- src/compiler/checker.ts | 230 +++++++++++++++++++--------------------- src/compiler/emitter.ts | 14 ++- src/compiler/factory.ts | 7 +- src/compiler/parser.ts | 13 +++ src/compiler/scanner.ts | 1 + src/compiler/types.ts | 36 ++++--- src/compiler/visitor.ts | 1 + 8 files changed, 166 insertions(+), 142 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 16dffe46aad..2b917bc577c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1284,12 +1284,14 @@ namespace ts { activeLabels!.pop(); } - function isDottedName(node: Expression) { - return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression && isQualifiedName((node).expression); + function isDottedName(node: Expression): boolean { + return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((node).expression); } function bindExpressionStatement(node: ExpressionStatement): void { bind(node.expression); + // A top level call expression with a dotted function name and at least one argument + // is potentially an assertion and is therefore included in the control flow. if (node.expression.kind === SyntaxKind.CallExpression) { const call = node.expression; if (isDottedName(call.expression) && call.arguments.length >= 1) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2ed815e8978..c8ad1f66064 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -522,7 +522,7 @@ namespace ts { markerSubType.constraint = markerSuperType; const markerOtherType = createTypeParameter(); - const noTypePredicate = createIdentifierTypePredicate("<>", 0, anyType); + const noTypePredicate = createTypePredicate(TypePredicateKind.Identifier, "<>", 0, anyType); const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); @@ -4212,11 +4212,12 @@ namespace ts { let returnTypeNode: TypeNode | undefined; const typePredicate = getTypePredicateOfSignature(signature); if (typePredicate) { - const parameterName = typePredicate.kind === TypePredicateKind.Identifier ? + const assertsModifier = typePredicate.kind === TypePredicateKind.Assertion ? createToken(SyntaxKind.AssertsKeyword) : undefined; + const parameterName = typePredicate.kind !== TypePredicateKind.This ? setEmitFlags(createIdentifier(typePredicate.parameterName), EmitFlags.NoAsciiEscaping) : createThisTypeNode(); - const typeNode = typeToTypeNodeHelper(typePredicate.type, context); - returnTypeNode = createTypePredicateNode(parameterName, typeNode); + const typeNode = typePredicate.type && typeToTypeNodeHelper(typePredicate.type, context); + returnTypeNode = createTypePredicateNode(assertsModifier, parameterName, typeNode); } else { const returnType = getReturnTypeOfSignature(signature); @@ -4685,8 +4686,9 @@ namespace ts { function typePredicateToStringWorker(writer: EmitTextWriter) { const predicate = createTypePredicateNode( - typePredicate.kind === TypePredicateKind.Identifier ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(), - nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)!, // TODO: GH#18217 + typePredicate.kind === TypePredicateKind.Assertion ? createToken(SyntaxKind.AssertsKeyword) : undefined, + typePredicate.kind !== TypePredicateKind.This ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(), + typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217 ); const printer = createPrinter({ removeComments: true }); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); @@ -8432,12 +8434,8 @@ namespace ts { return isBracketed || !!typeExpression && typeExpression.type.kind === SyntaxKind.JSDocOptionalType; } - function createIdentifierTypePredicate(parameterName: string, parameterIndex: number, type: Type): IdentifierTypePredicate { - return { kind: TypePredicateKind.Identifier, parameterName, parameterIndex, type }; - } - - function createThisTypePredicate(type: Type): ThisTypePredicate { - return { kind: TypePredicateKind.This, type }; + function createTypePredicate(kind: TypePredicateKind, parameterName: string | undefined, parameterIndex: number | undefined, type: Type | undefined): TypePredicate { + return { kind, parameterName, parameterIndex, type } as TypePredicate; } /** @@ -8672,9 +8670,15 @@ namespace ts { } } - function signatureHasTypePredicate(signature: Signature): boolean { - return getTypePredicateOfSignature(signature) !== undefined; - } + // function hasAssertionTypePredicate(signature: Signature): boolean { + // const predicate = getTypePredicateOfSignature(signature); + // return !!predicate && predicate.kind === TypePredicateKind.Assertion; + // } + + // function hasBooleanTypePredicate(signature: Signature): boolean { + // const predicate = getTypePredicateOfSignature(signature); + // return !!predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier); + // } function getTypePredicateOfSignature(signature: Signature): TypePredicate | undefined { if (!signature.resolvedTypePredicate) { @@ -8703,18 +8707,13 @@ namespace ts { return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate; } - function createTypePredicateFromTypePredicateNode(node: TypePredicateNode, signature: Signature): IdentifierTypePredicate | ThisTypePredicate { - const { parameterName } = node; - const type = getTypeFromTypeNode(node.type); - if (parameterName.kind === SyntaxKind.Identifier) { - return createIdentifierTypePredicate( - parameterName.escapedText as string, - findIndex(signature.parameters, p => p.escapedName === parameterName.escapedText), - type); - } - else { - return createThisTypePredicate(type); - } + function createTypePredicateFromTypePredicateNode(node: TypePredicateNode, signature: Signature): TypePredicate { + const parameterName = node.parameterName; + const type = node.type && getTypeFromTypeNode(node.type); + return parameterName.kind === SyntaxKind.ThisType ? + createTypePredicate(TypePredicateKind.This, /*parameterName*/ undefined, /*parameterIndex*/ undefined, type) : + createTypePredicate(node.assertsModifier ? TypePredicateKind.Assertion : TypePredicateKind.Identifier, parameterName.escapedText as string, + findIndex(signature.parameters, p => p.escapedName === parameterName.escapedText), type); } function getReturnTypeOfSignature(signature: Signature): Type { @@ -9820,7 +9819,7 @@ namespace ts { const types: Type[] = []; for (const sig of signatures) { const pred = getTypePredicateOfSignature(sig); - if (!pred) { + if (!pred || pred.kind === TypePredicateKind.Assertion) { continue; } @@ -9840,15 +9839,11 @@ namespace ts { return undefined; } const unionType = getUnionType(types); - return isIdentifierTypePredicate(first) - ? createIdentifierTypePredicate(first.parameterName, first.parameterIndex, unionType) - : createThisTypePredicate(unionType); + return createTypePredicate(first.kind, first.parameterName, first.parameterIndex, unionType); } function typePredicateKindsMatch(a: TypePredicate, b: TypePredicate): boolean { - return isIdentifierTypePredicate(a) - ? isIdentifierTypePredicate(b) && a.parameterIndex === b.parameterIndex - : !isIdentifierTypePredicate(b); + return a.kind === b.kind && a.parameterIndex === b.parameterIndex; } // This function assumes the constituent type list is sorted and deduplicated. @@ -11114,7 +11109,7 @@ namespace ts { case SyntaxKind.TypeReference: return getTypeFromTypeReference(node); case SyntaxKind.TypePredicate: - return booleanType; + return (node).assertsModifier ? voidType : booleanType; case SyntaxKind.ExpressionWithTypeArguments: return getTypeFromTypeReference(node); case SyntaxKind.TypeQuery: @@ -11272,21 +11267,8 @@ namespace ts { return result; } - function instantiateTypePredicate(predicate: TypePredicate, mapper: TypeMapper): ThisTypePredicate | IdentifierTypePredicate { - if (isIdentifierTypePredicate(predicate)) { - return { - kind: TypePredicateKind.Identifier, - parameterName: predicate.parameterName, - parameterIndex: predicate.parameterIndex, - type: instantiateType(predicate.type, mapper) - }; - } - else { - return { - kind: TypePredicateKind.This, - type: instantiateType(predicate.type, mapper) - }; - } + function instantiateTypePredicate(predicate: TypePredicate, mapper: TypeMapper): TypePredicate { + return createTypePredicate(predicate.kind, predicate.parameterName, predicate.parameterIndex, instantiateType(predicate.type, mapper)); } function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature { @@ -12338,7 +12320,7 @@ namespace ts { // with respect to T. const sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType)); const targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType)); - const callbacks = sourceSig && targetSig && !signatureHasTypePredicate(sourceSig) && !signatureHasTypePredicate(targetSig) && + const callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) && (getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable); const related = callbacks ? // TODO: GH#18217 It will work if they're both `undefined`, but not if only one is @@ -12407,7 +12389,7 @@ namespace ts { return Ternary.False; } - if (source.kind === TypePredicateKind.Identifier) { + if (source.kind !== TypePredicateKind.This) { if (source.parameterIndex !== (target as IdentifierTypePredicate).parameterIndex) { if (reportErrors) { errorReporter!(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, (target as IdentifierTypePredicate).parameterName); @@ -12417,7 +12399,9 @@ namespace ts { } } - const related = compareTypes(source.type, target.type, reportErrors); + const related = source.type === target.type ? Ternary.True : + source.type && target.type ? compareTypes(source.type, target.type, reportErrors) : + Ternary.False; if (related === Ternary.False && reportErrors) { errorReporter!(Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } @@ -14602,16 +14586,18 @@ namespace ts { if (!ignoreReturnTypes) { const sourceTypePredicate = getTypePredicateOfSignature(source); const targetTypePredicate = getTypePredicateOfSignature(target); - result &= sourceTypePredicate !== undefined || targetTypePredicate !== undefined - ? compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes) - // If they're both type predicates their return types will both be `boolean`, so no need to compare those. - : compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); + result &= sourceTypePredicate || targetTypePredicate ? + compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes) : + compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); } return result; } function compareTypePredicatesIdentical(source: TypePredicate | undefined, target: TypePredicate | undefined, compareTypes: (s: Type, t: Type) => Ternary): Ternary { - return source === undefined || target === undefined || !typePredicateKindsMatch(source, target) ? Ternary.False : compareTypes(source.type, target.type); + return !(source && target && typePredicateKindsMatch(source, target)) ? Ternary.False : + source.type === target.type ? Ternary.True : + source.type && target.type ? compareTypes(source.type, target.type) : + Ternary.False; } function literalTypesWithSameBaseType(types: Type[]): boolean { @@ -15219,8 +15205,7 @@ namespace ts { function applyToReturnTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) { const sourceTypePredicate = getTypePredicateOfSignature(source); const targetTypePredicate = getTypePredicateOfSignature(target); - if (sourceTypePredicate && targetTypePredicate && sourceTypePredicate.kind === targetTypePredicate.kind && - (sourceTypePredicate.kind === TypePredicateKind.This || sourceTypePredicate.parameterIndex === (targetTypePredicate).parameterIndex)) { + if (sourceTypePredicate && targetTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) { callback(sourceTypePredicate.type, targetTypePredicate.type); } else { @@ -16845,61 +16830,62 @@ namespace ts { return isLengthPushOrUnshift || isElementAssignment; } - function maybeTypePredicateCall(node: CallExpression) { - const links = getNodeLinks(node); - if (links.maybeTypePredicate === undefined) { - links.maybeTypePredicate = getMaybeTypePredicate(node); - } - return links.maybeTypePredicate; + function isDeclarationWithExplicitTypeAnnotation(declaration: Declaration | undefined) { + return !!(declaration && ( + declaration.kind === SyntaxKind.VariableDeclaration || declaration.kind === SyntaxKind.Parameter || + declaration.kind === SyntaxKind.PropertyDeclaration || declaration.kind === SyntaxKind.PropertySignature) && + (declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature).type); } - function getMaybeTypePredicate(node: CallExpression) { - if (node.expression.kind !== SyntaxKind.SuperKeyword) { - const funcType = checkNonNullExpression(node.expression); - if (funcType !== silentNeverType) { - const apparentType = getApparentType(funcType); - return apparentType !== errorType && some(getSignaturesOfType(apparentType, SignatureKind.Call), signatureHasTypePredicate); - } - } - return false; + function getExplicitTypeOfSymbol(symbol: Symbol) { + return symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.ValueModule) || + symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property) && isDeclarationWithExplicitTypeAnnotation(symbol.valueDeclaration) ? + getTypeOfSymbol(symbol) : undefined; } function getTypeOfDottedName(node: Expression) { + // We require the dotted function name in an assertion expression to be comprised of identifiers + // that reference function, method, class or value module symbols; or variable, property or + // parameter symbols with declarations that have explicit type annotations. Such references are + // resolvable with no possibility of triggering circularities in control flow analysis. if (node.kind === SyntaxKind.Identifier) { const symbol = getResolvedSymbol(node); - const nonAliasSymbol = symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol; - return nonAliasSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.ValueModule) ? getTypeOfSymbol(nonAliasSymbol) : undefined; + return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); } if (node.kind === SyntaxKind.PropertyAccessExpression) { const type = getTypeOfDottedName((node).expression); if (type) { const prop = getPropertyOfType(type, (node).name.escapedText); - return prop && prop.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.ValueModule) ? getTypeOfSymbol(prop) : undefined; + return prop && getExplicitTypeOfSymbol(prop); } } } - function getIsAssertCall(node: CallExpression) { - const type = getTypeOfDottedName(node.expression); - if (type) { - const signature = getSingleCallSignature(type); - if (signature && signature.declaration) { - const typeNode = getEffectiveReturnTypeNode(signature.declaration); - if (typeNode && typeNode.kind === SyntaxKind.UnionType) { - const types = (typeNode).types; - return types.length === 2 && types[0].kind === SyntaxKind.VoidKeyword && types[1].kind === SyntaxKind.NeverKeyword; - } - } - } - return false; - } - - function isAssertCall(node: CallExpression) { + function getTypePredicateForCall(node: CallExpression) { const links = getNodeLinks(node); - if (links.isAssertCall === undefined) { - links.isAssertCall = getIsAssertCall(node); + if (links.resolvedTypePredicate === undefined) { + links.resolvedTypePredicate = computeTypePredicateForCall(node) || noTypePredicate; } - return links.isAssertCall; + return links.resolvedTypePredicate === noTypePredicate ? undefined : links.resolvedTypePredicate; + } + + function computeTypePredicateForCall(node: CallExpression) { + // A call expression parented by an expression statement is a potential assertion. Other call + // expressions are potential type predicate function calls. + const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression) : + node.expression.kind !== SyntaxKind.SuperKeyword ? checkNonNullExpression(node.expression) : + undefined; + if (funcType && funcType !== silentNeverType) { + const apparentType = getApparentType(funcType); + if (some(getSignaturesOfType(apparentType, SignatureKind.Call), hasTypePredicate)) { + return getTypePredicateOfSignature(getResolvedSignature(node)); + } + } + return undefined; + } + + function hasTypePredicate(signature: Signature) { + return !!getTypePredicateOfSignature(signature); } function reportFlowControlError(node: Node) { @@ -17116,14 +17102,14 @@ namespace ts { } function getTypeAtFlowCall(flow: FlowCall): FlowType | undefined { - if (isAssertCall(flow.node)) { + const predicate = getTypePredicateForCall(flow.node); + if (predicate && predicate.kind === TypePredicateKind.Assertion) { const flowType = getTypeAtFlowNode(flow.antecedent); const type = getTypeFromFlowType(flowType); - const narrowedType = narrowTypeByAssertion(type, flow.node.arguments[0]); - if (narrowedType === type) { - return flowType; - } - return createFlowType(narrowedType, isIncomplete(flowType)); + const narrowedType = predicate.type ? + narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) : + narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]); + return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType)); } return undefined; } @@ -17711,24 +17697,24 @@ namespace ts { getIntersectionType([type, candidate]); } - function narrowTypeByTypePredicate(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { - if (!hasMatchingArgument(callExpression, reference) || !maybeTypePredicateCall(callExpression)) { - return type; - } - const signature = getResolvedSignature(callExpression); - const predicate = getTypePredicateOfSignature(signature); - if (!predicate) { - return type; + function narrowTypeByCallExpression(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { + if (hasMatchingArgument(callExpression, reference)) { + const predicate = getTypePredicateForCall(callExpression); + if (predicate && predicate.kind !== TypePredicateKind.Assertion) { + return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue); + } } + return type; + } + function narrowTypeByTypePredicate(type: Type, predicate: TypePredicate, callExpression: CallExpression, assumeTrue: boolean): Type { // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function' if (isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType)) { return type; } - - if (isIdentifierTypePredicate(predicate)) { + if (predicate.kind !== TypePredicateKind.This) { const predicateArgument = callExpression.arguments[predicate.parameterIndex]; - if (predicateArgument) { + if (predicateArgument && predicate.type) { if (isMatchingReference(reference, predicateArgument)) { return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf); } @@ -17763,7 +17749,7 @@ namespace ts { case SyntaxKind.ElementAccessExpression: return narrowTypeByTruthiness(type, expr, assumeTrue); case SyntaxKind.CallExpression: - return narrowTypeByTypePredicate(type, expr, assumeTrue); + return narrowTypeByCallExpression(type, expr, assumeTrue); case SyntaxKind.ParenthesizedExpression: return narrowType(type, (expr).expression, assumeTrue); case SyntaxKind.BinaryExpression: @@ -25485,12 +25471,14 @@ namespace ts { error(parameterName, Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); } else { - const leadingError = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); - checkTypeAssignableTo(typePredicate.type, - getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]), - node.type, - /*headMessage*/ undefined, - leadingError); + if (typePredicate.type) { + const leadingError = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); + checkTypeAssignableTo(typePredicate.type, + getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]), + node.type, + /*headMessage*/ undefined, + leadingError); + } } } else if (parameterName) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8681a452e2a..415f8f9680c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1906,11 +1906,17 @@ namespace ts { // function emitTypePredicate(node: TypePredicateNode) { + if (node.assertsModifier) { + emit(node.assertsModifier); + writeSpace(); + } emit(node.parameterName); - writeSpace(); - writeKeyword("is"); - writeSpace(); - emit(node.type); + if (node.type) { + writeSpace(); + writeKeyword("is"); + writeSpace(); + emit(node.type); + } } function emitTypeReference(node: TypeReferenceNode) { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 1f0294423a5..166999a7059 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -667,17 +667,18 @@ namespace ts { return createSynthesizedNode(kind); } - export function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode) { + export function createTypePredicateNode(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { const node = createSynthesizedNode(SyntaxKind.TypePredicate) as TypePredicateNode; + node.assertsModifier = assertsModifier; node.parameterName = asName(parameterName); node.type = type; return node; } - export function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode) { + export function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) { return node.parameterName !== parameterName || node.type !== type - ? updateNode(createTypePredicateNode(parameterName, type), node) + ? updateNode(createTypePredicateNode(assertsModifier, parameterName, type), node) : node; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 254be93000b..3e0ea65476a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2992,6 +2992,8 @@ namespace ts { return parseParenthesizedType(); case SyntaxKind.ImportKeyword: return parseImportType(); + case SyntaxKind.AssertsKeyword: + return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? parseAssertsTypePredicate() : parseTypeReference(); default: return parseTypeReference(); } @@ -3032,6 +3034,7 @@ namespace ts { case SyntaxKind.DotDotDotToken: case SyntaxKind.InferKeyword: case SyntaxKind.ImportKeyword: + case SyntaxKind.AssertsKeyword: return true; case SyntaxKind.FunctionKeyword: return !inStartOfParameter; @@ -3225,6 +3228,16 @@ namespace ts { } } + function parseAssertsTypePredicate(): TypeNode { + const node = createNode(SyntaxKind.TypePredicate); + node.assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword); + node.parameterName = parseIdentifier(); + if (parseOptional(SyntaxKind.IsKeyword)) { + node.type = parseType(); + } + return finishNode(node); + } + function parseType(): TypeNode { // The rules about 'yield' only apply to actual code/expression contexts. They don't // apply to 'type' contexts. So we disable these parameters here before moving on. diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index f949893171a..31e54e283fe 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -65,6 +65,7 @@ namespace ts { abstract: SyntaxKind.AbstractKeyword, any: SyntaxKind.AnyKeyword, as: SyntaxKind.AsKeyword, + asserts: SyntaxKind.AssertsKeyword, bigint: SyntaxKind.BigIntKeyword, boolean: SyntaxKind.BooleanKeyword, break: SyntaxKind.BreakKeyword, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index aec65b03367..ba1ad79a8c2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -32,6 +32,7 @@ namespace ts { | SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword + | SyntaxKind.AssertsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword @@ -250,6 +251,7 @@ namespace ts { // Contextual keywords AbstractKeyword, AsKeyword, + AssertsKeyword, AnyKeyword, AsyncKeyword, AwaitKeyword, @@ -734,6 +736,7 @@ namespace ts { export type AwaitKeywordToken = Token; export type PlusToken = Token; export type MinusToken = Token; + export type AssertsToken = Token; export type Modifier = Token @@ -1177,8 +1180,9 @@ namespace ts { export interface TypePredicateNode extends TypeNode { kind: SyntaxKind.TypePredicate; parent: SignatureDeclaration | JSDocTypeExpression; + assertsModifier?: AssertsToken; parameterName: Identifier | ThisTypeNode; - type: TypeNode; + type?: TypeNode; } export interface TypeQueryNode extends TypeNode { @@ -3493,25 +3497,32 @@ namespace ts { export const enum TypePredicateKind { This, - Identifier + Identifier, + Assertion } - export interface TypePredicateBase { - kind: TypePredicateKind; + export interface ThisTypePredicate { + kind: TypePredicateKind.This; + parameterName: undefined; + parameterIndex: undefined; type: Type; } - export interface ThisTypePredicate extends TypePredicateBase { - kind: TypePredicateKind.This; - } - - export interface IdentifierTypePredicate extends TypePredicateBase { + export interface IdentifierTypePredicate { kind: TypePredicateKind.Identifier; parameterName: string; parameterIndex: number; + type: Type; } - export type TypePredicate = IdentifierTypePredicate | ThisTypePredicate; + export interface AssertionTypePredicate { + kind: TypePredicateKind.Assertion; + parameterName: string; + parameterIndex: number; + type: Type | undefined; + } + + export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertionTypePredicate; /* @internal */ export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration; @@ -3907,8 +3918,9 @@ namespace ts { resolvedSignature?: Signature; // Cached signature of signature node or call expression resolvedSymbol?: Symbol; // Cached name resolution result resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result - maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate - isAssertCall?: boolean; + //maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate + //isAssertCall?: boolean; + resolvedTypePredicate?: TypePredicate; // Cached type predicate for call expression enumMemberValue?: string | number; // Constant value of enum member isVisible?: boolean; // Is this node visible containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 53ccd81f7a6..aa497511f78 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -340,6 +340,7 @@ namespace ts { case SyntaxKind.TypePredicate: return updateTypePredicateNode(node, + visitNode((node).assertsModifier, visitor), visitNode((node).parameterName, visitor), visitNode((node).type, visitor, isTypeNode)); From 1f5bb970d987a7387a3531e1cea00f51b08fe20a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 3 Aug 2019 08:28:53 -0700 Subject: [PATCH 003/100] Remove unused code --- src/compiler/checker.ts | 10 ---------- src/compiler/types.ts | 2 -- 2 files changed, 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c8ad1f66064..7dfb0cd2757 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8670,16 +8670,6 @@ namespace ts { } } - // function hasAssertionTypePredicate(signature: Signature): boolean { - // const predicate = getTypePredicateOfSignature(signature); - // return !!predicate && predicate.kind === TypePredicateKind.Assertion; - // } - - // function hasBooleanTypePredicate(signature: Signature): boolean { - // const predicate = getTypePredicateOfSignature(signature); - // return !!predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier); - // } - function getTypePredicateOfSignature(signature: Signature): TypePredicate | undefined { if (!signature.resolvedTypePredicate) { if (signature.target) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ba1ad79a8c2..3cdfba2aafb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3918,8 +3918,6 @@ namespace ts { resolvedSignature?: Signature; // Cached signature of signature node or call expression resolvedSymbol?: Symbol; // Cached name resolution result resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result - //maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate - //isAssertCall?: boolean; resolvedTypePredicate?: TypePredicate; // Cached type predicate for call expression enumMemberValue?: string | number; // Constant value of enum member isVisible?: boolean; // Is this node visible From fe70a62ef1ef87d20a860c6bdea999cdfab76592 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 3 Aug 2019 08:55:55 -0700 Subject: [PATCH 004/100] Accept new API baselines --- .../reference/api/tsserverlibrary.d.ts | 465 +++++++++--------- tests/baselines/reference/api/typescript.d.ts | 465 +++++++++--------- 2 files changed, 480 insertions(+), 450 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index d73cbab6b5f..00c88fc4963 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -73,7 +73,7 @@ declare namespace ts { end: number; } export type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; - export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword; + export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword; export type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; export enum SyntaxKind { Unknown = 0, @@ -198,205 +198,206 @@ declare namespace ts { YieldKeyword = 118, AbstractKeyword = 119, AsKeyword = 120, - AnyKeyword = 121, - AsyncKeyword = 122, - AwaitKeyword = 123, - BooleanKeyword = 124, - ConstructorKeyword = 125, - DeclareKeyword = 126, - GetKeyword = 127, - InferKeyword = 128, - IsKeyword = 129, - KeyOfKeyword = 130, - ModuleKeyword = 131, - NamespaceKeyword = 132, - NeverKeyword = 133, - ReadonlyKeyword = 134, - RequireKeyword = 135, - NumberKeyword = 136, - ObjectKeyword = 137, - SetKeyword = 138, - StringKeyword = 139, - SymbolKeyword = 140, - TypeKeyword = 141, - UndefinedKeyword = 142, - UniqueKeyword = 143, - UnknownKeyword = 144, - FromKeyword = 145, - GlobalKeyword = 146, - BigIntKeyword = 147, - OfKeyword = 148, - QualifiedName = 149, - ComputedPropertyName = 150, - TypeParameter = 151, - Parameter = 152, - Decorator = 153, - PropertySignature = 154, - PropertyDeclaration = 155, - MethodSignature = 156, - MethodDeclaration = 157, - Constructor = 158, - GetAccessor = 159, - SetAccessor = 160, - CallSignature = 161, - ConstructSignature = 162, - IndexSignature = 163, - TypePredicate = 164, - TypeReference = 165, - FunctionType = 166, - ConstructorType = 167, - TypeQuery = 168, - TypeLiteral = 169, - ArrayType = 170, - TupleType = 171, - OptionalType = 172, - RestType = 173, - UnionType = 174, - IntersectionType = 175, - ConditionalType = 176, - InferType = 177, - ParenthesizedType = 178, - ThisType = 179, - TypeOperator = 180, - IndexedAccessType = 181, - MappedType = 182, - LiteralType = 183, - ImportType = 184, - ObjectBindingPattern = 185, - ArrayBindingPattern = 186, - BindingElement = 187, - ArrayLiteralExpression = 188, - ObjectLiteralExpression = 189, - PropertyAccessExpression = 190, - ElementAccessExpression = 191, - CallExpression = 192, - NewExpression = 193, - TaggedTemplateExpression = 194, - TypeAssertionExpression = 195, - ParenthesizedExpression = 196, - FunctionExpression = 197, - ArrowFunction = 198, - DeleteExpression = 199, - TypeOfExpression = 200, - VoidExpression = 201, - AwaitExpression = 202, - PrefixUnaryExpression = 203, - PostfixUnaryExpression = 204, - BinaryExpression = 205, - ConditionalExpression = 206, - TemplateExpression = 207, - YieldExpression = 208, - SpreadElement = 209, - ClassExpression = 210, - OmittedExpression = 211, - ExpressionWithTypeArguments = 212, - AsExpression = 213, - NonNullExpression = 214, - MetaProperty = 215, - SyntheticExpression = 216, - TemplateSpan = 217, - SemicolonClassElement = 218, - Block = 219, - VariableStatement = 220, - EmptyStatement = 221, - ExpressionStatement = 222, - IfStatement = 223, - DoStatement = 224, - WhileStatement = 225, - ForStatement = 226, - ForInStatement = 227, - ForOfStatement = 228, - ContinueStatement = 229, - BreakStatement = 230, - ReturnStatement = 231, - WithStatement = 232, - SwitchStatement = 233, - LabeledStatement = 234, - ThrowStatement = 235, - TryStatement = 236, - DebuggerStatement = 237, - VariableDeclaration = 238, - VariableDeclarationList = 239, - FunctionDeclaration = 240, - ClassDeclaration = 241, - InterfaceDeclaration = 242, - TypeAliasDeclaration = 243, - EnumDeclaration = 244, - ModuleDeclaration = 245, - ModuleBlock = 246, - CaseBlock = 247, - NamespaceExportDeclaration = 248, - ImportEqualsDeclaration = 249, - ImportDeclaration = 250, - ImportClause = 251, - NamespaceImport = 252, - NamedImports = 253, - ImportSpecifier = 254, - ExportAssignment = 255, - ExportDeclaration = 256, - NamedExports = 257, - ExportSpecifier = 258, - MissingDeclaration = 259, - ExternalModuleReference = 260, - JsxElement = 261, - JsxSelfClosingElement = 262, - JsxOpeningElement = 263, - JsxClosingElement = 264, - JsxFragment = 265, - JsxOpeningFragment = 266, - JsxClosingFragment = 267, - JsxAttribute = 268, - JsxAttributes = 269, - JsxSpreadAttribute = 270, - JsxExpression = 271, - CaseClause = 272, - DefaultClause = 273, - HeritageClause = 274, - CatchClause = 275, - PropertyAssignment = 276, - ShorthandPropertyAssignment = 277, - SpreadAssignment = 278, - EnumMember = 279, - UnparsedPrologue = 280, - UnparsedPrepend = 281, - UnparsedText = 282, - UnparsedInternalText = 283, - UnparsedSyntheticReference = 284, - SourceFile = 285, - Bundle = 286, - UnparsedSource = 287, - InputFiles = 288, - JSDocTypeExpression = 289, - JSDocAllType = 290, - JSDocUnknownType = 291, - JSDocNullableType = 292, - JSDocNonNullableType = 293, - JSDocOptionalType = 294, - JSDocFunctionType = 295, - JSDocVariadicType = 296, - JSDocComment = 297, - JSDocTypeLiteral = 298, - JSDocSignature = 299, - JSDocTag = 300, - JSDocAugmentsTag = 301, - JSDocAuthorTag = 302, - JSDocClassTag = 303, - JSDocCallbackTag = 304, - JSDocEnumTag = 305, - JSDocParameterTag = 306, - JSDocReturnTag = 307, - JSDocThisTag = 308, - JSDocTypeTag = 309, - JSDocTemplateTag = 310, - JSDocTypedefTag = 311, - JSDocPropertyTag = 312, - SyntaxList = 313, - NotEmittedStatement = 314, - PartiallyEmittedExpression = 315, - CommaListExpression = 316, - MergeDeclarationMarker = 317, - EndOfDeclarationMarker = 318, - Count = 319, + AssertsKeyword = 121, + AnyKeyword = 122, + AsyncKeyword = 123, + AwaitKeyword = 124, + BooleanKeyword = 125, + ConstructorKeyword = 126, + DeclareKeyword = 127, + GetKeyword = 128, + InferKeyword = 129, + IsKeyword = 130, + KeyOfKeyword = 131, + ModuleKeyword = 132, + NamespaceKeyword = 133, + NeverKeyword = 134, + ReadonlyKeyword = 135, + RequireKeyword = 136, + NumberKeyword = 137, + ObjectKeyword = 138, + SetKeyword = 139, + StringKeyword = 140, + SymbolKeyword = 141, + TypeKeyword = 142, + UndefinedKeyword = 143, + UniqueKeyword = 144, + UnknownKeyword = 145, + FromKeyword = 146, + GlobalKeyword = 147, + BigIntKeyword = 148, + OfKeyword = 149, + QualifiedName = 150, + ComputedPropertyName = 151, + TypeParameter = 152, + Parameter = 153, + Decorator = 154, + PropertySignature = 155, + PropertyDeclaration = 156, + MethodSignature = 157, + MethodDeclaration = 158, + Constructor = 159, + GetAccessor = 160, + SetAccessor = 161, + CallSignature = 162, + ConstructSignature = 163, + IndexSignature = 164, + TypePredicate = 165, + TypeReference = 166, + FunctionType = 167, + ConstructorType = 168, + TypeQuery = 169, + TypeLiteral = 170, + ArrayType = 171, + TupleType = 172, + OptionalType = 173, + RestType = 174, + UnionType = 175, + IntersectionType = 176, + ConditionalType = 177, + InferType = 178, + ParenthesizedType = 179, + ThisType = 180, + TypeOperator = 181, + IndexedAccessType = 182, + MappedType = 183, + LiteralType = 184, + ImportType = 185, + ObjectBindingPattern = 186, + ArrayBindingPattern = 187, + BindingElement = 188, + ArrayLiteralExpression = 189, + ObjectLiteralExpression = 190, + PropertyAccessExpression = 191, + ElementAccessExpression = 192, + CallExpression = 193, + NewExpression = 194, + TaggedTemplateExpression = 195, + TypeAssertionExpression = 196, + ParenthesizedExpression = 197, + FunctionExpression = 198, + ArrowFunction = 199, + DeleteExpression = 200, + TypeOfExpression = 201, + VoidExpression = 202, + AwaitExpression = 203, + PrefixUnaryExpression = 204, + PostfixUnaryExpression = 205, + BinaryExpression = 206, + ConditionalExpression = 207, + TemplateExpression = 208, + YieldExpression = 209, + SpreadElement = 210, + ClassExpression = 211, + OmittedExpression = 212, + ExpressionWithTypeArguments = 213, + AsExpression = 214, + NonNullExpression = 215, + MetaProperty = 216, + SyntheticExpression = 217, + TemplateSpan = 218, + SemicolonClassElement = 219, + Block = 220, + VariableStatement = 221, + EmptyStatement = 222, + ExpressionStatement = 223, + IfStatement = 224, + DoStatement = 225, + WhileStatement = 226, + ForStatement = 227, + ForInStatement = 228, + ForOfStatement = 229, + ContinueStatement = 230, + BreakStatement = 231, + ReturnStatement = 232, + WithStatement = 233, + SwitchStatement = 234, + LabeledStatement = 235, + ThrowStatement = 236, + TryStatement = 237, + DebuggerStatement = 238, + VariableDeclaration = 239, + VariableDeclarationList = 240, + FunctionDeclaration = 241, + ClassDeclaration = 242, + InterfaceDeclaration = 243, + TypeAliasDeclaration = 244, + EnumDeclaration = 245, + ModuleDeclaration = 246, + ModuleBlock = 247, + CaseBlock = 248, + NamespaceExportDeclaration = 249, + ImportEqualsDeclaration = 250, + ImportDeclaration = 251, + ImportClause = 252, + NamespaceImport = 253, + NamedImports = 254, + ImportSpecifier = 255, + ExportAssignment = 256, + ExportDeclaration = 257, + NamedExports = 258, + ExportSpecifier = 259, + MissingDeclaration = 260, + ExternalModuleReference = 261, + JsxElement = 262, + JsxSelfClosingElement = 263, + JsxOpeningElement = 264, + JsxClosingElement = 265, + JsxFragment = 266, + JsxOpeningFragment = 267, + JsxClosingFragment = 268, + JsxAttribute = 269, + JsxAttributes = 270, + JsxSpreadAttribute = 271, + JsxExpression = 272, + CaseClause = 273, + DefaultClause = 274, + HeritageClause = 275, + CatchClause = 276, + PropertyAssignment = 277, + ShorthandPropertyAssignment = 278, + SpreadAssignment = 279, + EnumMember = 280, + UnparsedPrologue = 281, + UnparsedPrepend = 282, + UnparsedText = 283, + UnparsedInternalText = 284, + UnparsedSyntheticReference = 285, + SourceFile = 286, + Bundle = 287, + UnparsedSource = 288, + InputFiles = 289, + JSDocTypeExpression = 290, + JSDocAllType = 291, + JSDocUnknownType = 292, + JSDocNullableType = 293, + JSDocNonNullableType = 294, + JSDocOptionalType = 295, + JSDocFunctionType = 296, + JSDocVariadicType = 297, + JSDocComment = 298, + JSDocTypeLiteral = 299, + JSDocSignature = 300, + JSDocTag = 301, + JSDocAugmentsTag = 302, + JSDocAuthorTag = 303, + JSDocClassTag = 304, + JSDocCallbackTag = 305, + JSDocEnumTag = 306, + JSDocParameterTag = 307, + JSDocReturnTag = 308, + JSDocThisTag = 309, + JSDocTypeTag = 310, + JSDocTemplateTag = 311, + JSDocTypedefTag = 312, + JSDocPropertyTag = 313, + SyntaxList = 314, + NotEmittedStatement = 315, + PartiallyEmittedExpression = 316, + CommaListExpression = 317, + MergeDeclarationMarker = 318, + EndOfDeclarationMarker = 319, + Count = 320, FirstAssignment = 60, LastAssignment = 72, FirstCompoundAssignment = 61, @@ -404,15 +405,15 @@ declare namespace ts { FirstReservedWord = 74, LastReservedWord = 109, FirstKeyword = 74, - LastKeyword = 148, + LastKeyword = 149, FirstFutureReservedWord = 110, LastFutureReservedWord = 118, - FirstTypeNode = 164, - LastTypeNode = 184, + FirstTypeNode = 165, + LastTypeNode = 185, FirstPunctuation = 18, LastPunctuation = 72, FirstToken = 0, - LastToken = 148, + LastToken = 149, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -421,11 +422,11 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 28, LastBinaryOperator = 72, - FirstNode = 149, - FirstJSDocNode = 289, - LastJSDocNode = 312, - FirstJSDocTagNode = 300, - LastJSDocTagNode = 312, + FirstNode = 150, + FirstJSDocNode = 290, + LastJSDocNode = 313, + FirstJSDocTagNode = 301, + LastJSDocTagNode = 313, } export enum NodeFlags { None = 0, @@ -516,6 +517,7 @@ declare namespace ts { export type AwaitKeywordToken = Token; export type PlusToken = Token; export type MinusToken = Token; + export type AssertsToken = Token; export type Modifier = Token | Token | Token | Token | Token | Token | Token | Token | Token | Token | Token; export type ModifiersArray = NodeArray; export interface Identifier extends PrimaryExpression, Declaration { @@ -769,8 +771,9 @@ declare namespace ts { export interface TypePredicateNode extends TypeNode { kind: SyntaxKind.TypePredicate; parent: SignatureDeclaration | JSDocTypeExpression; + assertsModifier?: AssertsToken; parameterName: Identifier | ThisTypeNode; - type: TypeNode; + type?: TypeNode; } export interface TypeQueryNode extends TypeNode { kind: SyntaxKind.TypeQuery; @@ -1661,10 +1664,11 @@ declare namespace ts { FalseCondition = 64, SwitchClause = 128, ArrayMutation = 256, - Referenced = 512, - Shared = 1024, - PreFinally = 2048, - AfterFinally = 4096, + Call = 512, + Referenced = 1024, + Shared = 2048, + PreFinally = 4096, + AfterFinally = 8192, Label = 12, Condition = 96 } @@ -1678,7 +1682,7 @@ declare namespace ts { antecedent: FlowNode; lock: FlowLock; } - export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation; + export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; export interface FlowNodeBase { flags: FlowFlags; id?: number; @@ -1693,6 +1697,10 @@ declare namespace ts { node: Expression | VariableDeclaration | BindingElement; antecedent: FlowNode; } + export interface FlowCall extends FlowNodeBase { + node: CallExpression; + antecedent: FlowNode; + } export interface FlowCondition extends FlowNodeBase { expression: Expression; antecedent: FlowNode; @@ -2080,21 +2088,28 @@ declare namespace ts { } export enum TypePredicateKind { This = 0, - Identifier = 1 + Identifier = 1, + Assertion = 2 } - export interface TypePredicateBase { - kind: TypePredicateKind; + export interface ThisTypePredicate { + kind: TypePredicateKind.This; + parameterName: undefined; + parameterIndex: undefined; type: Type; } - export interface ThisTypePredicate extends TypePredicateBase { - kind: TypePredicateKind.This; - } - export interface IdentifierTypePredicate extends TypePredicateBase { + export interface IdentifierTypePredicate { kind: TypePredicateKind.Identifier; parameterName: string; parameterIndex: number; + type: Type; } - export type TypePredicate = IdentifierTypePredicate | ThisTypePredicate; + export interface AssertionTypePredicate { + kind: TypePredicateKind.Assertion; + parameterName: string; + parameterIndex: number; + type: Type | undefined; + } + export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertionTypePredicate; export enum SymbolFlags { None = 0, FunctionScopedVariable = 1, @@ -3823,8 +3838,8 @@ declare namespace ts { function createIndexSignature(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function updateIndexSignature(node: IndexSignatureDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode; - function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode; - function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode; + function createTypePredicateNode(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined): TypeReferenceNode; function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; function createFunctionTypeNode(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): FunctionTypeNode; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 1bb693c0845..df8d0e1ee79 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -73,7 +73,7 @@ declare namespace ts { end: number; } export type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.Unknown | KeywordSyntaxKind; - export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword; + export type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InKeyword | SyntaxKind.InferKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.RequireKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.OfKeyword; export type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; export enum SyntaxKind { Unknown = 0, @@ -198,205 +198,206 @@ declare namespace ts { YieldKeyword = 118, AbstractKeyword = 119, AsKeyword = 120, - AnyKeyword = 121, - AsyncKeyword = 122, - AwaitKeyword = 123, - BooleanKeyword = 124, - ConstructorKeyword = 125, - DeclareKeyword = 126, - GetKeyword = 127, - InferKeyword = 128, - IsKeyword = 129, - KeyOfKeyword = 130, - ModuleKeyword = 131, - NamespaceKeyword = 132, - NeverKeyword = 133, - ReadonlyKeyword = 134, - RequireKeyword = 135, - NumberKeyword = 136, - ObjectKeyword = 137, - SetKeyword = 138, - StringKeyword = 139, - SymbolKeyword = 140, - TypeKeyword = 141, - UndefinedKeyword = 142, - UniqueKeyword = 143, - UnknownKeyword = 144, - FromKeyword = 145, - GlobalKeyword = 146, - BigIntKeyword = 147, - OfKeyword = 148, - QualifiedName = 149, - ComputedPropertyName = 150, - TypeParameter = 151, - Parameter = 152, - Decorator = 153, - PropertySignature = 154, - PropertyDeclaration = 155, - MethodSignature = 156, - MethodDeclaration = 157, - Constructor = 158, - GetAccessor = 159, - SetAccessor = 160, - CallSignature = 161, - ConstructSignature = 162, - IndexSignature = 163, - TypePredicate = 164, - TypeReference = 165, - FunctionType = 166, - ConstructorType = 167, - TypeQuery = 168, - TypeLiteral = 169, - ArrayType = 170, - TupleType = 171, - OptionalType = 172, - RestType = 173, - UnionType = 174, - IntersectionType = 175, - ConditionalType = 176, - InferType = 177, - ParenthesizedType = 178, - ThisType = 179, - TypeOperator = 180, - IndexedAccessType = 181, - MappedType = 182, - LiteralType = 183, - ImportType = 184, - ObjectBindingPattern = 185, - ArrayBindingPattern = 186, - BindingElement = 187, - ArrayLiteralExpression = 188, - ObjectLiteralExpression = 189, - PropertyAccessExpression = 190, - ElementAccessExpression = 191, - CallExpression = 192, - NewExpression = 193, - TaggedTemplateExpression = 194, - TypeAssertionExpression = 195, - ParenthesizedExpression = 196, - FunctionExpression = 197, - ArrowFunction = 198, - DeleteExpression = 199, - TypeOfExpression = 200, - VoidExpression = 201, - AwaitExpression = 202, - PrefixUnaryExpression = 203, - PostfixUnaryExpression = 204, - BinaryExpression = 205, - ConditionalExpression = 206, - TemplateExpression = 207, - YieldExpression = 208, - SpreadElement = 209, - ClassExpression = 210, - OmittedExpression = 211, - ExpressionWithTypeArguments = 212, - AsExpression = 213, - NonNullExpression = 214, - MetaProperty = 215, - SyntheticExpression = 216, - TemplateSpan = 217, - SemicolonClassElement = 218, - Block = 219, - VariableStatement = 220, - EmptyStatement = 221, - ExpressionStatement = 222, - IfStatement = 223, - DoStatement = 224, - WhileStatement = 225, - ForStatement = 226, - ForInStatement = 227, - ForOfStatement = 228, - ContinueStatement = 229, - BreakStatement = 230, - ReturnStatement = 231, - WithStatement = 232, - SwitchStatement = 233, - LabeledStatement = 234, - ThrowStatement = 235, - TryStatement = 236, - DebuggerStatement = 237, - VariableDeclaration = 238, - VariableDeclarationList = 239, - FunctionDeclaration = 240, - ClassDeclaration = 241, - InterfaceDeclaration = 242, - TypeAliasDeclaration = 243, - EnumDeclaration = 244, - ModuleDeclaration = 245, - ModuleBlock = 246, - CaseBlock = 247, - NamespaceExportDeclaration = 248, - ImportEqualsDeclaration = 249, - ImportDeclaration = 250, - ImportClause = 251, - NamespaceImport = 252, - NamedImports = 253, - ImportSpecifier = 254, - ExportAssignment = 255, - ExportDeclaration = 256, - NamedExports = 257, - ExportSpecifier = 258, - MissingDeclaration = 259, - ExternalModuleReference = 260, - JsxElement = 261, - JsxSelfClosingElement = 262, - JsxOpeningElement = 263, - JsxClosingElement = 264, - JsxFragment = 265, - JsxOpeningFragment = 266, - JsxClosingFragment = 267, - JsxAttribute = 268, - JsxAttributes = 269, - JsxSpreadAttribute = 270, - JsxExpression = 271, - CaseClause = 272, - DefaultClause = 273, - HeritageClause = 274, - CatchClause = 275, - PropertyAssignment = 276, - ShorthandPropertyAssignment = 277, - SpreadAssignment = 278, - EnumMember = 279, - UnparsedPrologue = 280, - UnparsedPrepend = 281, - UnparsedText = 282, - UnparsedInternalText = 283, - UnparsedSyntheticReference = 284, - SourceFile = 285, - Bundle = 286, - UnparsedSource = 287, - InputFiles = 288, - JSDocTypeExpression = 289, - JSDocAllType = 290, - JSDocUnknownType = 291, - JSDocNullableType = 292, - JSDocNonNullableType = 293, - JSDocOptionalType = 294, - JSDocFunctionType = 295, - JSDocVariadicType = 296, - JSDocComment = 297, - JSDocTypeLiteral = 298, - JSDocSignature = 299, - JSDocTag = 300, - JSDocAugmentsTag = 301, - JSDocAuthorTag = 302, - JSDocClassTag = 303, - JSDocCallbackTag = 304, - JSDocEnumTag = 305, - JSDocParameterTag = 306, - JSDocReturnTag = 307, - JSDocThisTag = 308, - JSDocTypeTag = 309, - JSDocTemplateTag = 310, - JSDocTypedefTag = 311, - JSDocPropertyTag = 312, - SyntaxList = 313, - NotEmittedStatement = 314, - PartiallyEmittedExpression = 315, - CommaListExpression = 316, - MergeDeclarationMarker = 317, - EndOfDeclarationMarker = 318, - Count = 319, + AssertsKeyword = 121, + AnyKeyword = 122, + AsyncKeyword = 123, + AwaitKeyword = 124, + BooleanKeyword = 125, + ConstructorKeyword = 126, + DeclareKeyword = 127, + GetKeyword = 128, + InferKeyword = 129, + IsKeyword = 130, + KeyOfKeyword = 131, + ModuleKeyword = 132, + NamespaceKeyword = 133, + NeverKeyword = 134, + ReadonlyKeyword = 135, + RequireKeyword = 136, + NumberKeyword = 137, + ObjectKeyword = 138, + SetKeyword = 139, + StringKeyword = 140, + SymbolKeyword = 141, + TypeKeyword = 142, + UndefinedKeyword = 143, + UniqueKeyword = 144, + UnknownKeyword = 145, + FromKeyword = 146, + GlobalKeyword = 147, + BigIntKeyword = 148, + OfKeyword = 149, + QualifiedName = 150, + ComputedPropertyName = 151, + TypeParameter = 152, + Parameter = 153, + Decorator = 154, + PropertySignature = 155, + PropertyDeclaration = 156, + MethodSignature = 157, + MethodDeclaration = 158, + Constructor = 159, + GetAccessor = 160, + SetAccessor = 161, + CallSignature = 162, + ConstructSignature = 163, + IndexSignature = 164, + TypePredicate = 165, + TypeReference = 166, + FunctionType = 167, + ConstructorType = 168, + TypeQuery = 169, + TypeLiteral = 170, + ArrayType = 171, + TupleType = 172, + OptionalType = 173, + RestType = 174, + UnionType = 175, + IntersectionType = 176, + ConditionalType = 177, + InferType = 178, + ParenthesizedType = 179, + ThisType = 180, + TypeOperator = 181, + IndexedAccessType = 182, + MappedType = 183, + LiteralType = 184, + ImportType = 185, + ObjectBindingPattern = 186, + ArrayBindingPattern = 187, + BindingElement = 188, + ArrayLiteralExpression = 189, + ObjectLiteralExpression = 190, + PropertyAccessExpression = 191, + ElementAccessExpression = 192, + CallExpression = 193, + NewExpression = 194, + TaggedTemplateExpression = 195, + TypeAssertionExpression = 196, + ParenthesizedExpression = 197, + FunctionExpression = 198, + ArrowFunction = 199, + DeleteExpression = 200, + TypeOfExpression = 201, + VoidExpression = 202, + AwaitExpression = 203, + PrefixUnaryExpression = 204, + PostfixUnaryExpression = 205, + BinaryExpression = 206, + ConditionalExpression = 207, + TemplateExpression = 208, + YieldExpression = 209, + SpreadElement = 210, + ClassExpression = 211, + OmittedExpression = 212, + ExpressionWithTypeArguments = 213, + AsExpression = 214, + NonNullExpression = 215, + MetaProperty = 216, + SyntheticExpression = 217, + TemplateSpan = 218, + SemicolonClassElement = 219, + Block = 220, + VariableStatement = 221, + EmptyStatement = 222, + ExpressionStatement = 223, + IfStatement = 224, + DoStatement = 225, + WhileStatement = 226, + ForStatement = 227, + ForInStatement = 228, + ForOfStatement = 229, + ContinueStatement = 230, + BreakStatement = 231, + ReturnStatement = 232, + WithStatement = 233, + SwitchStatement = 234, + LabeledStatement = 235, + ThrowStatement = 236, + TryStatement = 237, + DebuggerStatement = 238, + VariableDeclaration = 239, + VariableDeclarationList = 240, + FunctionDeclaration = 241, + ClassDeclaration = 242, + InterfaceDeclaration = 243, + TypeAliasDeclaration = 244, + EnumDeclaration = 245, + ModuleDeclaration = 246, + ModuleBlock = 247, + CaseBlock = 248, + NamespaceExportDeclaration = 249, + ImportEqualsDeclaration = 250, + ImportDeclaration = 251, + ImportClause = 252, + NamespaceImport = 253, + NamedImports = 254, + ImportSpecifier = 255, + ExportAssignment = 256, + ExportDeclaration = 257, + NamedExports = 258, + ExportSpecifier = 259, + MissingDeclaration = 260, + ExternalModuleReference = 261, + JsxElement = 262, + JsxSelfClosingElement = 263, + JsxOpeningElement = 264, + JsxClosingElement = 265, + JsxFragment = 266, + JsxOpeningFragment = 267, + JsxClosingFragment = 268, + JsxAttribute = 269, + JsxAttributes = 270, + JsxSpreadAttribute = 271, + JsxExpression = 272, + CaseClause = 273, + DefaultClause = 274, + HeritageClause = 275, + CatchClause = 276, + PropertyAssignment = 277, + ShorthandPropertyAssignment = 278, + SpreadAssignment = 279, + EnumMember = 280, + UnparsedPrologue = 281, + UnparsedPrepend = 282, + UnparsedText = 283, + UnparsedInternalText = 284, + UnparsedSyntheticReference = 285, + SourceFile = 286, + Bundle = 287, + UnparsedSource = 288, + InputFiles = 289, + JSDocTypeExpression = 290, + JSDocAllType = 291, + JSDocUnknownType = 292, + JSDocNullableType = 293, + JSDocNonNullableType = 294, + JSDocOptionalType = 295, + JSDocFunctionType = 296, + JSDocVariadicType = 297, + JSDocComment = 298, + JSDocTypeLiteral = 299, + JSDocSignature = 300, + JSDocTag = 301, + JSDocAugmentsTag = 302, + JSDocAuthorTag = 303, + JSDocClassTag = 304, + JSDocCallbackTag = 305, + JSDocEnumTag = 306, + JSDocParameterTag = 307, + JSDocReturnTag = 308, + JSDocThisTag = 309, + JSDocTypeTag = 310, + JSDocTemplateTag = 311, + JSDocTypedefTag = 312, + JSDocPropertyTag = 313, + SyntaxList = 314, + NotEmittedStatement = 315, + PartiallyEmittedExpression = 316, + CommaListExpression = 317, + MergeDeclarationMarker = 318, + EndOfDeclarationMarker = 319, + Count = 320, FirstAssignment = 60, LastAssignment = 72, FirstCompoundAssignment = 61, @@ -404,15 +405,15 @@ declare namespace ts { FirstReservedWord = 74, LastReservedWord = 109, FirstKeyword = 74, - LastKeyword = 148, + LastKeyword = 149, FirstFutureReservedWord = 110, LastFutureReservedWord = 118, - FirstTypeNode = 164, - LastTypeNode = 184, + FirstTypeNode = 165, + LastTypeNode = 185, FirstPunctuation = 18, LastPunctuation = 72, FirstToken = 0, - LastToken = 148, + LastToken = 149, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -421,11 +422,11 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 28, LastBinaryOperator = 72, - FirstNode = 149, - FirstJSDocNode = 289, - LastJSDocNode = 312, - FirstJSDocTagNode = 300, - LastJSDocTagNode = 312, + FirstNode = 150, + FirstJSDocNode = 290, + LastJSDocNode = 313, + FirstJSDocTagNode = 301, + LastJSDocTagNode = 313, } export enum NodeFlags { None = 0, @@ -516,6 +517,7 @@ declare namespace ts { export type AwaitKeywordToken = Token; export type PlusToken = Token; export type MinusToken = Token; + export type AssertsToken = Token; export type Modifier = Token | Token | Token | Token | Token | Token | Token | Token | Token | Token | Token; export type ModifiersArray = NodeArray; export interface Identifier extends PrimaryExpression, Declaration { @@ -769,8 +771,9 @@ declare namespace ts { export interface TypePredicateNode extends TypeNode { kind: SyntaxKind.TypePredicate; parent: SignatureDeclaration | JSDocTypeExpression; + assertsModifier?: AssertsToken; parameterName: Identifier | ThisTypeNode; - type: TypeNode; + type?: TypeNode; } export interface TypeQueryNode extends TypeNode { kind: SyntaxKind.TypeQuery; @@ -1661,10 +1664,11 @@ declare namespace ts { FalseCondition = 64, SwitchClause = 128, ArrayMutation = 256, - Referenced = 512, - Shared = 1024, - PreFinally = 2048, - AfterFinally = 4096, + Call = 512, + Referenced = 1024, + Shared = 2048, + PreFinally = 4096, + AfterFinally = 8192, Label = 12, Condition = 96 } @@ -1678,7 +1682,7 @@ declare namespace ts { antecedent: FlowNode; lock: FlowLock; } - export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCondition | FlowSwitchClause | FlowArrayMutation; + export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; export interface FlowNodeBase { flags: FlowFlags; id?: number; @@ -1693,6 +1697,10 @@ declare namespace ts { node: Expression | VariableDeclaration | BindingElement; antecedent: FlowNode; } + export interface FlowCall extends FlowNodeBase { + node: CallExpression; + antecedent: FlowNode; + } export interface FlowCondition extends FlowNodeBase { expression: Expression; antecedent: FlowNode; @@ -2080,21 +2088,28 @@ declare namespace ts { } export enum TypePredicateKind { This = 0, - Identifier = 1 + Identifier = 1, + Assertion = 2 } - export interface TypePredicateBase { - kind: TypePredicateKind; + export interface ThisTypePredicate { + kind: TypePredicateKind.This; + parameterName: undefined; + parameterIndex: undefined; type: Type; } - export interface ThisTypePredicate extends TypePredicateBase { - kind: TypePredicateKind.This; - } - export interface IdentifierTypePredicate extends TypePredicateBase { + export interface IdentifierTypePredicate { kind: TypePredicateKind.Identifier; parameterName: string; parameterIndex: number; + type: Type; } - export type TypePredicate = IdentifierTypePredicate | ThisTypePredicate; + export interface AssertionTypePredicate { + kind: TypePredicateKind.Assertion; + parameterName: string; + parameterIndex: number; + type: Type | undefined; + } + export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertionTypePredicate; export enum SymbolFlags { None = 0, FunctionScopedVariable = 1, @@ -3823,8 +3838,8 @@ declare namespace ts { function createIndexSignature(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function updateIndexSignature(node: IndexSignatureDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode; - function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode): TypePredicateNode; - function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode): TypePredicateNode; + function createTypePredicateNode(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined): TypeReferenceNode; function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; function createFunctionTypeNode(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): FunctionTypeNode; From 1c55e5de69c581da19184c1b9bfa08c800d1bb7c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 5 Aug 2019 08:27:54 +0200 Subject: [PATCH 005/100] Address code review feedback --- src/compiler/binder.ts | 3 ++- src/compiler/checker.ts | 22 ++++++++++++---------- src/compiler/parser.ts | 5 ++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2b917bc577c..e48943d3c83 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1285,7 +1285,8 @@ namespace ts { } function isDottedName(node: Expression): boolean { - return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((node).expression); + return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || + node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((node).expression); } function bindExpressionStatement(node: ExpressionStatement): void { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7dfb0cd2757..66aa107c561 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16838,16 +16838,18 @@ namespace ts { // that reference function, method, class or value module symbols; or variable, property or // parameter symbols with declarations that have explicit type annotations. Such references are // resolvable with no possibility of triggering circularities in control flow analysis. - if (node.kind === SyntaxKind.Identifier) { - const symbol = getResolvedSymbol(node); - return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); - } - if (node.kind === SyntaxKind.PropertyAccessExpression) { - const type = getTypeOfDottedName((node).expression); - if (type) { - const prop = getPropertyOfType(type, (node).name.escapedText); - return prop && getExplicitTypeOfSymbol(prop); - } + switch (node.kind) { + case SyntaxKind.Identifier: + const symbol = getResolvedSymbol(node); + return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); + case SyntaxKind.ThisKeyword: + return checkThisExpression(node); + case SyntaxKind.PropertyAccessExpression: + const type = getTypeOfDottedName((node).expression); + if (type) { + const prop = getPropertyOfType(type, (node).name.escapedText); + return prop && getExplicitTypeOfSymbol(prop); + } } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3e0ea65476a..6dc0235a7d0 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3211,6 +3211,7 @@ namespace ts { const type = parseType(); if (typePredicateVariable) { const node = createNode(SyntaxKind.TypePredicate, typePredicateVariable.pos); + node.assertsModifier = undefined; node.parameterName = typePredicateVariable; node.type = type; return finishNode(node); @@ -3232,9 +3233,7 @@ namespace ts { const node = createNode(SyntaxKind.TypePredicate); node.assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword); node.parameterName = parseIdentifier(); - if (parseOptional(SyntaxKind.IsKeyword)) { - node.type = parseType(); - } + node.type = parseOptional(SyntaxKind.IsKeyword) ? parseType() : undefined; return finishNode(node); } From df02ad6e59b0f3388f6644688303b4419f6e771a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 8 Aug 2019 10:48:45 +0200 Subject: [PATCH 006/100] Reflect control flow effects of calls to never-returning functions --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 76 ++++++++++++++++++++--------------------- src/compiler/types.ts | 2 +- 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e48943d3c83..8e004b125ab 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1295,7 +1295,7 @@ namespace ts { // is potentially an assertion and is therefore included in the control flow. if (node.expression.kind === SyntaxKind.CallExpression) { const call = node.expression; - if (isDottedName(call.expression) && call.arguments.length >= 1) { + if (isDottedName(call.expression)) { currentFlow = createFlowCall(currentFlow, call); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 66aa107c561..01de800c7c8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16853,31 +16853,23 @@ namespace ts { } } - function getTypePredicateForCall(node: CallExpression) { + function isCallWithEffects(node: CallExpression) { const links = getNodeLinks(node); - if (links.resolvedTypePredicate === undefined) { - links.resolvedTypePredicate = computeTypePredicateForCall(node) || noTypePredicate; + if (links.isCallWithEffects === undefined) { + // A call expression parented by an expression statement is a potential assertion. Other call + // expressions are potential type predicate function calls. + const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression) : + node.expression.kind !== SyntaxKind.SuperKeyword ? checkNonNullExpression(node.expression) : + undefined; + const apparentType = funcType && getApparentType(funcType) || unknownType; + links.isCallWithEffects = some(getSignaturesOfType(apparentType, SignatureKind.Call), hasTypePredicateOrNeverReturnType); } - return links.resolvedTypePredicate === noTypePredicate ? undefined : links.resolvedTypePredicate; + return links.isCallWithEffects; } - function computeTypePredicateForCall(node: CallExpression) { - // A call expression parented by an expression statement is a potential assertion. Other call - // expressions are potential type predicate function calls. - const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression) : - node.expression.kind !== SyntaxKind.SuperKeyword ? checkNonNullExpression(node.expression) : - undefined; - if (funcType && funcType !== silentNeverType) { - const apparentType = getApparentType(funcType); - if (some(getSignaturesOfType(apparentType, SignatureKind.Call), hasTypePredicate)) { - return getTypePredicateOfSignature(getResolvedSignature(node)); - } - } - return undefined; - } - - function hasTypePredicate(signature: Signature) { - return !!getTypePredicateOfSignature(signature); + function hasTypePredicateOrNeverReturnType(signature: Signature) { + return !!(getTypePredicateOfSignature(signature) || + signature.declaration && (getReturnTypeFromAnnotation(signature.declaration) || unknownType).flags & TypeFlags.Never); } function reportFlowControlError(node: Node) { @@ -17094,14 +17086,20 @@ namespace ts { } function getTypeAtFlowCall(flow: FlowCall): FlowType | undefined { - const predicate = getTypePredicateForCall(flow.node); - if (predicate && predicate.kind === TypePredicateKind.Assertion) { - const flowType = getTypeAtFlowNode(flow.antecedent); - const type = getTypeFromFlowType(flowType); - const narrowedType = predicate.type ? - narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) : - narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]); - return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType)); + if (isCallWithEffects(flow.node)) { + const signature = getResolvedSignature(flow.node); + const predicate = getTypePredicateOfSignature(signature); + if (predicate && predicate.kind === TypePredicateKind.Assertion) { + const flowType = getTypeAtFlowNode(flow.antecedent); + const type = getTypeFromFlowType(flowType); + const narrowedType = predicate.type ? + narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) : + narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]); + return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType)); + } + if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) { + return neverType; + } } return undefined; } @@ -17690,8 +17688,9 @@ namespace ts { } function narrowTypeByCallExpression(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { - if (hasMatchingArgument(callExpression, reference)) { - const predicate = getTypePredicateForCall(callExpression); + if (hasMatchingArgument(callExpression, reference) && isCallWithEffects(callExpression)) { + const signature = getResolvedSignature(callExpression); + const predicate = getTypePredicateOfSignature(signature); if (predicate && predicate.kind !== TypePredicateKind.Assertion) { return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue); } @@ -23652,15 +23651,14 @@ namespace ts { return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes); } - function functionHasImplicitReturn(func: FunctionLikeDeclaration) { - if (!(func.flags & NodeFlags.HasImplicitReturn)) { - return false; - } + function isNeverFunctionCall(expr: Expression) { + return expr.kind === SyntaxKind.CallExpression && isCallWithEffects(expr) && !!(getTypeOfExpression(expr).flags & TypeFlags.Never); + } - if (some((func.body).statements, statement => statement.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(statement))) { - return false; - } - return true; + function functionHasImplicitReturn(func: FunctionLikeDeclaration) { + return !!(func.flags & NodeFlags.HasImplicitReturn) && !some((func.body).statements, statement => + statement.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(statement) || + statement.kind === SyntaxKind.ExpressionStatement && isNeverFunctionCall((statement).expression)); } /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */ diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3cdfba2aafb..6b757736cc5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3918,7 +3918,7 @@ namespace ts { resolvedSignature?: Signature; // Cached signature of signature node or call expression resolvedSymbol?: Symbol; // Cached name resolution result resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result - resolvedTypePredicate?: TypePredicate; // Cached type predicate for call expression + isCallWithEffects?: boolean; // Is call expression with possible control flow effects? enumMemberValue?: string | number; // Constant value of enum member isVisible?: boolean; // Is this node visible containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference From 99ab53edcd01fd217f575e805fd16ecf6c0ba7f9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 9 Aug 2019 10:15:47 +0200 Subject: [PATCH 007/100] Make flow nodes more monomorphic --- src/compiler/binder.ts | 50 ++++++++++++++++++++++++----------------- src/compiler/checker.ts | 4 ++-- src/compiler/types.ts | 29 +++++++++++++++--------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8e004b125ab..b4ccdf488b1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -148,8 +148,8 @@ namespace ts { let Symbol: new (flags: SymbolFlags, name: __String) => Symbol; // tslint:disable-line variable-name let classifiableNames: UnderscoreEscapedMap; - const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; - const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; + const unreachableFlow = createFlowNode(FlowFlags.Unreachable, /*antecedent*/ undefined, /*node*/ undefined); + const reportedUnreachableFlow: FlowNode = createFlowNode(FlowFlags.Unreachable, /*antecedent*/ undefined, /*node*/ undefined); // state used to aggregate transform flags during bind. let subtreeTransformFlags: TransformFlags = TransformFlags.None; @@ -560,9 +560,9 @@ namespace ts { // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave // similarly to break statements that exit to a label just past the statement body. if (!isIIFE) { - currentFlow = { flags: FlowFlags.Start }; + currentFlow = createFlowNode(FlowFlags.Start, /*antecedent*/ undefined, /*node*/ undefined) as FlowStart; if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) { - currentFlow.container = node; + currentFlow.node = node; } } // We create a return control flow graph for IIFEs and constructors. For constructors @@ -842,18 +842,22 @@ namespace ts { return isNarrowableReference(expr); } - function createBranchLabel(): FlowLabel { + function createFlowNode(flags: FlowFlags, antecedent: FlowNode | undefined, node: Node | undefined) { return { - flags: FlowFlags.BranchLabel, - antecedents: undefined - }; + flags, + antecedent, + node, + id: undefined, + antecedents: undefined, + } as FlowNode; + } + + function createBranchLabel(): FlowLabel { + return createFlowNode(FlowFlags.BranchLabel, /*antecedent*/ undefined, /*node*/ undefined) as FlowLabel; } function createLoopLabel(): FlowLabel { - return { - flags: FlowFlags.LoopLabel, - antecedents: undefined - }; + return createFlowNode(FlowFlags.LoopLabel, /*antecedent*/ undefined, /*node*/ undefined) as FlowLabel; } function setFlowNodeReferenced(flow: FlowNode) { @@ -883,7 +887,7 @@ namespace ts { return antecedent; } setFlowNodeReferenced(antecedent); - return flowNodeCreated({ flags, expression, antecedent }); + return flowNodeCreated(createFlowNode(flags, antecedent, expression)); } function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode { @@ -891,23 +895,26 @@ namespace ts { return antecedent; } setFlowNodeReferenced(antecedent); - return flowNodeCreated({ flags: FlowFlags.SwitchClause, switchStatement, clauseStart, clauseEnd, antecedent }); + const result = createFlowNode(FlowFlags.SwitchClause, antecedent, /*node*/ undefined) as FlowSwitchClause; + result.switchStatement = switchStatement; + result.clauseStart = clauseStart; + result.clauseEnd = clauseEnd; + return flowNodeCreated(result); } function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode { setFlowNodeReferenced(antecedent); - return flowNodeCreated({ flags: FlowFlags.Assignment, antecedent, node }); + return flowNodeCreated(createFlowNode(FlowFlags.Assignment, antecedent, node)); } function createFlowCall(antecedent: FlowNode, node: CallExpression): FlowNode { setFlowNodeReferenced(antecedent); - return flowNodeCreated({ flags: FlowFlags.Call, antecedent, node }); + return flowNodeCreated(createFlowNode(FlowFlags.Call, antecedent, node)); } function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode { setFlowNodeReferenced(antecedent); - const res: FlowArrayMutation = flowNodeCreated({ flags: FlowFlags.ArrayMutation, antecedent, node }); - return res; + return flowNodeCreated(createFlowNode(FlowFlags.ArrayMutation, antecedent, node)); } function finishFlowLabel(flow: FlowLabel): FlowNode { @@ -1185,7 +1192,8 @@ namespace ts { // // extra edges that we inject allows to control this behavior // if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped. - const preFinallyFlow: PreFinallyFlow = { flags: FlowFlags.PreFinally, antecedent: preFinallyPrior, lock: {} }; + const preFinallyFlow = createFlowNode(FlowFlags.PreFinally, preFinallyPrior, /*node*/ undefined) as PreFinallyFlow; + preFinallyFlow.lock = {}; addAntecedent(preFinallyLabel, preFinallyFlow); currentFlow = finishFlowLabel(preFinallyLabel); @@ -1204,7 +1212,7 @@ namespace ts { } } if (!(currentFlow.flags & FlowFlags.Unreachable)) { - const afterFinallyFlow: AfterFinallyFlow = flowNodeCreated({ flags: FlowFlags.AfterFinally, antecedent: currentFlow }); + const afterFinallyFlow = flowNodeCreated(createFlowNode(FlowFlags.AfterFinally, currentFlow, /*node*/ undefined) as AfterFinallyFlow); preFinallyFlow.lock = afterFinallyFlow; currentFlow = afterFinallyFlow; } @@ -1828,7 +1836,7 @@ namespace ts { const host = getJSDocHost(typeAlias); container = findAncestor(host.parent, n => !!(getContainerFlags(n) & ContainerFlags.IsContainer)) || file; blockScopeContainer = getEnclosingBlockScopeContainer(host) || file; - currentFlow = { flags: FlowFlags.Start }; + currentFlow = createFlowNode(FlowFlags.Start, /*antecedent*/ undefined, /*node*/ undefined); parent = typeAlias; bind(typeAlias.typeExpression); if (isJSDocEnumTag(typeAlias) || !typeAlias.fullName || typeAlias.fullName.kind === SyntaxKind.Identifier) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 01de800c7c8..491dc35a2b2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17001,7 +17001,7 @@ namespace ts { } else if (flags & FlowFlags.Start) { // Check if we should continue with the control flow of the containing function. - const container = (flow).container; + const container = (flow).node; if (container && container !== flowContainer && reference.kind !== SyntaxKind.PropertyAccessExpression && reference.kind !== SyntaxKind.ElementAccessExpression && @@ -17150,7 +17150,7 @@ namespace ts { // *only* place a silent never type is ever generated. const assumeTrue = (flow.flags & FlowFlags.TrueCondition) !== 0; const nonEvolvingType = finalizeEvolvingArrayType(type); - const narrowedType = narrowType(nonEvolvingType, flow.expression, assumeTrue); + const narrowedType = narrowType(nonEvolvingType, flow.node, assumeTrue); if (narrowedType === nonEvolvingType) { return flowType; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6b757736cc5..96a054e841b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2565,6 +2565,22 @@ namespace ts { Condition = TrueCondition | FalseCondition } + export type FlowNode = + | AfterFinallyFlow + | PreFinallyFlow + | FlowStart + | FlowLabel + | FlowAssignment + | FlowCall + | FlowCondition + | FlowSwitchClause + | FlowArrayMutation; + + export interface FlowNodeBase { + flags: FlowFlags; + id: number | undefined; // Node id used by flow type cache in checker + } + export interface FlowLock { locked?: boolean; } @@ -2578,18 +2594,11 @@ namespace ts { lock: FlowLock; } - export type FlowNode = - | AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; - export interface FlowNodeBase { - flags: FlowFlags; - id?: number; // Node id used by flow type cache in checker - } - // FlowStart represents the start of a control flow. For a function expression or arrow - // function, the container property references the function (which in turn has a flowNode + // function, the node property references the function (which in turn has a flowNode // property for the containing control flow). export interface FlowStart extends FlowNodeBase { - container?: FunctionExpression | ArrowFunction | MethodDeclaration; + node?: FunctionExpression | ArrowFunction | MethodDeclaration; } // FlowLabel represents a junction with multiple possible preceding control flows. @@ -2612,7 +2621,7 @@ namespace ts { // FlowCondition represents a condition that is known to be true or false at the // node's location in the control flow. export interface FlowCondition extends FlowNodeBase { - expression: Expression; + node: Expression; antecedent: FlowNode; } From d5e08d485d783537c4bbdc5d72425763656cba5d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 9 Aug 2019 10:16:16 +0200 Subject: [PATCH 008/100] Accept baseline API changes --- tests/baselines/reference/api/tsserverlibrary.d.ts | 14 +++++++------- tests/baselines/reference/api/typescript.d.ts | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 00c88fc4963..c1a271bb0af 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1672,6 +1672,11 @@ declare namespace ts { Label = 12, Condition = 96 } + export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; + export interface FlowNodeBase { + flags: FlowFlags; + id: number | undefined; + } export interface FlowLock { locked?: boolean; } @@ -1682,13 +1687,8 @@ declare namespace ts { antecedent: FlowNode; lock: FlowLock; } - export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; - export interface FlowNodeBase { - flags: FlowFlags; - id?: number; - } export interface FlowStart extends FlowNodeBase { - container?: FunctionExpression | ArrowFunction | MethodDeclaration; + node?: FunctionExpression | ArrowFunction | MethodDeclaration; } export interface FlowLabel extends FlowNodeBase { antecedents: FlowNode[] | undefined; @@ -1702,7 +1702,7 @@ declare namespace ts { antecedent: FlowNode; } export interface FlowCondition extends FlowNodeBase { - expression: Expression; + node: Expression; antecedent: FlowNode; } export interface FlowSwitchClause extends FlowNodeBase { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index df8d0e1ee79..0bb7d724ee0 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1672,6 +1672,11 @@ declare namespace ts { Label = 12, Condition = 96 } + export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; + export interface FlowNodeBase { + flags: FlowFlags; + id: number | undefined; + } export interface FlowLock { locked?: boolean; } @@ -1682,13 +1687,8 @@ declare namespace ts { antecedent: FlowNode; lock: FlowLock; } - export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; - export interface FlowNodeBase { - flags: FlowFlags; - id?: number; - } export interface FlowStart extends FlowNodeBase { - container?: FunctionExpression | ArrowFunction | MethodDeclaration; + node?: FunctionExpression | ArrowFunction | MethodDeclaration; } export interface FlowLabel extends FlowNodeBase { antecedents: FlowNode[] | undefined; @@ -1702,7 +1702,7 @@ declare namespace ts { antecedent: FlowNode; } export interface FlowCondition extends FlowNodeBase { - expression: Expression; + node: Expression; antecedent: FlowNode; } export interface FlowSwitchClause extends FlowNodeBase { From 19f1d3ba0a8c0f85a99a770d3a344161b911d934 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 9 Aug 2019 12:35:28 +0200 Subject: [PATCH 009/100] Less aggressive monomorphism for flow nodes --- src/compiler/binder.ts | 41 +++++++++++++---------------------------- src/compiler/types.ts | 2 +- 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b4ccdf488b1..19dd6bee232 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -148,8 +148,8 @@ namespace ts { let Symbol: new (flags: SymbolFlags, name: __String) => Symbol; // tslint:disable-line variable-name let classifiableNames: UnderscoreEscapedMap; - const unreachableFlow = createFlowNode(FlowFlags.Unreachable, /*antecedent*/ undefined, /*node*/ undefined); - const reportedUnreachableFlow: FlowNode = createFlowNode(FlowFlags.Unreachable, /*antecedent*/ undefined, /*node*/ undefined); + const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; + const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable }; // state used to aggregate transform flags during bind. let subtreeTransformFlags: TransformFlags = TransformFlags.None; @@ -560,7 +560,7 @@ namespace ts { // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave // similarly to break statements that exit to a label just past the statement body. if (!isIIFE) { - currentFlow = createFlowNode(FlowFlags.Start, /*antecedent*/ undefined, /*node*/ undefined) as FlowStart; + currentFlow = { flags: FlowFlags.Start }; if (containerFlags & (ContainerFlags.IsFunctionExpression | ContainerFlags.IsObjectLiteralOrClassExpressionMethod)) { currentFlow.node = node; } @@ -842,22 +842,12 @@ namespace ts { return isNarrowableReference(expr); } - function createFlowNode(flags: FlowFlags, antecedent: FlowNode | undefined, node: Node | undefined) { - return { - flags, - antecedent, - node, - id: undefined, - antecedents: undefined, - } as FlowNode; - } - function createBranchLabel(): FlowLabel { - return createFlowNode(FlowFlags.BranchLabel, /*antecedent*/ undefined, /*node*/ undefined) as FlowLabel; + return { flags: FlowFlags.BranchLabel, antecedents: undefined }; } function createLoopLabel(): FlowLabel { - return createFlowNode(FlowFlags.LoopLabel, /*antecedent*/ undefined, /*node*/ undefined) as FlowLabel; + return { flags: FlowFlags.LoopLabel, antecedents: undefined }; } function setFlowNodeReferenced(flow: FlowNode) { @@ -887,7 +877,7 @@ namespace ts { return antecedent; } setFlowNodeReferenced(antecedent); - return flowNodeCreated(createFlowNode(flags, antecedent, expression)); + return flowNodeCreated({ flags, antecedent, node: expression }); } function createFlowSwitchClause(antecedent: FlowNode, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): FlowNode { @@ -895,26 +885,22 @@ namespace ts { return antecedent; } setFlowNodeReferenced(antecedent); - const result = createFlowNode(FlowFlags.SwitchClause, antecedent, /*node*/ undefined) as FlowSwitchClause; - result.switchStatement = switchStatement; - result.clauseStart = clauseStart; - result.clauseEnd = clauseEnd; - return flowNodeCreated(result); + return flowNodeCreated({ flags: FlowFlags.SwitchClause, antecedent, switchStatement, clauseStart, clauseEnd }); } function createFlowAssignment(antecedent: FlowNode, node: Expression | VariableDeclaration | BindingElement): FlowNode { setFlowNodeReferenced(antecedent); - return flowNodeCreated(createFlowNode(FlowFlags.Assignment, antecedent, node)); + return flowNodeCreated({ flags: FlowFlags.Assignment, antecedent, node }); } function createFlowCall(antecedent: FlowNode, node: CallExpression): FlowNode { setFlowNodeReferenced(antecedent); - return flowNodeCreated(createFlowNode(FlowFlags.Call, antecedent, node)); + return flowNodeCreated({ flags: FlowFlags.Call, antecedent, node }); } function createFlowArrayMutation(antecedent: FlowNode, node: CallExpression | BinaryExpression): FlowNode { setFlowNodeReferenced(antecedent); - return flowNodeCreated(createFlowNode(FlowFlags.ArrayMutation, antecedent, node)); + return flowNodeCreated({ flags: FlowFlags.ArrayMutation, antecedent, node }); } function finishFlowLabel(flow: FlowLabel): FlowNode { @@ -1192,8 +1178,7 @@ namespace ts { // // extra edges that we inject allows to control this behavior // if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped. - const preFinallyFlow = createFlowNode(FlowFlags.PreFinally, preFinallyPrior, /*node*/ undefined) as PreFinallyFlow; - preFinallyFlow.lock = {}; + const preFinallyFlow: PreFinallyFlow = { flags: FlowFlags.PreFinally, antecedent: preFinallyPrior, lock: {} }; addAntecedent(preFinallyLabel, preFinallyFlow); currentFlow = finishFlowLabel(preFinallyLabel); @@ -1212,7 +1197,7 @@ namespace ts { } } if (!(currentFlow.flags & FlowFlags.Unreachable)) { - const afterFinallyFlow = flowNodeCreated(createFlowNode(FlowFlags.AfterFinally, currentFlow, /*node*/ undefined) as AfterFinallyFlow); + const afterFinallyFlow: AfterFinallyFlow = flowNodeCreated({ flags: FlowFlags.AfterFinally, antecedent: currentFlow }); preFinallyFlow.lock = afterFinallyFlow; currentFlow = afterFinallyFlow; } @@ -1836,7 +1821,7 @@ namespace ts { const host = getJSDocHost(typeAlias); container = findAncestor(host.parent, n => !!(getContainerFlags(n) & ContainerFlags.IsContainer)) || file; blockScopeContainer = getEnclosingBlockScopeContainer(host) || file; - currentFlow = createFlowNode(FlowFlags.Start, /*antecedent*/ undefined, /*node*/ undefined); + currentFlow = { flags: FlowFlags.Start }; parent = typeAlias; bind(typeAlias.typeExpression); if (isJSDocEnumTag(typeAlias) || !typeAlias.fullName || typeAlias.fullName.kind === SyntaxKind.Identifier) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 96a054e841b..2702f2c5249 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2578,7 +2578,7 @@ namespace ts { export interface FlowNodeBase { flags: FlowFlags; - id: number | undefined; // Node id used by flow type cache in checker + id?: number; // Node id used by flow type cache in checker } export interface FlowLock { From 83212e72407967c194762e2a2e097e2dc2076007 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 9 Aug 2019 12:35:48 +0200 Subject: [PATCH 010/100] Accept API baseline changes --- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index c1a271bb0af..2579518fe17 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1675,7 +1675,7 @@ declare namespace ts { export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; export interface FlowNodeBase { flags: FlowFlags; - id: number | undefined; + id?: number; } export interface FlowLock { locked?: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 0bb7d724ee0..4417b52af36 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1675,7 +1675,7 @@ declare namespace ts { export type FlowNode = AfterFinallyFlow | PreFinallyFlow | FlowStart | FlowLabel | FlowAssignment | FlowCall | FlowCondition | FlowSwitchClause | FlowArrayMutation; export interface FlowNodeBase { flags: FlowFlags; - id: number | undefined; + id?: number; } export interface FlowLock { locked?: boolean; From cdeddf14e9a112e64403eecb09257ac51023467f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 10 Aug 2019 08:38:18 +0200 Subject: [PATCH 011/100] Call getResolvedSignature only when needed for generics or overloads --- src/compiler/checker.ts | 27 ++++++++++++++++----------- src/compiler/types.ts | 2 +- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 71493cbe634..b2bc96fa9cd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16877,18 +16877,22 @@ namespace ts { } } - function isCallWithEffects(node: CallExpression) { + function getEffectsSignature(node: CallExpression) { const links = getNodeLinks(node); - if (links.isCallWithEffects === undefined) { + let signature = links.effectsSignature; + if (signature === undefined) { // A call expression parented by an expression statement is a potential assertion. Other call // expressions are potential type predicate function calls. const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression) : node.expression.kind !== SyntaxKind.SuperKeyword ? checkNonNullExpression(node.expression) : undefined; - const apparentType = funcType && getApparentType(funcType) || unknownType; - links.isCallWithEffects = some(getSignaturesOfType(apparentType, SignatureKind.Call), hasTypePredicateOrNeverReturnType); + const signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, SignatureKind.Call); + const candidate = signatures.length === 1 && !signatures[0].typeParameters ? signatures[0] : + some(signatures, hasTypePredicateOrNeverReturnType) ? getResolvedSignature(node) : + undefined; + signature = links.effectsSignature = candidate && hasTypePredicateOrNeverReturnType(candidate) ? candidate : unknownSignature; } - return links.isCallWithEffects; + return signature === unknownSignature ? undefined : signature; } function hasTypePredicateOrNeverReturnType(signature: Signature) { @@ -17110,8 +17114,8 @@ namespace ts { } function getTypeAtFlowCall(flow: FlowCall): FlowType | undefined { - if (isCallWithEffects(flow.node)) { - const signature = getResolvedSignature(flow.node); + const signature = getEffectsSignature(flow.node); + if (signature) { const predicate = getTypePredicateOfSignature(signature); if (predicate && predicate.kind === TypePredicateKind.Assertion) { const flowType = getTypeAtFlowNode(flow.antecedent); @@ -17712,9 +17716,9 @@ namespace ts { } function narrowTypeByCallExpression(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type { - if (hasMatchingArgument(callExpression, reference) && isCallWithEffects(callExpression)) { - const signature = getResolvedSignature(callExpression); - const predicate = getTypePredicateOfSignature(signature); + if (hasMatchingArgument(callExpression, reference)) { + const signature = getEffectsSignature(callExpression); + const predicate = signature && getTypePredicateOfSignature(signature); if (predicate && predicate.kind !== TypePredicateKind.Assertion) { return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue); } @@ -23695,7 +23699,8 @@ namespace ts { } function isNeverFunctionCall(expr: Expression) { - return expr.kind === SyntaxKind.CallExpression && isCallWithEffects(expr) && !!(getTypeOfExpression(expr).flags & TypeFlags.Never); + const signature = expr.kind === SyntaxKind.CallExpression && getEffectsSignature(expr); + return !!(signature && getReturnTypeOfSignature(signature).flags & TypeFlags.Never); } function functionHasImplicitReturn(func: FunctionLikeDeclaration) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7038b45e24a..9be0bf42db9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3927,7 +3927,7 @@ namespace ts { resolvedSignature?: Signature; // Cached signature of signature node or call expression resolvedSymbol?: Symbol; // Cached name resolution result resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result - isCallWithEffects?: boolean; // Is call expression with possible control flow effects? + effectsSignature?: Signature; // Signature with possible control flow effects enumMemberValue?: string | number; // Constant value of enum member isVisible?: boolean; // Is this node visible containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference From 0599f848575dcfbda5730c446003f4e59411446d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 17 Aug 2019 06:23:07 -0700 Subject: [PATCH 012/100] Support 'asserts this' and 'asserts this is T' type predicates --- src/compiler/checker.ts | 34 ++++++++++++++++++---------------- src/compiler/parser.ts | 2 +- src/compiler/types.ts | 16 ++++++++++++---- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 58af0a7134a..c919bb986e4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4228,8 +4228,10 @@ namespace ts { let returnTypeNode: TypeNode | undefined; const typePredicate = getTypePredicateOfSignature(signature); if (typePredicate) { - const assertsModifier = typePredicate.kind === TypePredicateKind.Assertion ? createToken(SyntaxKind.AssertsKeyword) : undefined; - const parameterName = typePredicate.kind !== TypePredicateKind.This ? + const assertsModifier = typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? + createToken(SyntaxKind.AssertsKeyword) : + undefined; + const parameterName = typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? setEmitFlags(createIdentifier(typePredicate.parameterName), EmitFlags.NoAsciiEscaping) : createThisTypeNode(); const typeNode = typePredicate.type && typeToTypeNodeHelper(typePredicate.type, context); @@ -4702,8 +4704,8 @@ namespace ts { function typePredicateToStringWorker(writer: EmitTextWriter) { const predicate = createTypePredicateNode( - typePredicate.kind === TypePredicateKind.Assertion ? createToken(SyntaxKind.AssertsKeyword) : undefined, - typePredicate.kind !== TypePredicateKind.This ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(), + typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? createToken(SyntaxKind.AssertsKeyword) : undefined, + typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217 ); const printer = createPrinter({ removeComments: true }); @@ -8721,8 +8723,8 @@ namespace ts { const parameterName = node.parameterName; const type = node.type && getTypeFromTypeNode(node.type); return parameterName.kind === SyntaxKind.ThisType ? - createTypePredicate(TypePredicateKind.This, /*parameterName*/ undefined, /*parameterIndex*/ undefined, type) : - createTypePredicate(node.assertsModifier ? TypePredicateKind.Assertion : TypePredicateKind.Identifier, parameterName.escapedText as string, + createTypePredicate(node.assertsModifier ? TypePredicateKind.AssertsThis : TypePredicateKind.This, /*parameterName*/ undefined, /*parameterIndex*/ undefined, type) : + createTypePredicate(node.assertsModifier ? TypePredicateKind.AssertsIdentifier : TypePredicateKind.Identifier, parameterName.escapedText as string, findIndex(signature.parameters, p => p.escapedName === parameterName.escapedText), type); } @@ -9829,7 +9831,7 @@ namespace ts { const types: Type[] = []; for (const sig of signatures) { const pred = getTypePredicateOfSignature(sig); - if (!pred || pred.kind === TypePredicateKind.Assertion) { + if (!pred || pred.kind === TypePredicateKind.AssertsThis || pred.kind === TypePredicateKind.AssertsIdentifier) { continue; } @@ -12400,7 +12402,7 @@ namespace ts { return Ternary.False; } - if (source.kind !== TypePredicateKind.This) { + if (source.kind === TypePredicateKind.Identifier || source.kind === TypePredicateKind.AssertsIdentifier) { if (source.parameterIndex !== (target as IdentifierTypePredicate).parameterIndex) { if (reportErrors) { errorReporter!(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, (target as IdentifierTypePredicate).parameterName); @@ -17119,12 +17121,12 @@ namespace ts { const signature = getEffectsSignature(flow.node); if (signature) { const predicate = getTypePredicateOfSignature(signature); - if (predicate && predicate.kind === TypePredicateKind.Assertion) { + if (predicate && (predicate.kind === TypePredicateKind.AssertsThis || predicate.kind === TypePredicateKind.AssertsIdentifier)) { const flowType = getTypeAtFlowNode(flow.antecedent); const type = getTypeFromFlowType(flowType); - const narrowedType = predicate.type ? - narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) : - narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]); + const narrowedType = predicate.type ? narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) : + predicate.kind === TypePredicateKind.AssertsIdentifier ? narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]) : + type; return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType)); } if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) { @@ -17721,7 +17723,7 @@ namespace ts { if (hasMatchingArgument(callExpression, reference)) { const signature = getEffectsSignature(callExpression); const predicate = signature && getTypePredicateOfSignature(signature); - if (predicate && predicate.kind !== TypePredicateKind.Assertion) { + if (predicate && (predicate.kind === TypePredicateKind.This || predicate.kind === TypePredicateKind.Identifier)) { return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue); } } @@ -17733,7 +17735,7 @@ namespace ts { if (isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType)) { return type; } - if (predicate.kind !== TypePredicateKind.This) { + if (predicate.kind === TypePredicateKind.Identifier || predicate.kind === TypePredicateKind.AssertsIdentifier) { const predicateArgument = callExpression.arguments[predicate.parameterIndex]; if (predicateArgument && predicate.type) { if (isMatchingReference(reference, predicateArgument)) { @@ -17746,7 +17748,7 @@ namespace ts { } else { const invokedExpression = skipParentheses(callExpression.expression); - if (isAccessExpression(invokedExpression)) { + if (isAccessExpression(invokedExpression) && predicate.type) { const possibleReference = skipParentheses(invokedExpression.expression); if (isMatchingReference(reference, possibleReference)) { return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf); @@ -25501,7 +25503,7 @@ namespace ts { checkSourceElement(node.type); const { parameterName } = node; - if (isThisTypePredicate(typePredicate)) { + if (typePredicate.kind === TypePredicateKind.This || typePredicate.kind === TypePredicateKind.AssertsThis) { getTypeFromThisTypeNode(parameterName as ThisTypeNode); } else { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3c2b7bd42cc..c1331165327 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3258,7 +3258,7 @@ namespace ts { function parseAssertsTypePredicate(): TypeNode { const node = createNode(SyntaxKind.TypePredicate); node.assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword); - node.parameterName = parseIdentifier(); + node.parameterName = token() === SyntaxKind.ThisKeyword ? parseThisTypeNode() : parseIdentifier(); node.type = parseOptional(SyntaxKind.IsKeyword) ? parseType() : undefined; return finishNode(node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3b121c76e20..b27de58134a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3514,7 +3514,8 @@ namespace ts { export const enum TypePredicateKind { This, Identifier, - Assertion + AssertsThis, + AssertsIdentifier } export interface ThisTypePredicate { @@ -3531,14 +3532,21 @@ namespace ts { type: Type; } - export interface AssertionTypePredicate { - kind: TypePredicateKind.Assertion; + export interface AssertsThisTypePredicate { + kind: TypePredicateKind.AssertsThis; + parameterName: undefined; + parameterIndex: undefined; + type: Type | undefined; + } + + export interface AssertsIdentifierTypePredicate { + kind: TypePredicateKind.AssertsIdentifier; parameterName: string; parameterIndex: number; type: Type | undefined; } - export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertionTypePredicate; + export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertsThisTypePredicate | AssertsIdentifierTypePredicate; /* @internal */ export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration; From e7cbfc41e5afbaa68bdc30e2865acd3a7b0b44e8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 17 Aug 2019 07:05:49 -0700 Subject: [PATCH 013/100] Update API to be backwards compatible --- src/compiler/checker.ts | 4 ++-- src/compiler/factory.ts | 17 +++++++++++++---- src/compiler/visitor.ts | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c919bb986e4..0af56d7f172 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4235,7 +4235,7 @@ namespace ts { setEmitFlags(createIdentifier(typePredicate.parameterName), EmitFlags.NoAsciiEscaping) : createThisTypeNode(); const typeNode = typePredicate.type && typeToTypeNodeHelper(typePredicate.type, context); - returnTypeNode = createTypePredicateNode(assertsModifier, parameterName, typeNode); + returnTypeNode = createTypePredicateNodeWithModifier(assertsModifier, parameterName, typeNode); } else { const returnType = getReturnTypeOfSignature(signature); @@ -4703,7 +4703,7 @@ namespace ts { return writer ? typePredicateToStringWorker(writer).getText() : usingSingleLineStringWriter(typePredicateToStringWorker); function typePredicateToStringWorker(writer: EmitTextWriter) { - const predicate = createTypePredicateNode( + const predicate = createTypePredicateNodeWithModifier( typePredicate.kind === TypePredicateKind.AssertsThis || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? createToken(SyntaxKind.AssertsKeyword) : undefined, typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? createIdentifier(typePredicate.parameterName) : createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217 diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 9a484681acf..3118b9a2efe 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -667,7 +667,11 @@ namespace ts { return createSynthesizedNode(kind); } - export function createTypePredicateNode(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { + export function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { + return createTypePredicateNodeWithModifier(/*assertsModifier*/ undefined, parameterName, type); + } + + export function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined) { const node = createSynthesizedNode(SyntaxKind.TypePredicate) as TypePredicateNode; node.assertsModifier = assertsModifier; node.parameterName = asName(parameterName); @@ -675,10 +679,15 @@ namespace ts { return node; } - export function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) { - return node.parameterName !== parameterName + export function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) { + return updateTypePredicateNodeWithModifier(node, node.assertsModifier, parameterName, type); + } + + export function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined) { + return node.assertsModifier !== assertsModifier + || node.parameterName !== parameterName || node.type !== type - ? updateNode(createTypePredicateNode(assertsModifier, parameterName, type), node) + ? updateNode(createTypePredicateNodeWithModifier(assertsModifier, parameterName, type), node) : node; } diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index aa497511f78..266b794438b 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -339,7 +339,7 @@ namespace ts { // Types case SyntaxKind.TypePredicate: - return updateTypePredicateNode(node, + return updateTypePredicateNodeWithModifier(node, visitNode((node).assertsModifier, visitor), visitNode((node).parameterName, visitor), visitNode((node).type, visitor, isTypeNode)); From 2c36249ed6bd63f4fd66813985ae2dff681349a5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 17 Aug 2019 07:07:27 -0700 Subject: [PATCH 014/100] Accept new API baselines --- .../reference/api/tsserverlibrary.d.ts | 21 +++++++++++++------ tests/baselines/reference/api/typescript.d.ts | 21 +++++++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 60222fc8bd3..c458e88300b 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2094,7 +2094,8 @@ declare namespace ts { export enum TypePredicateKind { This = 0, Identifier = 1, - Assertion = 2 + AssertsThis = 2, + AssertsIdentifier = 3 } export interface ThisTypePredicate { kind: TypePredicateKind.This; @@ -2108,13 +2109,19 @@ declare namespace ts { parameterIndex: number; type: Type; } - export interface AssertionTypePredicate { - kind: TypePredicateKind.Assertion; + export interface AssertsThisTypePredicate { + kind: TypePredicateKind.AssertsThis; + parameterName: undefined; + parameterIndex: undefined; + type: Type | undefined; + } + export interface AssertsIdentifierTypePredicate { + kind: TypePredicateKind.AssertsIdentifier; parameterName: string; parameterIndex: number; type: Type | undefined; } - export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertionTypePredicate; + export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertsThisTypePredicate | AssertsIdentifierTypePredicate; export enum SymbolFlags { None = 0, FunctionScopedVariable = 1, @@ -3843,8 +3850,10 @@ declare namespace ts { function createIndexSignature(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function updateIndexSignature(node: IndexSignatureDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode; - function createTypePredicateNode(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; - function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; + function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; + function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined): TypeReferenceNode; function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; function createFunctionTypeNode(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): FunctionTypeNode; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index dbb9ac16f83..d8df06e936f 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2094,7 +2094,8 @@ declare namespace ts { export enum TypePredicateKind { This = 0, Identifier = 1, - Assertion = 2 + AssertsThis = 2, + AssertsIdentifier = 3 } export interface ThisTypePredicate { kind: TypePredicateKind.This; @@ -2108,13 +2109,19 @@ declare namespace ts { parameterIndex: number; type: Type; } - export interface AssertionTypePredicate { - kind: TypePredicateKind.Assertion; + export interface AssertsThisTypePredicate { + kind: TypePredicateKind.AssertsThis; + parameterName: undefined; + parameterIndex: undefined; + type: Type | undefined; + } + export interface AssertsIdentifierTypePredicate { + kind: TypePredicateKind.AssertsIdentifier; parameterName: string; parameterIndex: number; type: Type | undefined; } - export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertionTypePredicate; + export type TypePredicate = ThisTypePredicate | IdentifierTypePredicate | AssertsThisTypePredicate | AssertsIdentifierTypePredicate; export enum SymbolFlags { None = 0, FunctionScopedVariable = 1, @@ -3843,8 +3850,10 @@ declare namespace ts { function createIndexSignature(decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function updateIndexSignature(node: IndexSignatureDeclaration, decorators: ReadonlyArray | undefined, modifiers: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode): IndexSignatureDeclaration; function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode; - function createTypePredicateNode(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; - function updateTypePredicateNode(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; + function createTypePredicateNode(parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + function createTypePredicateNodeWithModifier(assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode | string, type: TypeNode | undefined): TypePredicateNode; + function updateTypePredicateNode(node: TypePredicateNode, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; + function updateTypePredicateNodeWithModifier(node: TypePredicateNode, assertsModifier: AssertsToken | undefined, parameterName: Identifier | ThisTypeNode, type: TypeNode | undefined): TypePredicateNode; function createTypeReferenceNode(typeName: string | EntityName, typeArguments: ReadonlyArray | undefined): TypeReferenceNode; function updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; function createFunctionTypeNode(typeParameters: ReadonlyArray | undefined, parameters: ReadonlyArray, type: TypeNode | undefined): FunctionTypeNode; From 3be6e75d6aee0c2a0a3be1b42ab84aa8c5c2e8ac Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 26 Aug 2019 11:13:17 -0700 Subject: [PATCH 015/100] Improve names in infer-from-usage Basically, drop "Context" from all names, because it just indicates that it's an implementation of the State monad. --- src/services/codefixes/inferFromUsage.ts | 238 +++++++++++------------ 1 file changed, 119 insertions(+), 119 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 396d7f44fa8..417ed5c625c 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -359,7 +359,7 @@ namespace ts.codefix { const references = getReferences(token, program, cancellationToken); const checker = program.getTypeChecker(); const types = InferFromReference.inferTypesFromReferences(references, checker, cancellationToken); - return InferFromReference.unifyFromContext(types, checker); + return InferFromReference.unifyFromUsage(types, checker); } function inferFunctionReferencesFromUsage(containingFunction: FunctionLike, sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): ReadonlyArray | undefined { @@ -395,33 +395,33 @@ namespace ts.codefix { } namespace InferFromReference { - interface CallContext { + interface CallUsage { argumentTypes: Type[]; - returnType: UsageContext; + returnType: Usage; } - interface UsageContext { + interface Usage { isNumber?: boolean; isString?: boolean; /** Used ambiguously, eg x + ___ or object[___]; results in string | number if no other evidence exists */ isNumberOrString?: boolean; candidateTypes?: Type[]; - properties?: UnderscoreEscapedMap; - callContexts?: CallContext[]; - constructContexts?: CallContext[]; - numberIndexContext?: UsageContext; - stringIndexContext?: UsageContext; + properties?: UnderscoreEscapedMap; + calls?: CallUsage[]; + constructs?: CallUsage[]; + numberIndex?: Usage; + stringIndex?: Usage; candidateThisTypes?: Type[]; } export function inferTypesFromReferences(references: ReadonlyArray, checker: TypeChecker, cancellationToken: CancellationToken): Type[] { - const usageContext: UsageContext = {}; + const usage: Usage = {}; for (const reference of references) { cancellationToken.throwIfCancellationRequested(); - inferTypeFromContext(reference, checker, usageContext); + calculateUsageOfNode(reference, checker, usage); } - return inferFromContext(usageContext, checker); + return inferFromUsage(usage, checker); } export function inferTypeForParametersFromReferences(references: ReadonlyArray | undefined, declaration: FunctionLike, program: Program, cancellationToken: CancellationToken): ParameterInference[] | undefined { @@ -430,35 +430,35 @@ namespace ts.codefix { } const checker = program.getTypeChecker(); - const usageContext: UsageContext = {}; + const usage: Usage = {}; for (const reference of references) { cancellationToken.throwIfCancellationRequested(); - inferTypeFromContext(reference, checker, usageContext); + calculateUsageOfNode(reference, checker, usage); } - const callContexts = [...usageContext.constructContexts || [], ...usageContext.callContexts || []]; + const calls = [...usage.constructs || [], ...usage.calls || []]; return declaration.parameters.map((parameter, parameterIndex): ParameterInference => { const types = []; const isRest = isRestParameter(parameter); let isOptional = false; - for (const callContext of callContexts) { - if (callContext.argumentTypes.length <= parameterIndex) { + for (const call of calls) { + if (call.argumentTypes.length <= parameterIndex) { isOptional = isInJSFile(declaration); types.push(checker.getUndefinedType()); } else if (isRest) { - for (let i = parameterIndex; i < callContext.argumentTypes.length; i++) { - types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i])); + for (let i = parameterIndex; i < call.argumentTypes.length; i++) { + types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[i])); } } else { - types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex])); + types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[parameterIndex])); } } if (isIdentifier(parameter.name)) { const inferred = inferTypesFromReferences(getReferences(parameter.name, program, cancellationToken), checker, cancellationToken); types.push(...(isRest ? mapDefined(inferred, checker.getElementTypeOfArrayType) : inferred)); } - const type = unifyFromContext(types, checker); + const type = unifyFromUsage(types, checker); return { type: isRest ? checker.createArrayType(type) : type, isOptional: isOptional && !isRest, @@ -473,89 +473,89 @@ namespace ts.codefix { } const checker = program.getTypeChecker(); - const usageContext: UsageContext = {}; + const usage: Usage = {}; for (const reference of references) { cancellationToken.throwIfCancellationRequested(); - inferTypeFromContext(reference, checker, usageContext); + calculateUsageOfNode(reference, checker, usage); } - return unifyFromContext(usageContext.candidateThisTypes || emptyArray, checker); + return unifyFromUsage(usage.candidateThisTypes || emptyArray, checker); } - function inferTypeFromContext(node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + function calculateUsageOfNode(node: Expression, checker: TypeChecker, usage: Usage): void { while (isRightSideOfQualifiedNameOrPropertyAccess(node)) { node = node.parent; } switch (node.parent.kind) { case SyntaxKind.PostfixUnaryExpression: - usageContext.isNumber = true; + usage.isNumber = true; break; case SyntaxKind.PrefixUnaryExpression: - inferTypeFromPrefixUnaryExpressionContext(node.parent, usageContext); + inferTypeFromPrefixUnaryExpression(node.parent, usage); break; case SyntaxKind.BinaryExpression: - inferTypeFromBinaryExpressionContext(node, node.parent, checker, usageContext); + inferTypeFromBinaryExpression(node, node.parent, checker, usage); break; case SyntaxKind.CaseClause: case SyntaxKind.DefaultClause: - inferTypeFromSwitchStatementLabelContext(node.parent, checker, usageContext); + inferTypeFromSwitchStatementLabel(node.parent, checker, usage); break; case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: if ((node.parent).expression === node) { - inferTypeFromCallExpressionContext(node.parent, checker, usageContext); + inferTypeFromCallExpression(node.parent, checker, usage); } else { - inferTypeFromContextualType(node, checker, usageContext); + inferTypeFromContextualType(node, checker, usage); } break; case SyntaxKind.PropertyAccessExpression: - inferTypeFromPropertyAccessExpressionContext(node.parent, checker, usageContext); + inferTypeFromPropertyAccessExpression(node.parent, checker, usage); break; case SyntaxKind.ElementAccessExpression: - inferTypeFromPropertyElementExpressionContext(node.parent, node, checker, usageContext); + inferTypeFromPropertyElementExpression(node.parent, node, checker, usage); break; case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: - inferTypeFromPropertyAssignment(node.parent, checker, usageContext); + inferTypeFromPropertyAssignment(node.parent, checker, usage); break; case SyntaxKind.PropertyDeclaration: - inferTypeFromPropertyDeclaration(node.parent, checker, usageContext); + inferTypeFromPropertyDeclaration(node.parent, checker, usage); break; case SyntaxKind.VariableDeclaration: { const { name, initializer } = node.parent as VariableDeclaration; if (node === name) { if (initializer) { // This can happen for `let x = null;` which still has an implicit-any error. - addCandidateType(usageContext, checker.getTypeAtLocation(initializer)); + addCandidateType(usage, checker.getTypeAtLocation(initializer)); } break; } } // falls through default: - return inferTypeFromContextualType(node, checker, usageContext); + return inferTypeFromContextualType(node, checker, usage); } } - function inferTypeFromContextualType(node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + function inferTypeFromContextualType(node: Expression, checker: TypeChecker, usage: Usage): void { if (isExpressionNode(node)) { - addCandidateType(usageContext, checker.getContextualType(node)); + addCandidateType(usage, checker.getContextualType(node)); } } - function inferTypeFromPrefixUnaryExpressionContext(node: PrefixUnaryExpression, usageContext: UsageContext): void { + function inferTypeFromPrefixUnaryExpression(node: PrefixUnaryExpression, usage: Usage): void { switch (node.operator) { case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: case SyntaxKind.MinusToken: case SyntaxKind.TildeToken: - usageContext.isNumber = true; + usage.isNumber = true; break; case SyntaxKind.PlusToken: - usageContext.isNumberOrString = true; + usage.isNumberOrString = true; break; // case SyntaxKind.ExclamationToken: @@ -563,7 +563,7 @@ namespace ts.codefix { } } - function inferTypeFromBinaryExpressionContext(node: Expression, parent: BinaryExpression, checker: TypeChecker, usageContext: UsageContext): void { + function inferTypeFromBinaryExpression(node: Expression, parent: BinaryExpression, checker: TypeChecker, usage: Usage): void { switch (parent.operatorToken.kind) { // ExponentiationOperator case SyntaxKind.AsteriskAsteriskToken: @@ -606,10 +606,10 @@ namespace ts.codefix { case SyntaxKind.GreaterThanEqualsToken: const operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left); if (operandType.flags & TypeFlags.EnumLike) { - addCandidateType(usageContext, operandType); + addCandidateType(usage, operandType); } else { - usageContext.isNumber = true; + usage.isNumber = true; } break; @@ -617,16 +617,16 @@ namespace ts.codefix { case SyntaxKind.PlusToken: const otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left); if (otherOperandType.flags & TypeFlags.EnumLike) { - addCandidateType(usageContext, otherOperandType); + addCandidateType(usage, otherOperandType); } else if (otherOperandType.flags & TypeFlags.NumberLike) { - usageContext.isNumber = true; + usage.isNumber = true; } else if (otherOperandType.flags & TypeFlags.StringLike) { - usageContext.isString = true; + usage.isString = true; } else { - usageContext.isNumberOrString = true; + usage.isNumberOrString = true; } break; @@ -636,12 +636,12 @@ namespace ts.codefix { case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.ExclamationEqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: - addCandidateType(usageContext, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left)); + addCandidateType(usage, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left)); break; case SyntaxKind.InKeyword: if (node === parent.left) { - usageContext.isString = true; + usage.isString = true; } break; @@ -651,7 +651,7 @@ namespace ts.codefix { (node.parent.parent.kind === SyntaxKind.VariableDeclaration || isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) { // var x = x || {}; // TODO: use getFalsyflagsOfType - addCandidateType(usageContext, checker.getTypeAtLocation(parent.right)); + addCandidateType(usage, checker.getTypeAtLocation(parent.right)); } break; @@ -663,68 +663,68 @@ namespace ts.codefix { } } - function inferTypeFromSwitchStatementLabelContext(parent: CaseOrDefaultClause, checker: TypeChecker, usageContext: UsageContext): void { - addCandidateType(usageContext, checker.getTypeAtLocation(parent.parent.parent.expression)); + function inferTypeFromSwitchStatementLabel(parent: CaseOrDefaultClause, checker: TypeChecker, usage: Usage): void { + addCandidateType(usage, checker.getTypeAtLocation(parent.parent.parent.expression)); } - function inferTypeFromCallExpressionContext(parent: CallExpression | NewExpression, checker: TypeChecker, usageContext: UsageContext): void { - const callContext: CallContext = { + function inferTypeFromCallExpression(parent: CallExpression | NewExpression, checker: TypeChecker, usage: Usage): void { + const call: CallUsage = { argumentTypes: [], returnType: {} }; if (parent.arguments) { for (const argument of parent.arguments) { - callContext.argumentTypes.push(checker.getTypeAtLocation(argument)); + call.argumentTypes.push(checker.getTypeAtLocation(argument)); } } - inferTypeFromContext(parent, checker, callContext.returnType); + calculateUsageOfNode(parent, checker, call.returnType); if (parent.kind === SyntaxKind.CallExpression) { - (usageContext.callContexts || (usageContext.callContexts = [])).push(callContext); + (usage.calls || (usage.calls = [])).push(call); } else { - (usageContext.constructContexts || (usageContext.constructContexts = [])).push(callContext); + (usage.constructs || (usage.constructs = [])).push(call); } } - function inferTypeFromPropertyAccessExpressionContext(parent: PropertyAccessExpression, checker: TypeChecker, usageContext: UsageContext): void { + function inferTypeFromPropertyAccessExpression(parent: PropertyAccessExpression, checker: TypeChecker, usage: Usage): void { const name = escapeLeadingUnderscores(parent.name.text); - if (!usageContext.properties) { - usageContext.properties = createUnderscoreEscapedMap(); + if (!usage.properties) { + usage.properties = createUnderscoreEscapedMap(); } - const propertyUsageContext = usageContext.properties.get(name) || { }; - inferTypeFromContext(parent, checker, propertyUsageContext); - usageContext.properties.set(name, propertyUsageContext); + const propertyUsage = usage.properties.get(name) || { }; + calculateUsageOfNode(parent, checker, propertyUsage); + usage.properties.set(name, propertyUsage); } - function inferTypeFromPropertyElementExpressionContext(parent: ElementAccessExpression, node: Expression, checker: TypeChecker, usageContext: UsageContext): void { + function inferTypeFromPropertyElementExpression(parent: ElementAccessExpression, node: Expression, checker: TypeChecker, usage: Usage): void { if (node === parent.argumentExpression) { - usageContext.isNumberOrString = true; + usage.isNumberOrString = true; return; } else { const indexType = checker.getTypeAtLocation(parent.argumentExpression); - const indexUsageContext = {}; - inferTypeFromContext(parent, checker, indexUsageContext); + const indexUsage = {}; + calculateUsageOfNode(parent, checker, indexUsage); if (indexType.flags & TypeFlags.NumberLike) { - usageContext.numberIndexContext = indexUsageContext; + usage.numberIndex = indexUsage; } else { - usageContext.stringIndexContext = indexUsageContext; + usage.stringIndex = indexUsage; } } } - function inferTypeFromPropertyAssignment(assignment: PropertyAssignment | ShorthandPropertyAssignment, checker: TypeChecker, usageContext: UsageContext) { + function inferTypeFromPropertyAssignment(assignment: PropertyAssignment | ShorthandPropertyAssignment, checker: TypeChecker, usage: Usage) { const nodeWithRealType = isVariableDeclaration(assignment.parent.parent) ? assignment.parent.parent : assignment.parent; - addCandidateThisType(usageContext, checker.getTypeAtLocation(nodeWithRealType)); + addCandidateThisType(usage, checker.getTypeAtLocation(nodeWithRealType)); } - function inferTypeFromPropertyDeclaration(declaration: PropertyDeclaration, checker: TypeChecker, usageContext: UsageContext) { - addCandidateThisType(usageContext, checker.getTypeAtLocation(declaration.parent)); + function inferTypeFromPropertyDeclaration(declaration: PropertyDeclaration, checker: TypeChecker, usage: Usage) { + addCandidateThisType(usage, checker.getTypeAtLocation(declaration.parent)); } interface Priority { @@ -745,7 +745,7 @@ namespace ts.codefix { return inferences.filter(i => toRemove.every(f => !f(i))); } - export function unifyFromContext(inferences: ReadonlyArray, checker: TypeChecker, fallback = checker.getAnyType()): Type { + export function unifyFromUsage(inferences: ReadonlyArray, checker: TypeChecker, fallback = checker.getAnyType()): Type { if (!inferences.length) return fallback; // 1. string or number individually override string | number @@ -815,82 +815,82 @@ namespace ts.codefix { numberIndices.length ? checker.createIndexInfo(checker.getUnionType(numberIndices), numberIndexReadonly) : undefined); } - function inferFromContext(usageContext: UsageContext, checker: TypeChecker) { + function inferFromUsage(usage: Usage, checker: TypeChecker) { const types = []; - if (usageContext.isNumber) { + if (usage.isNumber) { types.push(checker.getNumberType()); } - if (usageContext.isString) { + if (usage.isString) { types.push(checker.getStringType()); } - if (usageContext.isNumberOrString) { + if (usage.isNumberOrString) { types.push(checker.getUnionType([checker.getStringType(), checker.getNumberType()])); } - types.push(...(usageContext.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t))); + types.push(...(usage.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t))); - if (usageContext.properties && hasCallContext(usageContext.properties.get("then" as __String))) { - const paramType = getParameterTypeFromCallContexts(0, usageContext.properties.get("then" as __String)!.callContexts!, /*isRestParameter*/ false, checker)!; // TODO: GH#18217 + if (usage.properties && hasCalls(usage.properties.get("then" as __String))) { + const paramType = getParameterTypeFromCalls(0, usage.properties.get("then" as __String)!.calls!, /*isRestParameter*/ false, checker)!; // TODO: GH#18217 const types = paramType.getCallSignatures().map(c => c.getReturnType()); types.push(checker.createPromiseType(types.length ? checker.getUnionType(types, UnionReduction.Subtype) : checker.getAnyType())); } - else if (usageContext.properties && hasCallContext(usageContext.properties.get("push" as __String))) { - types.push(checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push" as __String)!.callContexts!, /*isRestParameter*/ false, checker)!)); + else if (usage.properties && hasCalls(usage.properties.get("push" as __String))) { + types.push(checker.createArrayType(getParameterTypeFromCalls(0, usage.properties.get("push" as __String)!.calls!, /*isRestParameter*/ false, checker)!)); } - if (usageContext.numberIndexContext) { - types.push(checker.createArrayType(recur(usageContext.numberIndexContext))); + if (usage.numberIndex) { + types.push(checker.createArrayType(recur(usage.numberIndex))); } - else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.stringIndexContext) { + else if (usage.properties || usage.calls || usage.constructs || usage.stringIndex) { const members = createUnderscoreEscapedMap(); const callSignatures: Signature[] = []; const constructSignatures: Signature[] = []; let stringIndexInfo: IndexInfo | undefined; - if (usageContext.properties) { - usageContext.properties.forEach((context, name) => { + if (usage.properties) { + usage.properties.forEach((u, name) => { const symbol = checker.createSymbol(SymbolFlags.Property, name); - symbol.type = recur(context); + symbol.type = recur(u); members.set(name, symbol); }); } - if (usageContext.callContexts) { - for (const callContext of usageContext.callContexts) { - callSignatures.push(getSignatureFromCallContext(callContext, checker)); + if (usage.calls) { + for (const call of usage.calls) { + callSignatures.push(getSignatureFromCall(call, checker)); } } - if (usageContext.constructContexts) { - for (const constructContext of usageContext.constructContexts) { - constructSignatures.push(getSignatureFromCallContext(constructContext, checker)); + if (usage.constructs) { + for (const construct of usage.constructs) { + constructSignatures.push(getSignatureFromCall(construct, checker)); } } - if (usageContext.stringIndexContext) { - stringIndexInfo = checker.createIndexInfo(recur(usageContext.stringIndexContext), /*isReadonly*/ false); + if (usage.stringIndex) { + stringIndexInfo = checker.createIndexInfo(recur(usage.stringIndex), /*isReadonly*/ false); } types.push(checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined)); // TODO: GH#18217 } return types; - function recur(innerContext: UsageContext): Type { - return unifyFromContext(inferFromContext(innerContext, checker), checker); + function recur(innerUsage: Usage): Type { + return unifyFromUsage(inferFromUsage(innerUsage, checker), checker); } } - function getParameterTypeFromCallContexts(parameterIndex: number, callContexts: CallContext[], isRestParameter: boolean, checker: TypeChecker) { + function getParameterTypeFromCalls(parameterIndex: number, calls: CallUsage[], isRestParameter: boolean, checker: TypeChecker) { let types: Type[] = []; - if (callContexts) { - for (const callContext of callContexts) { - if (callContext.argumentTypes.length > parameterIndex) { + if (calls) { + for (const call of calls) { + if (call.argumentTypes.length > parameterIndex) { if (isRestParameter) { - types = concatenate(types, map(callContext.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); + types = concatenate(types, map(call.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); } else { - types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex])); + types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[parameterIndex])); } } } @@ -903,32 +903,32 @@ namespace ts.codefix { return undefined; } - function getSignatureFromCallContext(callContext: CallContext, checker: TypeChecker): Signature { + function getSignatureFromCall(call: CallUsage, checker: TypeChecker): Signature { const parameters: Symbol[] = []; - for (let i = 0; i < callContext.argumentTypes.length; i++) { + for (let i = 0; i < call.argumentTypes.length; i++) { const symbol = checker.createSymbol(SymbolFlags.FunctionScopedVariable, escapeLeadingUnderscores(`arg${i}`)); - symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i])); + symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(call.argumentTypes[i])); parameters.push(symbol); } - const returnType = unifyFromContext(inferFromContext(callContext.returnType, checker), checker, checker.getVoidType()); + const returnType = unifyFromUsage(inferFromUsage(call.returnType, checker), checker, checker.getVoidType()); // TODO: GH#18217 - return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, call.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } - function addCandidateType(context: UsageContext, type: Type | undefined) { + function addCandidateType(usage: Usage, type: Type | undefined) { if (type && !(type.flags & TypeFlags.Any) && !(type.flags & TypeFlags.Never)) { - (context.candidateTypes || (context.candidateTypes = [])).push(type); + (usage.candidateTypes || (usage.candidateTypes = [])).push(type); } } - function addCandidateThisType(context: UsageContext, type: Type | undefined) { + function addCandidateThisType(usage: Usage, type: Type | undefined) { if (type && !(type.flags & TypeFlags.Any) && !(type.flags & TypeFlags.Never)) { - (context.candidateThisTypes || (context.candidateThisTypes = [])).push(type); + (usage.candidateThisTypes || (usage.candidateThisTypes = [])).push(type); } } - function hasCallContext(usageContext: UsageContext | undefined): boolean { - return !!usageContext && !!usageContext.callContexts; + function hasCalls(usage: Usage | undefined): boolean { + return !!usage && !!usage.calls; } } } From d347b08a42bb705415fe8b859a69697c1d155a59 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 27 Aug 2019 13:13:58 -0700 Subject: [PATCH 016/100] Copied from old branch 1. Everything explodes! Out of stack space! 2. Results aren't used yet. 3. But call and construct use the new getSignatureFromCalls, so I expect some baseline changes after I get the infinite recursion fixed. --- src/compiler/checker.ts | 3 + src/compiler/types.ts | 1 + src/services/codefixes/inferFromUsage.ts | 85 ++++++++++++++++++++---- 3 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cfd83efeb31..1b6fee6f0de 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -524,6 +524,9 @@ namespace ts { }, getApparentType, getUnionType, + isTypeAssignableTo: (source, target) => { + return isTypeAssignableTo(source, target); + }, createAnonymousType, createSignature, createSymbol, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2c8a882c164..6e92eba8ded 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3286,6 +3286,7 @@ namespace ts { /* @internal */ getElementTypeOfArrayType(arrayType: Type): Type | undefined; /* @internal */ createPromiseType(type: Type): Type; + /* @internal */ isTypeAssignableTo(source: Type, target: Type): boolean; /* @internal */ createAnonymousType(symbol: Symbol, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): Type; /* @internal */ createSignature( declaration: SignatureDeclaration, diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 2eb9eaca7b7..4b111dae25b 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -401,7 +401,7 @@ namespace ts.codefix { interface CallUsage { argumentTypes: Type[]; - returnType: Usage; + return_: Usage; } interface Usage { @@ -671,16 +671,17 @@ namespace ts.codefix { function inferTypeFromCallExpression(parent: CallExpression | NewExpression, usage: Usage): void { const call: CallUsage = { argumentTypes: [], - returnType: {} + return_: {} }; if (parent.arguments) { for (const argument of parent.arguments) { + // TODO: should recursively infer a usage here, right? call.argumentTypes.push(checker.getTypeAtLocation(argument)); } } - calculateUsageOfNode(parent, call.returnType); + calculateUsageOfNode(parent, call.return_); if (parent.kind === SyntaxKind.CallExpression) { (usage.calls || (usage.calls = [])).push(call); } @@ -830,6 +831,7 @@ namespace ts.codefix { } types.push(...(usage.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t))); + types.push(...findBuiltinType(usage)); if (usage.properties && hasCalls(usage.properties.get("then" as __String))) { const paramType = getParameterTypeFromCalls(0, usage.properties.get("then" as __String)!.calls!, /*isRestParameter*/ false)!; // TODO: GH#18217 @@ -858,15 +860,11 @@ namespace ts.codefix { } if (usage.calls) { - for (const call of usage.calls) { - callSignatures.push(getSignatureFromCall(call)); - } + callSignatures.push(getSignatureFromCalls(usage.calls)); } if (usage.constructs) { - for (const construct of usage.constructs) { - constructSignatures.push(getSignatureFromCall(construct)); - } + constructSignatures.push(getSignatureFromCalls(usage.constructs)); } if (usage.stringIndex) { @@ -882,6 +880,61 @@ namespace ts.codefix { } } + function combineUsages(usages: Usage[]): Usage { + return { + isNumber: usages.some(u => u.isNumber), + isString: usages.some(u => u.isString), + isNumberOrString: usages.some(u => u.isNumberOrString), + candidateTypes: flatMap(usages, u => u.candidateTypes) as Type[], + properties: undefined, // TODO + calls: flatMap(usages, u => u.calls) as CallUsage[], + constructs: flatMap(usages, u => u.constructs) as CallUsage[], + numberIndex: forEach(usages, u => u.numberIndex), + stringIndex: forEach(usages, u => u.stringIndex), + candidateThisTypes: flatMap(usages, u => u.candidateThisTypes) as Type[], + } + } + + function findBuiltinType(usage: Usage): Type[] { + const builtins = [ + checker.getStringType(), + checker.getNumberType(), + checker.createArrayType(checker.getAnyType()), + checker.createPromiseType(checker.getAnyType()), + // checker.getFunctionType() // not sure what this was supposed to be good for. + ]; + const matches = builtins.filter(t => matchesAllPropertiesOf(t, usage)); + if (false && 0 < matches.length && matches.length < 3) { + return matches; + } + return []; + } + + function matchesAllPropertiesOf(type: Type, usage: Usage) { + if (!usage.properties) return false; + let result = true; + usage.properties.forEach((prop, name) => { + const source = checker.getUnionType(inferFromUsage(prop)); + const target = checker.getTypeOfPropertyOfType(type, name as string); + if (target && prop.calls) { + const sigs = checker.getSignaturesOfType(target, ts.SignatureKind.Call); + result = result && !!sigs.length && sigs.some( + sig => checker.isTypeAssignableTo( + getFunctionFromCalls(prop.calls!), + checker.createAnonymousType(undefined!, createSymbolTable(), [sig], emptyArray, undefined, undefined))); + } + else { + result = result && !!source && !!target && checker.isTypeAssignableTo(source, target); + } + }); + return result; + } + + + function getFunctionFromCalls(calls: CallUsage[]) { + return checker.createAnonymousType(undefined!, createSymbolTable(), [getSignatureFromCalls(calls)], emptyArray, undefined, undefined); + } + function getParameterTypeFromCalls(parameterIndex: number, calls: CallUsage[], isRestParameter: boolean) { let types: Type[] = []; if (calls) { @@ -904,16 +957,20 @@ namespace ts.codefix { return undefined; } - function getSignatureFromCall(call: CallUsage): Signature { + function getSignatureFromCalls(calls: CallUsage[]): Signature { const parameters: Symbol[] = []; - for (let i = 0; i < call.argumentTypes.length; i++) { + const length = Math.max(...calls.map(c => c.argumentTypes.length)); + for (let i = 0; i < length; i++) { const symbol = checker.createSymbol(SymbolFlags.FunctionScopedVariable, escapeLeadingUnderscores(`arg${i}`)); - symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(call.argumentTypes[i])); + symbol.type = unifyFromUsage(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType())); + if (calls.some(call => call.argumentTypes[i] === undefined)) { + symbol.flags |= SymbolFlags.Optional; + } parameters.push(symbol); } - const returnType = unifyFromUsage(inferFromUsage(call.returnType), checker.getVoidType()); + const returnType = unifyFromUsage(inferFromUsage(combineUsages(calls.map(call => call.return_))), checker.getVoidType()); // TODO: GH#18217 - return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, call.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } function addCandidateType(usage: Usage, type: Type | undefined) { From 945d423ef5b511ae157b15849b2b822de4b48953 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 28 Aug 2019 14:12:21 -0700 Subject: [PATCH 017/100] Fix bugs in combineUsages/getSignatureFromCalls --- src/services/codefixes/inferFromUsage.ts | 76 +++++++++++++++++------- 1 file changed, 56 insertions(+), 20 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 4b111dae25b..92382c462fa 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -405,18 +405,19 @@ namespace ts.codefix { } interface Usage { - isNumber?: boolean; - isString?: boolean; + isNumber: boolean | undefined; + isString: boolean | undefined; /** Used ambiguously, eg x + ___ or object[___]; results in string | number if no other evidence exists */ - isNumberOrString?: boolean; + isNumberOrString: boolean | undefined; - candidateTypes?: Type[]; - properties?: UnderscoreEscapedMap; - calls?: CallUsage[]; - constructs?: CallUsage[]; - numberIndex?: Usage; - stringIndex?: Usage; - candidateThisTypes?: Type[]; + candidateTypes: Type[] | undefined; + properties: UnderscoreEscapedMap | undefined; + calls: CallUsage[] | undefined; + constructs: CallUsage[] | undefined; + numberIndex: Usage | undefined; + stringIndex: Usage | undefined; + candidateThisTypes: Type[] | undefined; + inferredTypes: Type[] | undefined; } function single(): Type { @@ -428,7 +429,7 @@ namespace ts.codefix { return undefined; } - const usage: Usage = {}; + const usage = createEmptyUsage(); for (const reference of references) { cancellationToken.throwIfCancellationRequested(); calculateUsageOfNode(reference, usage); @@ -466,7 +467,7 @@ namespace ts.codefix { } function thisParameter() { - const usage: Usage = {}; + const usage = createEmptyUsage(); for (const reference of references) { cancellationToken.throwIfCancellationRequested(); calculateUsageOfNode(reference, usage); @@ -476,7 +477,7 @@ namespace ts.codefix { } function inferTypesFromReferencesSingle(references: readonly Identifier[]): Type[] { - const usage: Usage = {}; + const usage: Usage = createEmptyUsage(); for (const reference of references) { cancellationToken.throwIfCancellationRequested(); calculateUsageOfNode(reference, usage); @@ -671,7 +672,7 @@ namespace ts.codefix { function inferTypeFromCallExpression(parent: CallExpression | NewExpression, usage: Usage): void { const call: CallUsage = { argumentTypes: [], - return_: {} + return_: createEmptyUsage() }; if (parent.arguments) { @@ -695,7 +696,7 @@ namespace ts.codefix { if (!usage.properties) { usage.properties = createUnderscoreEscapedMap(); } - const propertyUsage = usage.properties.get(name) || { }; + const propertyUsage = usage.properties.get(name) || createEmptyUsage(); calculateUsageOfNode(parent, propertyUsage); usage.properties.set(name, propertyUsage); } @@ -707,7 +708,7 @@ namespace ts.codefix { } else { const indexType = checker.getTypeAtLocation(parent.argumentExpression); - const indexUsage = {}; + const indexUsage = createEmptyUsage(); calculateUsageOfNode(parent, indexUsage); if (indexType.flags & TypeFlags.NumberLike) { usage.numberIndex = indexUsage; @@ -845,7 +846,10 @@ namespace ts.codefix { if (usage.numberIndex) { types.push(checker.createArrayType(recur(usage.numberIndex))); } - else if (usage.properties || usage.calls || usage.constructs || usage.stringIndex) { + else if (usage.properties && usage.properties.size + || usage.calls && usage.calls.length + || usage.constructs && usage.constructs.length + || usage.stringIndex) { const members = createUnderscoreEscapedMap(); const callSignatures: Signature[] = []; const constructSignatures: Signature[] = []; @@ -873,25 +877,57 @@ namespace ts.codefix { types.push(checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined)); // TODO: GH#18217 } - return types; + return types; // TODO: Should cache this since I HOPE it doesn't change function recur(innerUsage: Usage): Type { return unifyFromUsage(inferFromUsage(innerUsage)); } } + function createEmptyUsage(): Usage { + return { + isNumber: undefined, + isString: undefined, + isNumberOrString: undefined, + candidateTypes: undefined, + properties: undefined, + calls: undefined, + constructs: undefined, + numberIndex: undefined, + stringIndex: undefined, + candidateThisTypes: undefined, + inferredTypes: undefined, + } + } + function combineUsages(usages: Usage[]): Usage { + const combinedProperties = createUnderscoreEscapedMap() + for (const u of usages) { + if (u.properties) { + u.properties.forEach((p,name) => { + if (!combinedProperties.has(name)) { + combinedProperties.set(name, []); + } + combinedProperties.get(name)!.push(p); + }); + } + } + const properties = createUnderscoreEscapedMap() + combinedProperties.forEach((ps,name) => { + properties.set(name, combineUsages(ps)); + }); return { isNumber: usages.some(u => u.isNumber), isString: usages.some(u => u.isString), isNumberOrString: usages.some(u => u.isNumberOrString), candidateTypes: flatMap(usages, u => u.candidateTypes) as Type[], - properties: undefined, // TODO + properties, calls: flatMap(usages, u => u.calls) as CallUsage[], constructs: flatMap(usages, u => u.constructs) as CallUsage[], numberIndex: forEach(usages, u => u.numberIndex), stringIndex: forEach(usages, u => u.stringIndex), candidateThisTypes: flatMap(usages, u => u.candidateThisTypes) as Type[], + inferredTypes: undefined, // clear type cache } } @@ -901,7 +937,7 @@ namespace ts.codefix { checker.getNumberType(), checker.createArrayType(checker.getAnyType()), checker.createPromiseType(checker.getAnyType()), - // checker.getFunctionType() // not sure what this was supposed to be good for. + // checker.getFunctionType() // TODO: not sure what this was supposed to be good for. ]; const matches = builtins.filter(t => matchesAllPropertiesOf(t, usage)); if (false && 0 < matches.length && matches.length < 3) { From 37150d9cb548e6e7802b731e8c03a298434e18d7 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 29 Aug 2019 12:40:33 -0700 Subject: [PATCH 018/100] Turn on findBuiltinTypes Type parameter inference is special-cased, just moved from its previous place with no improvement. --- src/services/codefixes/inferFromUsage.ts | 103 +++++++++--------- .../codeFixInferFromFunctionUsage.ts | 4 +- .../codeFixInferFromPrimitiveUsage.ts | 9 ++ .../codeFixInferFromUsageCallBodyBoth.ts | 2 +- 4 files changed, 65 insertions(+), 53 deletions(-) create mode 100644 tests/cases/fourslash/codeFixInferFromPrimitiveUsage.ts diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 92382c462fa..ab1c2a4a52d 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -421,7 +421,7 @@ namespace ts.codefix { } function single(): Type { - return unifyFromUsage(inferTypesFromReferencesSingle(references)); + return unifyTypes(inferTypesFromReferencesSingle(references)); } function parameters(declaration: FunctionLike): ParameterInference[] | undefined { @@ -457,7 +457,7 @@ namespace ts.codefix { const inferred = inferTypesFromReferencesSingle(getReferences(parameter.name, program, cancellationToken)); types.push(...(isRest ? mapDefined(inferred, checker.getElementTypeOfArrayType) : inferred)); } - const type = unifyFromUsage(types); + const type = unifyTypes(types); return { type: isRest ? checker.createArrayType(type) : type, isOptional: isOptional && !isRest, @@ -473,7 +473,7 @@ namespace ts.codefix { calculateUsageOfNode(reference, usage); } - return unifyFromUsage(usage.candidateThisTypes || emptyArray); + return unifyTypes(usage.candidateThisTypes || emptyArray); } function inferTypesFromReferencesSingle(references: readonly Identifier[]): Type[] { @@ -627,6 +627,9 @@ namespace ts.codefix { else if (otherOperandType.flags & TypeFlags.StringLike) { usage.isString = true; } + else if (otherOperandType.flags & TypeFlags.Any) { + // do nothing, maybe we'll learn something elsewhere + } else { usage.isNumberOrString = true; } @@ -748,7 +751,7 @@ namespace ts.codefix { return inferences.filter(i => toRemove.every(f => !f(i))); } - function unifyFromUsage(inferences: ReadonlyArray, fallback = checker.getAnyType()): Type { + function unifyTypes(inferences: ReadonlyArray, fallback = checker.getAnyType()): Type { if (!inferences.length) return fallback; // 1. string or number individually override string | number @@ -774,7 +777,7 @@ namespace ts.codefix { good = good.filter(i => !(checker.getObjectFlags(i) & ObjectFlags.Anonymous)); good.push(unifyAnonymousTypes(anons)); } - return checker.getWidenedType(checker.getUnionType(good)); + return checker.getWidenedType(checker.getUnionType(good, UnionReduction.Subtype)); } function unifyAnonymousTypes(anons: AnonymousType[]) { @@ -832,16 +835,7 @@ namespace ts.codefix { } types.push(...(usage.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t))); - types.push(...findBuiltinType(usage)); - - if (usage.properties && hasCalls(usage.properties.get("then" as __String))) { - const paramType = getParameterTypeFromCalls(0, usage.properties.get("then" as __String)!.calls!, /*isRestParameter*/ false)!; // TODO: GH#18217 - const types = paramType.getCallSignatures().map(sig => sig.getReturnType()); - types.push(checker.createPromiseType(types.length ? checker.getUnionType(types, UnionReduction.Subtype) : checker.getAnyType())); - } - else if (usage.properties && hasCalls(usage.properties.get("push" as __String))) { - types.push(checker.createArrayType(getParameterTypeFromCalls(0, usage.properties.get("push" as __String)!.calls!, /*isRestParameter*/ false)!)); - } + types.push(...findBuiltinTypes(usage)); if (usage.numberIndex) { types.push(checker.createArrayType(recur(usage.numberIndex))); @@ -864,11 +858,12 @@ namespace ts.codefix { } if (usage.calls) { - callSignatures.push(getSignatureFromCalls(usage.calls)); + callSignatures.push(getSignatureFromCalls(usage.calls, checker.getVoidType())); } if (usage.constructs) { - constructSignatures.push(getSignatureFromCalls(usage.constructs)); + // TODO: fallback return should maybe be {}? + constructSignatures.push(getSignatureFromCalls(usage.constructs, checker.getVoidType())); } if (usage.stringIndex) { @@ -880,7 +875,7 @@ namespace ts.codefix { return types; // TODO: Should cache this since I HOPE it doesn't change function recur(innerUsage: Usage): Type { - return unifyFromUsage(inferFromUsage(innerUsage)); + return unifyTypes(inferFromUsage(innerUsage)); } } @@ -931,7 +926,8 @@ namespace ts.codefix { } } - function findBuiltinType(usage: Usage): Type[] { + function findBuiltinTypes(usage: Usage): Type[] { + if (!usage.properties || !usage.properties.size) return []; const builtins = [ checker.getStringType(), checker.getNumberType(), @@ -939,9 +935,21 @@ namespace ts.codefix { checker.createPromiseType(checker.getAnyType()), // checker.getFunctionType() // TODO: not sure what this was supposed to be good for. ]; + // TODO: Still need to infer type parameters const matches = builtins.filter(t => matchesAllPropertiesOf(t, usage)); - if (false && 0 < matches.length && matches.length < 3) { - return matches; + if (0 < matches.length && matches.length < 3) { + return matches.map(m => { + // special-case array and promise for now + if (m === builtins[3] && hasCalls(usage.properties!.get("then" as __String))) { + const paramType = getParameterTypeFromCalls(0, usage.properties!.get("then" as __String)!.calls!, /*isRestParameter*/ false)!; // TODO: GH#18217 + const returns = paramType.getCallSignatures().map(sig => sig.getReturnType()); + return checker.createPromiseType(returns.length ? checker.getUnionType(returns, UnionReduction.Subtype) : checker.getAnyType()); + } + else if (m === builtins[2] && hasCalls(usage.properties!.get("push" as __String))) { + return checker.createArrayType(getParameterTypeFromCalls(0, usage.properties!.get("push" as __String)!.calls!, /*isRestParameter*/ false)!); + } + return m; + }); } return []; } @@ -949,18 +957,18 @@ namespace ts.codefix { function matchesAllPropertiesOf(type: Type, usage: Usage) { if (!usage.properties) return false; let result = true; - usage.properties.forEach((prop, name) => { - const source = checker.getUnionType(inferFromUsage(prop)); - const target = checker.getTypeOfPropertyOfType(type, name as string); - if (target && prop.calls) { - const sigs = checker.getSignaturesOfType(target, ts.SignatureKind.Call); - result = result && !!sigs.length && sigs.some( - sig => checker.isTypeAssignableTo( - getFunctionFromCalls(prop.calls!), - checker.createAnonymousType(undefined!, createSymbolTable(), [sig], emptyArray, undefined, undefined))); + usage.properties.forEach((propUsage, name) => { + const source = checker.getTypeOfPropertyOfType(type, name as string); + if (!source) { + result = false; + return; + } + if (propUsage.calls) { + const sigs = checker.getSignaturesOfType(source, ts.SignatureKind.Call); + result = result && !!sigs.length && checker.isTypeAssignableTo(source, getFunctionFromCalls(propUsage.calls)); } else { - result = result && !!source && !!target && checker.isTypeAssignableTo(source, target); + result = result && checker.isTypeAssignableTo(source, unifyTypes(inferFromUsage(propUsage))); } }); return result; @@ -968,43 +976,38 @@ namespace ts.codefix { function getFunctionFromCalls(calls: CallUsage[]) { - return checker.createAnonymousType(undefined!, createSymbolTable(), [getSignatureFromCalls(calls)], emptyArray, undefined, undefined); + return checker.createAnonymousType(undefined!, createSymbolTable(), [getSignatureFromCalls(calls, checker.getAnyType())], emptyArray, undefined, undefined); } function getParameterTypeFromCalls(parameterIndex: number, calls: CallUsage[], isRestParameter: boolean) { + // TODO: This is largely redundant with getSignatureFromCalls, I think. (though it handles rest parameters correctly, so that needs to be integrated there) let types: Type[] = []; - if (calls) { - for (const call of calls) { - if (call.argumentTypes.length > parameterIndex) { - if (isRestParameter) { - types = concatenate(types, map(call.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); - } - else { - types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[parameterIndex])); - } + for (const call of calls) { + if (call.argumentTypes.length > parameterIndex) { + if (isRestParameter) { + types = concatenate(types, map(call.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); + } + else { + types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[parameterIndex])); } } } - - if (types.length) { - const type = checker.getWidenedType(checker.getUnionType(types, UnionReduction.Subtype)); - return isRestParameter ? checker.createArrayType(type) : type; - } - return undefined; + const type = unifyTypes(types); + return isRestParameter ? checker.createArrayType(type) : type; } - function getSignatureFromCalls(calls: CallUsage[]): Signature { + function getSignatureFromCalls(calls: CallUsage[], fallbackReturn: Type): Signature { const parameters: Symbol[] = []; const length = Math.max(...calls.map(c => c.argumentTypes.length)); for (let i = 0; i < length; i++) { const symbol = checker.createSymbol(SymbolFlags.FunctionScopedVariable, escapeLeadingUnderscores(`arg${i}`)); - symbol.type = unifyFromUsage(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType())); + symbol.type = unifyTypes(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType())); if (calls.some(call => call.argumentTypes[i] === undefined)) { symbol.flags |= SymbolFlags.Optional; } parameters.push(symbol); } - const returnType = unifyFromUsage(inferFromUsage(combineUsages(calls.map(call => call.return_))), checker.getVoidType()); + const returnType = unifyTypes(inferFromUsage(combineUsages(calls.map(call => call.return_))), fallbackReturn); // TODO: GH#18217 return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } diff --git a/tests/cases/fourslash/codeFixInferFromFunctionUsage.ts b/tests/cases/fourslash/codeFixInferFromFunctionUsage.ts index 27a039878ba..f2dbad67b4b 100644 --- a/tests/cases/fourslash/codeFixInferFromFunctionUsage.ts +++ b/tests/cases/fourslash/codeFixInferFromFunctionUsage.ts @@ -2,8 +2,8 @@ // @noImplicitAny: true ////function wrap( [| arr |] ) { -//// arr.sort(function (a: number, b: number) { return a < b ? -1 : 1 }) +//// arr.other(function (a: number, b: number) { return a < b ? -1 : 1 }) //// } // https://github.com/Microsoft/TypeScript/issues/29330 -verify.rangeAfterCodeFix("arr: { sort: (arg0: (a: number, b: number) => 1 | -1) => void; }"); +verify.rangeAfterCodeFix("arr: { other: (arg0: (a: number, b: number) => 1 | -1) => void; }"); diff --git a/tests/cases/fourslash/codeFixInferFromPrimitiveUsage.ts b/tests/cases/fourslash/codeFixInferFromPrimitiveUsage.ts new file mode 100644 index 00000000000..81c25770085 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromPrimitiveUsage.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +////function wrap( [| s |] ) { +//// return s.length + s.toUpperCase() +//// } + +// https://github.com/Microsoft/TypeScript/issues/29330 +verify.rangeAfterCodeFix("s: string"); diff --git a/tests/cases/fourslash/codeFixInferFromUsageCallBodyBoth.ts b/tests/cases/fourslash/codeFixInferFromUsageCallBodyBoth.ts index 859d5ea2ce7..f59d1bc1907 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageCallBodyBoth.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageCallBodyBoth.ts @@ -1,7 +1,7 @@ /// ////class C { -//// +//// p = 2 ////} ////var c = new C() ////function f([|x, y |]) { From 909bc61f01253dcb9bc944463434d4117ad910a9 Mon Sep 17 00:00:00 2001 From: xiaofa Date: Fri, 30 Aug 2019 17:37:27 +0800 Subject: [PATCH 019/100] Add convert const to let --- src/compiler/diagnosticMessages.json | 4 +++ src/services/codefixes/convertConstToLet.ts | 32 +++++++++++++++++++++ src/services/tsconfig.json | 1 + tests/cases/fourslash/codeFixConstToLet.ts | 12 ++++++++ 4 files changed, 49 insertions(+) create mode 100644 src/services/codefixes/convertConstToLet.ts create mode 100644 tests/cases/fourslash/codeFixConstToLet.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b296c224d08..bf08c95f10c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5124,6 +5124,10 @@ "category": "Message", "code": 95090 }, + "Convert 'const' to 'let'": { + "category": "Message", + "code": 95091 + }, "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": { "category": "Error", diff --git a/src/services/codefixes/convertConstToLet.ts b/src/services/codefixes/convertConstToLet.ts new file mode 100644 index 00000000000..df027f7d8c8 --- /dev/null +++ b/src/services/codefixes/convertConstToLet.ts @@ -0,0 +1,32 @@ +/* @internal */ +namespace ts.codefix { + const fixId = "fixConvertConstToLet"; + const errorCodes = [Diagnostics.Cannot_assign_to_0_because_it_is_a_constant.code]; + + registerCodeFix({ + errorCodes, + getCodeActions: context => { + const { sourceFile, span, program } = context; + const variableStatement = getVaribleStatement(sourceFile, span.start, program); + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, variableStatement)); + return [createCodeFixAction(fixId, changes, Diagnostics.Convert_const_to_let, fixId, Diagnostics.Convert_const_to_let)]; + }, + fixIds: [fixId] + }); + + function getVaribleStatement(sourceFile: SourceFile, pos: number, program: Program) { + const token = getTokenAtPosition(sourceFile, pos); + const checker = program.getTypeChecker(); + const symbol = checker.getSymbolAtLocation(token); + if (symbol) { + return symbol.valueDeclaration.parent.parent as VariableStatement; + } + } + function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, variableStatement?: VariableStatement) { + if (!variableStatement) { + return; + } + const start = variableStatement.getStart(); + changes.replaceRangeWithText(sourceFile, { pos: start, end: start + 5 }, "let"); + } +} diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 6b52393422c..965ea4d5ac4 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -82,6 +82,7 @@ "codefixes/fixAddModuleReferTypeMissingTypeof.ts", "codefixes/convertToMappedObjectType.ts", "codefixes/removeUnnecessaryAwait.ts", + "codefixes/convertConstToLet.ts", "refactors/convertExport.ts", "refactors/convertImport.ts", "refactors/extractSymbol.ts", diff --git a/tests/cases/fourslash/codeFixConstToLet.ts b/tests/cases/fourslash/codeFixConstToLet.ts new file mode 100644 index 00000000000..949c45104a2 --- /dev/null +++ b/tests/cases/fourslash/codeFixConstToLet.ts @@ -0,0 +1,12 @@ +/// + +//// const x = 42; +//// x = 75; + +verify.codeFix({ + description: "Convert 'const' to 'let'", + index: 0, + newFileContent: +`let x = 42; +x = 75;` +}); \ No newline at end of file From 383286ff533aad1e9fe3bfa907ef84689eff920e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 30 Aug 2019 13:44:06 -0700 Subject: [PATCH 020/100] Add type parameter inference It's a smeary copy of the checker's type parameter, so I feel bad about duplicating that code. Not sure what the solution is, architecturally. --- src/services/codefixes/inferFromUsage.ts | 132 ++++++++++++------ .../codeFixInferFromPrimitiveUsage.ts | 7 +- 2 files changed, 94 insertions(+), 45 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index ab1c2a4a52d..0a190e7b379 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -393,6 +393,19 @@ namespace ts.codefix { function inferTypeFromReferences(program: Program, references: ReadonlyArray, cancellationToken: CancellationToken) { const checker = program.getTypeChecker(); + const builtinConstructors: { [s: string]: (t: Type) => Type } = { + string: () => checker.getStringType(), + number: () => checker.getNumberType(), + Array: t => checker.createArrayType(t), + Promise: t => checker.createPromiseType(t), + }; + const builtins = [ + checker.getStringType(), + checker.getNumberType(), + checker.createArrayType(checker.getAnyType()), + checker.createPromiseType(checker.getAnyType()), + ]; + return { single, parameters, @@ -777,7 +790,7 @@ namespace ts.codefix { good = good.filter(i => !(checker.getObjectFlags(i) & ObjectFlags.Anonymous)); good.push(unifyAnonymousTypes(anons)); } - return checker.getWidenedType(checker.getUnionType(good, UnionReduction.Subtype)); + return checker.getWidenedType(checker.getUnionType(good.map(checker.getBaseTypeOfLiteralType), UnionReduction.Subtype)); } function unifyAnonymousTypes(anons: AnonymousType[]) { @@ -928,28 +941,9 @@ namespace ts.codefix { function findBuiltinTypes(usage: Usage): Type[] { if (!usage.properties || !usage.properties.size) return []; - const builtins = [ - checker.getStringType(), - checker.getNumberType(), - checker.createArrayType(checker.getAnyType()), - checker.createPromiseType(checker.getAnyType()), - // checker.getFunctionType() // TODO: not sure what this was supposed to be good for. - ]; - // TODO: Still need to infer type parameters const matches = builtins.filter(t => matchesAllPropertiesOf(t, usage)); if (0 < matches.length && matches.length < 3) { - return matches.map(m => { - // special-case array and promise for now - if (m === builtins[3] && hasCalls(usage.properties!.get("then" as __String))) { - const paramType = getParameterTypeFromCalls(0, usage.properties!.get("then" as __String)!.calls!, /*isRestParameter*/ false)!; // TODO: GH#18217 - const returns = paramType.getCallSignatures().map(sig => sig.getReturnType()); - return checker.createPromiseType(returns.length ? checker.getUnionType(returns, UnionReduction.Subtype) : checker.getAnyType()); - } - else if (m === builtins[2] && hasCalls(usage.properties!.get("push" as __String))) { - return checker.createArrayType(getParameterTypeFromCalls(0, usage.properties!.get("push" as __String)!.calls!, /*isRestParameter*/ false)!); - } - return m; - }); + return matches.map(m => inferTypeParameterFromUsage(m, usage)); } return []; } @@ -974,28 +968,86 @@ namespace ts.codefix { return result; } + // inference is limited to + // 1. generic types with a single parameter + // 2. inference to/from calls with a single signature + function inferTypeParameterFromUsage(type: Type, usage: Usage) { + if (!usage.properties || !(getObjectFlags(type) & ObjectFlags.Reference)) return type; + const generic = (type as TypeReference).target; + const singleTypeParameter = singleOrUndefined(generic.typeParameters); + if (!singleTypeParameter) return type; + + const types: Type[] = []; + usage.properties.forEach((propUsage, name) => { + const source = checker.getTypeOfPropertyOfType(generic, name as string); + if (!source) { + return Debug.fail("generic should have all the properties of its reference."); + } + if (!propUsage.calls) return; + + types.push(...infer(source, getFunctionFromCalls(propUsage.calls), singleTypeParameter)); + }); + return builtinConstructors[type.symbol.escapedName as string](unifyTypes(types)); + } + + // TODO: Source and target are bad names. Should be builtinType and usageType...or something + // and search is a bad name + function infer(source: Type, target: Type, search: Type): readonly Type[] { + if (source === search) { + return [target]; + } + else if (source.flags & TypeFlags.UnionOrIntersection) { + return flatMap((source as UnionOrIntersectionType).types, t => infer(t, target, search)); + } + else if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference) { + // this is wrong because we need a reference to the targetType to, so we can check that it's also a reference + const sourceArgs = (source as TypeReference).typeArguments; + const targetArgs = (target as TypeReference).typeArguments; + const types = []; + if (sourceArgs && targetArgs) { + for (let i = 0; i < sourceArgs.length; i++) { + if (targetArgs[i]) { + types.push(...infer(sourceArgs[i], targetArgs[i], search)); + } + } + } + return types; + } + const sourceSigs = checker.getSignaturesOfType(source, SignatureKind.Call); + const targetSigs = checker.getSignaturesOfType(target, SignatureKind.Call); + if (sourceSigs.length === 1 && targetSigs.length === 1) { + return inferFromSignatures(sourceSigs[0], targetSigs[0], search); + } + return []; + } + + function inferFromSignatures(sourceSig: Signature, targetSig: Signature, search: Type) { + const types = []; + for (let i = 0; i < sourceSig.parameters.length; i++) { + const sourceParam = sourceSig.parameters[i]; + const targetParam = targetSig.parameters[i]; + const isRest = sourceSig.declaration && isRestParameter(sourceSig.declaration.parameters[i]); + if (!targetParam) { + break; + } + let sourceType = checker.getTypeOfSymbolAtLocation(sourceParam, sourceParam.valueDeclaration); + let elementType = isRest && checker.getElementTypeOfArrayType(sourceType); + if (elementType) { + sourceType = elementType; + } + const targetType = (targetParam as SymbolLinks).type || checker.getTypeOfSymbolAtLocation(targetParam, targetParam.valueDeclaration); + types.push(...infer(sourceType, targetType, search)); + } + const sourceReturn = checker.getReturnTypeOfSignature(sourceSig); + const targetReturn = checker.getReturnTypeOfSignature(targetSig); + types.push(...infer(sourceReturn, targetReturn, search)); + return types; + } function getFunctionFromCalls(calls: CallUsage[]) { return checker.createAnonymousType(undefined!, createSymbolTable(), [getSignatureFromCalls(calls, checker.getAnyType())], emptyArray, undefined, undefined); } - function getParameterTypeFromCalls(parameterIndex: number, calls: CallUsage[], isRestParameter: boolean) { - // TODO: This is largely redundant with getSignatureFromCalls, I think. (though it handles rest parameters correctly, so that needs to be integrated there) - let types: Type[] = []; - for (const call of calls) { - if (call.argumentTypes.length > parameterIndex) { - if (isRestParameter) { - types = concatenate(types, map(call.argumentTypes.slice(parameterIndex), a => checker.getBaseTypeOfLiteralType(a))); - } - else { - types.push(checker.getBaseTypeOfLiteralType(call.argumentTypes[parameterIndex])); - } - } - } - const type = unifyTypes(types); - return isRestParameter ? checker.createArrayType(type) : type; - } - function getSignatureFromCalls(calls: CallUsage[], fallbackReturn: Type): Signature { const parameters: Symbol[] = []; const length = Math.max(...calls.map(c => c.argumentTypes.length)); @@ -1023,9 +1075,5 @@ namespace ts.codefix { (usage.candidateThisTypes || (usage.candidateThisTypes = [])).push(type); } } - - function hasCalls(usage: Usage | undefined): boolean { - return !!usage && !!usage.calls; - } } } diff --git a/tests/cases/fourslash/codeFixInferFromPrimitiveUsage.ts b/tests/cases/fourslash/codeFixInferFromPrimitiveUsage.ts index 81c25770085..b74e49b4d39 100644 --- a/tests/cases/fourslash/codeFixInferFromPrimitiveUsage.ts +++ b/tests/cases/fourslash/codeFixInferFromPrimitiveUsage.ts @@ -1,9 +1,10 @@ /// // @noImplicitAny: true -////function wrap( [| s |] ) { -//// return s.length + s.toUpperCase() +//// function wrap( [| s |] ) { +//// return s.length + s.indexOf('hi') //// } // https://github.com/Microsoft/TypeScript/issues/29330 -verify.rangeAfterCodeFix("s: string"); +verify.rangeAfterCodeFix("s: string | string[]"); + From 8ffc42f5a6739f257ecf52a24fee0c45c1c282a3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 3 Sep 2019 15:24:49 -0700 Subject: [PATCH 021/100] Don't instantiate-in-context-of when inferring to type variable --- src/compiler/checker.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cfad47b6533..f51aee47a1a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -177,6 +177,7 @@ namespace ts { const enum ContextFlags { None = 0, Signature = 1 << 0, // Obtaining contextual signature + NoConstraints = 1 << 1, // Don't obtain type variable constraints } const enum AccessFlags { @@ -19193,7 +19194,7 @@ namespace ts { getContextualTypeForObjectLiteralMethod(node, contextFlags) : getContextualType(node, contextFlags); const instantiatedType = instantiateContextualType(contextualType, node, contextFlags); - if (instantiatedType) { + if (instantiatedType && !(contextFlags && contextFlags & ContextFlags.NoConstraints && instantiatedType.flags & TypeFlags.TypeVariable)) { const apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true); if (apparentType.flags & TypeFlags.Union) { if (isObjectLiteralExpression(node)) { @@ -25098,8 +25099,8 @@ namespace ts { const constructSignature = getSingleSignature(type, SignatureKind.Construct, /*allowMembers*/ true); const signature = callSignature || constructSignature; if (signature && signature.typeParameters) { - const contextualType = getApparentTypeOfContextualType(node); - if (contextualType && !isMixinConstructorType(contextualType)) { + const contextualType = getApparentTypeOfContextualType(node, ContextFlags.NoConstraints); + if (contextualType) { const contextualSignature = getSingleSignature(getNonNullableType(contextualType), callSignature ? SignatureKind.Call : SignatureKind.Construct, /*allowMembers*/ false); if (contextualSignature && !contextualSignature.typeParameters) { if (checkMode & CheckMode.SkipGenericFunctions) { From c02fdaa590ecea073894d0d05b3cadd60270d5ff Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 3 Sep 2019 16:36:41 -0700 Subject: [PATCH 022/100] Accept new baselines --- .../reference/functionConstraintSatisfaction2.types | 4 ++-- .../reference/functionConstraintSatisfaction3.types | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/functionConstraintSatisfaction2.types b/tests/baselines/reference/functionConstraintSatisfaction2.types index f5a7eb0fd65..f0a0f3b61f2 100644 --- a/tests/baselines/reference/functionConstraintSatisfaction2.types +++ b/tests/baselines/reference/functionConstraintSatisfaction2.types @@ -79,8 +79,8 @@ var r7 = foo2(b); >b : new (x: string) => string var r8 = foo2((x: U) => x); // no error expected ->r8 : (x: string) => string ->foo2((x: U) => x) : (x: string) => string +>r8 : (x: U) => U +>foo2((x: U) => x) : (x: U) => U >foo2 : string>(x: T) => T >(x: U) => x : (x: U) => U >x : U diff --git a/tests/baselines/reference/functionConstraintSatisfaction3.types b/tests/baselines/reference/functionConstraintSatisfaction3.types index 499f73b1664..dc760608c73 100644 --- a/tests/baselines/reference/functionConstraintSatisfaction3.types +++ b/tests/baselines/reference/functionConstraintSatisfaction3.types @@ -103,16 +103,16 @@ var c2: { (x: T): T; (x: T, y: T): T }; >y : T var r9 = foo(function (x: U) { return x; }); ->r9 : (x: string) => string ->foo(function (x: U) { return x; }) : (x: string) => string +>r9 : (x: U) => U +>foo(function (x: U) { return x; }) : (x: U) => U >foo : string>(x: T) => T >function (x: U) { return x; } : (x: U) => U >x : U >x : U var r10 = foo((x: U) => x); ->r10 : (x: string) => string ->foo((x: U) => x) : (x: string) => string +>r10 : (x: U) => U +>foo((x: U) => x) : (x: U) => U >foo : string>(x: T) => T >(x: U) => x : (x: U) => U >x : U From 4bd9b62fa6e02cc72eb511a23cc42ea1dc153f86 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 3 Sep 2019 17:23:43 -0700 Subject: [PATCH 023/100] Add regression tests --- .../contextualSignatureInstantiation4.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/cases/compiler/contextualSignatureInstantiation4.ts diff --git a/tests/cases/compiler/contextualSignatureInstantiation4.ts b/tests/cases/compiler/contextualSignatureInstantiation4.ts new file mode 100644 index 00000000000..6c29ca3d40a --- /dev/null +++ b/tests/cases/compiler/contextualSignatureInstantiation4.ts @@ -0,0 +1,20 @@ +// @strict: true + +// Repros from #32976 + +declare class Banana { constructor(a: string, property: T) } + +declare function fruitFactory1(Fruit: new (...args: any[]) => TFruit): TFruit +const banana1 = fruitFactory1(Banana) // Banana + +declare function fruitFactory2(Fruit: new (a: string, ...args: any[]) => TFruit): TFruit +const banana2 = fruitFactory2(Banana) // Banana + +declare function fruitFactory3(Fruit: new (a: string, s: "foo", ...args: any[]) => TFruit): TFruit +const banana3 = fruitFactory3(Banana) // Banana<"foo"> + +declare function fruitFactory4(Fruit: new (a: string, ...args: "foo"[]) => TFruit): TFruit +const banana4 = fruitFactory4(Banana) // Banana<"foo"> + +declare function fruitFactory5(Fruit: new (...args: "foo"[]) => TFruit): TFruit +const banana5 = fruitFactory5(Banana) // Banana<"foo"> From bbec8b36ef346e497a90bc99c00556dc97939976 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 3 Sep 2019 17:23:52 -0700 Subject: [PATCH 024/100] Accept new baselines --- .../contextualSignatureInstantiation4.js | 29 +++++++ .../contextualSignatureInstantiation4.symbols | 79 +++++++++++++++++++ .../contextualSignatureInstantiation4.types | 67 ++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 tests/baselines/reference/contextualSignatureInstantiation4.js create mode 100644 tests/baselines/reference/contextualSignatureInstantiation4.symbols create mode 100644 tests/baselines/reference/contextualSignatureInstantiation4.types diff --git a/tests/baselines/reference/contextualSignatureInstantiation4.js b/tests/baselines/reference/contextualSignatureInstantiation4.js new file mode 100644 index 00000000000..8db041b29b5 --- /dev/null +++ b/tests/baselines/reference/contextualSignatureInstantiation4.js @@ -0,0 +1,29 @@ +//// [contextualSignatureInstantiation4.ts] +// Repros from #32976 + +declare class Banana { constructor(a: string, property: T) } + +declare function fruitFactory1(Fruit: new (...args: any[]) => TFruit): TFruit +const banana1 = fruitFactory1(Banana) // Banana + +declare function fruitFactory2(Fruit: new (a: string, ...args: any[]) => TFruit): TFruit +const banana2 = fruitFactory2(Banana) // Banana + +declare function fruitFactory3(Fruit: new (a: string, s: "foo", ...args: any[]) => TFruit): TFruit +const banana3 = fruitFactory3(Banana) // Banana<"foo"> + +declare function fruitFactory4(Fruit: new (a: string, ...args: "foo"[]) => TFruit): TFruit +const banana4 = fruitFactory4(Banana) // Banana<"foo"> + +declare function fruitFactory5(Fruit: new (...args: "foo"[]) => TFruit): TFruit +const banana5 = fruitFactory5(Banana) // Banana<"foo"> + + +//// [contextualSignatureInstantiation4.js] +"use strict"; +// Repros from #32976 +var banana1 = fruitFactory1(Banana); // Banana +var banana2 = fruitFactory2(Banana); // Banana +var banana3 = fruitFactory3(Banana); // Banana<"foo"> +var banana4 = fruitFactory4(Banana); // Banana<"foo"> +var banana5 = fruitFactory5(Banana); // Banana<"foo"> diff --git a/tests/baselines/reference/contextualSignatureInstantiation4.symbols b/tests/baselines/reference/contextualSignatureInstantiation4.symbols new file mode 100644 index 00000000000..a08486b43d8 --- /dev/null +++ b/tests/baselines/reference/contextualSignatureInstantiation4.symbols @@ -0,0 +1,79 @@ +=== tests/cases/compiler/contextualSignatureInstantiation4.ts === +// Repros from #32976 + +declare class Banana { constructor(a: string, property: T) } +>Banana : Symbol(Banana, Decl(contextualSignatureInstantiation4.ts, 0, 0)) +>T : Symbol(T, Decl(contextualSignatureInstantiation4.ts, 2, 21)) +>a : Symbol(a, Decl(contextualSignatureInstantiation4.ts, 2, 53)) +>property : Symbol(property, Decl(contextualSignatureInstantiation4.ts, 2, 63)) +>T : Symbol(T, Decl(contextualSignatureInstantiation4.ts, 2, 21)) + +declare function fruitFactory1(Fruit: new (...args: any[]) => TFruit): TFruit +>fruitFactory1 : Symbol(fruitFactory1, Decl(contextualSignatureInstantiation4.ts, 2, 78)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 4, 31)) +>Fruit : Symbol(Fruit, Decl(contextualSignatureInstantiation4.ts, 4, 39)) +>args : Symbol(args, Decl(contextualSignatureInstantiation4.ts, 4, 51)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 4, 31)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 4, 31)) + +const banana1 = fruitFactory1(Banana) // Banana +>banana1 : Symbol(banana1, Decl(contextualSignatureInstantiation4.ts, 5, 5)) +>fruitFactory1 : Symbol(fruitFactory1, Decl(contextualSignatureInstantiation4.ts, 2, 78)) +>Banana : Symbol(Banana, Decl(contextualSignatureInstantiation4.ts, 0, 0)) + +declare function fruitFactory2(Fruit: new (a: string, ...args: any[]) => TFruit): TFruit +>fruitFactory2 : Symbol(fruitFactory2, Decl(contextualSignatureInstantiation4.ts, 5, 37)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 7, 31)) +>Fruit : Symbol(Fruit, Decl(contextualSignatureInstantiation4.ts, 7, 39)) +>a : Symbol(a, Decl(contextualSignatureInstantiation4.ts, 7, 51)) +>args : Symbol(args, Decl(contextualSignatureInstantiation4.ts, 7, 61)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 7, 31)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 7, 31)) + +const banana2 = fruitFactory2(Banana) // Banana +>banana2 : Symbol(banana2, Decl(contextualSignatureInstantiation4.ts, 8, 5)) +>fruitFactory2 : Symbol(fruitFactory2, Decl(contextualSignatureInstantiation4.ts, 5, 37)) +>Banana : Symbol(Banana, Decl(contextualSignatureInstantiation4.ts, 0, 0)) + +declare function fruitFactory3(Fruit: new (a: string, s: "foo", ...args: any[]) => TFruit): TFruit +>fruitFactory3 : Symbol(fruitFactory3, Decl(contextualSignatureInstantiation4.ts, 8, 37)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 10, 31)) +>Fruit : Symbol(Fruit, Decl(contextualSignatureInstantiation4.ts, 10, 39)) +>a : Symbol(a, Decl(contextualSignatureInstantiation4.ts, 10, 51)) +>s : Symbol(s, Decl(contextualSignatureInstantiation4.ts, 10, 61)) +>args : Symbol(args, Decl(contextualSignatureInstantiation4.ts, 10, 71)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 10, 31)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 10, 31)) + +const banana3 = fruitFactory3(Banana) // Banana<"foo"> +>banana3 : Symbol(banana3, Decl(contextualSignatureInstantiation4.ts, 11, 5)) +>fruitFactory3 : Symbol(fruitFactory3, Decl(contextualSignatureInstantiation4.ts, 8, 37)) +>Banana : Symbol(Banana, Decl(contextualSignatureInstantiation4.ts, 0, 0)) + +declare function fruitFactory4(Fruit: new (a: string, ...args: "foo"[]) => TFruit): TFruit +>fruitFactory4 : Symbol(fruitFactory4, Decl(contextualSignatureInstantiation4.ts, 11, 37)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 13, 31)) +>Fruit : Symbol(Fruit, Decl(contextualSignatureInstantiation4.ts, 13, 39)) +>a : Symbol(a, Decl(contextualSignatureInstantiation4.ts, 13, 51)) +>args : Symbol(args, Decl(contextualSignatureInstantiation4.ts, 13, 61)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 13, 31)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 13, 31)) + +const banana4 = fruitFactory4(Banana) // Banana<"foo"> +>banana4 : Symbol(banana4, Decl(contextualSignatureInstantiation4.ts, 14, 5)) +>fruitFactory4 : Symbol(fruitFactory4, Decl(contextualSignatureInstantiation4.ts, 11, 37)) +>Banana : Symbol(Banana, Decl(contextualSignatureInstantiation4.ts, 0, 0)) + +declare function fruitFactory5(Fruit: new (...args: "foo"[]) => TFruit): TFruit +>fruitFactory5 : Symbol(fruitFactory5, Decl(contextualSignatureInstantiation4.ts, 14, 37)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 16, 31)) +>Fruit : Symbol(Fruit, Decl(contextualSignatureInstantiation4.ts, 16, 39)) +>args : Symbol(args, Decl(contextualSignatureInstantiation4.ts, 16, 51)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 16, 31)) +>TFruit : Symbol(TFruit, Decl(contextualSignatureInstantiation4.ts, 16, 31)) + +const banana5 = fruitFactory5(Banana) // Banana<"foo"> +>banana5 : Symbol(banana5, Decl(contextualSignatureInstantiation4.ts, 17, 5)) +>fruitFactory5 : Symbol(fruitFactory5, Decl(contextualSignatureInstantiation4.ts, 14, 37)) +>Banana : Symbol(Banana, Decl(contextualSignatureInstantiation4.ts, 0, 0)) + diff --git a/tests/baselines/reference/contextualSignatureInstantiation4.types b/tests/baselines/reference/contextualSignatureInstantiation4.types new file mode 100644 index 00000000000..1c27df7ff69 --- /dev/null +++ b/tests/baselines/reference/contextualSignatureInstantiation4.types @@ -0,0 +1,67 @@ +=== tests/cases/compiler/contextualSignatureInstantiation4.ts === +// Repros from #32976 + +declare class Banana { constructor(a: string, property: T) } +>Banana : Banana +>a : string +>property : T + +declare function fruitFactory1(Fruit: new (...args: any[]) => TFruit): TFruit +>fruitFactory1 : (Fruit: new (...args: any[]) => TFruit) => TFruit +>Fruit : new (...args: any[]) => TFruit +>args : any[] + +const banana1 = fruitFactory1(Banana) // Banana +>banana1 : Banana +>fruitFactory1(Banana) : Banana +>fruitFactory1 : (Fruit: new (...args: any[]) => TFruit) => TFruit +>Banana : typeof Banana + +declare function fruitFactory2(Fruit: new (a: string, ...args: any[]) => TFruit): TFruit +>fruitFactory2 : (Fruit: new (a: string, ...args: any[]) => TFruit) => TFruit +>Fruit : new (a: string, ...args: any[]) => TFruit +>a : string +>args : any[] + +const banana2 = fruitFactory2(Banana) // Banana +>banana2 : Banana +>fruitFactory2(Banana) : Banana +>fruitFactory2 : (Fruit: new (a: string, ...args: any[]) => TFruit) => TFruit +>Banana : typeof Banana + +declare function fruitFactory3(Fruit: new (a: string, s: "foo", ...args: any[]) => TFruit): TFruit +>fruitFactory3 : (Fruit: new (a: string, s: "foo", ...args: any[]) => TFruit) => TFruit +>Fruit : new (a: string, s: "foo", ...args: any[]) => TFruit +>a : string +>s : "foo" +>args : any[] + +const banana3 = fruitFactory3(Banana) // Banana<"foo"> +>banana3 : Banana<"foo"> +>fruitFactory3(Banana) : Banana<"foo"> +>fruitFactory3 : (Fruit: new (a: string, s: "foo", ...args: any[]) => TFruit) => TFruit +>Banana : typeof Banana + +declare function fruitFactory4(Fruit: new (a: string, ...args: "foo"[]) => TFruit): TFruit +>fruitFactory4 : (Fruit: new (a: string, ...args: "foo"[]) => TFruit) => TFruit +>Fruit : new (a: string, ...args: "foo"[]) => TFruit +>a : string +>args : "foo"[] + +const banana4 = fruitFactory4(Banana) // Banana<"foo"> +>banana4 : Banana<"foo"> +>fruitFactory4(Banana) : Banana<"foo"> +>fruitFactory4 : (Fruit: new (a: string, ...args: "foo"[]) => TFruit) => TFruit +>Banana : typeof Banana + +declare function fruitFactory5(Fruit: new (...args: "foo"[]) => TFruit): TFruit +>fruitFactory5 : (Fruit: new (...args: "foo"[]) => TFruit) => TFruit +>Fruit : new (...args: "foo"[]) => TFruit +>args : "foo"[] + +const banana5 = fruitFactory5(Banana) // Banana<"foo"> +>banana5 : Banana<"foo"> +>fruitFactory5(Banana) : Banana<"foo"> +>fruitFactory5 : (Fruit: new (...args: "foo"[]) => TFruit) => TFruit +>Banana : typeof Banana + From 052a3d9d73a009e11f26fa8ba99f6e72c63b5e6d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 5 Sep 2019 16:16:35 -0700 Subject: [PATCH 025/100] Infer void from expr statement usage, not calls This makes inferences a lot better. --- src/services/codefixes/inferFromUsage.ts | 8 +++++--- .../cases/fourslash/codeFixInferFromCallInAssignment.ts | 9 +++++++++ .../fourslash/codeFixInferFromExpressionStatement.ts | 8 ++++++++ .../codeFixInferFromUsageCommentAfterParameter.ts | 2 +- tests/cases/fourslash/codeFixInferFromUsageJSXElement.ts | 2 +- .../fourslash/codeFixInferFromUsagePropertyAccess.ts | 2 +- .../fourslash/codeFixInferFromUsagePropertyAccessJS.ts | 2 +- 7 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 tests/cases/fourslash/codeFixInferFromCallInAssignment.ts create mode 100644 tests/cases/fourslash/codeFixInferFromExpressionStatement.ts diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 0a190e7b379..daa2166103a 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -504,6 +504,9 @@ namespace ts.codefix { } switch (node.parent.kind) { + case SyntaxKind.ExpressionStatement: + addCandidateType(usage, checker.getVoidType()); + break; case SyntaxKind.PostfixUnaryExpression: usage.isNumber = true; break; @@ -871,12 +874,11 @@ namespace ts.codefix { } if (usage.calls) { - callSignatures.push(getSignatureFromCalls(usage.calls, checker.getVoidType())); + callSignatures.push(getSignatureFromCalls(usage.calls, checker.getAnyType())); } if (usage.constructs) { - // TODO: fallback return should maybe be {}? - constructSignatures.push(getSignatureFromCalls(usage.constructs, checker.getVoidType())); + constructSignatures.push(getSignatureFromCalls(usage.constructs, checker.getAnyType())); } if (usage.stringIndex) { diff --git a/tests/cases/fourslash/codeFixInferFromCallInAssignment.ts b/tests/cases/fourslash/codeFixInferFromCallInAssignment.ts new file mode 100644 index 00000000000..85e1d3bc509 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromCallInAssignment.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +//// function inferAny( [| app |] ) { +//// const result = app.use('hi') +//// return result +//// } + +verify.rangeAfterCodeFix("app: { use: (arg0: string) => any; }"); diff --git a/tests/cases/fourslash/codeFixInferFromExpressionStatement.ts b/tests/cases/fourslash/codeFixInferFromExpressionStatement.ts new file mode 100644 index 00000000000..b5969c79378 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromExpressionStatement.ts @@ -0,0 +1,8 @@ +/// + +// @noImplicitAny: true +//// function inferVoid( [| app |] ) { +//// app.use('hi') +//// } + +verify.rangeAfterCodeFix("app: { use: (arg0: string) => void; }"); diff --git a/tests/cases/fourslash/codeFixInferFromUsageCommentAfterParameter.ts b/tests/cases/fourslash/codeFixInferFromUsageCommentAfterParameter.ts index bdefd2b5dea..866bfe04c13 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageCommentAfterParameter.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageCommentAfterParameter.ts @@ -16,7 +16,7 @@ verify.codeFix({ index: 0, newFileContent: `/** - * @param {(arg0: any) => void} callback + * @param {(arg0: any) => any} callback */ function coll(callback /*, name1, name2, ... */) { return callback(this); diff --git a/tests/cases/fourslash/codeFixInferFromUsageJSXElement.ts b/tests/cases/fourslash/codeFixInferFromUsageJSXElement.ts index 3200fffafb8..abe35fe46c8 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageJSXElement.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageJSXElement.ts @@ -30,4 +30,4 @@ //// } -verify.rangeAfterCodeFix("props: { isLoading: any; update: (arg0: any) => void; }",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); +verify.rangeAfterCodeFix("props: { isLoading: any; update: (arg0: any) => any; }",/*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, 0); diff --git a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts index c8b85ee11e8..44d2e2d7b1c 100644 --- a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts +++ b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccess.ts @@ -12,4 +12,4 @@ //// return x.y.z ////} -verify.rangeAfterCodeFix("a: { b: { c: any; }; }, m: { n: () => number; }, x: { y: { z: number[]; }; }", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); \ No newline at end of file +verify.rangeAfterCodeFix("a: { b: { c: void; }; }, m: { n: () => number; }, x: { y: { z: number[]; }; }", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); diff --git a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts index ed9d4b33b37..357b1a991ba 100644 --- a/tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts +++ b/tests/cases/fourslash/codeFixInferFromUsagePropertyAccessJS.ts @@ -21,7 +21,7 @@ verify.codeFix({ index: 0, newFileContent: `/** - * @param {{ b: { c: any; }; }} a + * @param {{ b: { c: void; }; }} a * @param {{ n: () => number; }} m * @param {{ y: { z: number[]; }; }} x */ From d32c6b2df1e1988c9565b4a7d08e422337540c2a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 5 Sep 2019 16:21:08 -0700 Subject: [PATCH 026/100] Fallback type is always any now void is explicitly inferred now, never used as a fallback. --- src/services/codefixes/inferFromUsage.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index daa2166103a..b453535b462 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -767,8 +767,8 @@ namespace ts.codefix { return inferences.filter(i => toRemove.every(f => !f(i))); } - function unifyTypes(inferences: ReadonlyArray, fallback = checker.getAnyType()): Type { - if (!inferences.length) return fallback; + function unifyTypes(inferences: ReadonlyArray): Type { + if (!inferences.length) return checker.getAnyType(); // 1. string or number individually override string | number // 2. non-any, non-void overrides any or void @@ -874,11 +874,11 @@ namespace ts.codefix { } if (usage.calls) { - callSignatures.push(getSignatureFromCalls(usage.calls, checker.getAnyType())); + callSignatures.push(getSignatureFromCalls(usage.calls)); } if (usage.constructs) { - constructSignatures.push(getSignatureFromCalls(usage.constructs, checker.getAnyType())); + constructSignatures.push(getSignatureFromCalls(usage.constructs)); } if (usage.stringIndex) { @@ -1047,10 +1047,10 @@ namespace ts.codefix { } function getFunctionFromCalls(calls: CallUsage[]) { - return checker.createAnonymousType(undefined!, createSymbolTable(), [getSignatureFromCalls(calls, checker.getAnyType())], emptyArray, undefined, undefined); + return checker.createAnonymousType(undefined!, createSymbolTable(), [getSignatureFromCalls(calls)], emptyArray, undefined, undefined); } - function getSignatureFromCalls(calls: CallUsage[], fallbackReturn: Type): Signature { + function getSignatureFromCalls(calls: CallUsage[]): Signature { const parameters: Symbol[] = []; const length = Math.max(...calls.map(c => c.argumentTypes.length)); for (let i = 0; i < length; i++) { @@ -1061,7 +1061,7 @@ namespace ts.codefix { } parameters.push(symbol); } - const returnType = unifyTypes(inferFromUsage(combineUsages(calls.map(call => call.return_))), fallbackReturn); + const returnType = unifyTypes(inferFromUsage(combineUsages(calls.map(call => call.return_)))); // TODO: GH#18217 return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } From f394190572fb76b194df5f093f1af51abc1ffb98 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 6 Sep 2019 11:18:50 -0700 Subject: [PATCH 027/100] Tonnes of cleanup --- src/services/codefixes/inferFromUsage.ts | 167 ++++++++++++----------- 1 file changed, 87 insertions(+), 80 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index b453535b462..2e9fb0dfc72 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -433,6 +433,53 @@ namespace ts.codefix { inferredTypes: Type[] | undefined; } + function createEmptyUsage(): Usage { + return { + isNumber: undefined, + isString: undefined, + isNumberOrString: undefined, + candidateTypes: undefined, + properties: undefined, + calls: undefined, + constructs: undefined, + numberIndex: undefined, + stringIndex: undefined, + candidateThisTypes: undefined, + inferredTypes: undefined, + }; + } + + function combineUsages(usages: Usage[]): Usage { + const combinedProperties = createUnderscoreEscapedMap(); + for (const u of usages) { + if (u.properties) { + u.properties.forEach((p, name) => { + if (!combinedProperties.has(name)) { + combinedProperties.set(name, []); + } + combinedProperties.get(name)!.push(p); + }); + } + } + const properties = createUnderscoreEscapedMap(); + combinedProperties.forEach((ps, name) => { + properties.set(name, combineUsages(ps)); + }); + return { + isNumber: usages.some(u => u.isNumber), + isString: usages.some(u => u.isString), + isNumberOrString: usages.some(u => u.isNumberOrString), + candidateTypes: flatMap(usages, u => u.candidateTypes) as Type[], + properties, + calls: flatMap(usages, u => u.calls) as CallUsage[], + constructs: flatMap(usages, u => u.constructs) as CallUsage[], + numberIndex: forEach(usages, u => u.numberIndex), + stringIndex: forEach(usages, u => u.stringIndex), + candidateThisTypes: flatMap(usages, u => u.candidateThisTypes) as Type[], + inferredTypes: undefined, // clear type cache + }; + } + function single(): Type { return unifyTypes(inferTypesFromReferencesSingle(references)); } @@ -767,6 +814,10 @@ namespace ts.codefix { return inferences.filter(i => toRemove.every(f => !f(i))); } + function unifyFromUsage(usage: Usage) { + return unifyTypes(inferFromUsage(usage)); + } + function unifyTypes(inferences: ReadonlyArray): Type { if (!inferences.length) return checker.getAnyType(); @@ -837,7 +888,7 @@ namespace ts.codefix { numberIndices.length ? checker.createIndexInfo(checker.getUnionType(numberIndices), numberIndexReadonly) : undefined); } - function inferFromUsage(usage: Usage) { + function inferFromUsage(usage: Usage): Type[] { const types = []; if (usage.isNumber) { @@ -851,12 +902,20 @@ namespace ts.codefix { } types.push(...(usage.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t))); - types.push(...findBuiltinTypes(usage)); + types.push(...inferNamedTypesFromProperties(usage)); if (usage.numberIndex) { - types.push(checker.createArrayType(recur(usage.numberIndex))); + types.push(checker.createArrayType(unifyFromUsage(usage.numberIndex))); } - else if (usage.properties && usage.properties.size + const structural = inferStructuralType(usage); + if (structural) { + types.push(structural); + } + return types; + } + + function inferStructuralType(usage: Usage) { + if (usage.properties && usage.properties.size || usage.calls && usage.calls.length || usage.constructs && usage.constructs.length || usage.stringIndex) { @@ -868,7 +927,7 @@ namespace ts.codefix { if (usage.properties) { usage.properties.forEach((u, name) => { const symbol = checker.createSymbol(SymbolFlags.Property, name); - symbol.type = recur(u); + symbol.type = unifyFromUsage(u); members.set(name, symbol); }); } @@ -882,75 +941,23 @@ namespace ts.codefix { } if (usage.stringIndex) { - stringIndexInfo = checker.createIndexInfo(recur(usage.stringIndex), /*isReadonly*/ false); + stringIndexInfo = checker.createIndexInfo(unifyFromUsage(usage.stringIndex), /*isReadonly*/ false); } - types.push(checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined)); // TODO: GH#18217 - } - return types; // TODO: Should cache this since I HOPE it doesn't change - - function recur(innerUsage: Usage): Type { - return unifyTypes(inferFromUsage(innerUsage)); + return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined); // TODO: GH#18217 } } - function createEmptyUsage(): Usage { - return { - isNumber: undefined, - isString: undefined, - isNumberOrString: undefined, - candidateTypes: undefined, - properties: undefined, - calls: undefined, - constructs: undefined, - numberIndex: undefined, - stringIndex: undefined, - candidateThisTypes: undefined, - inferredTypes: undefined, - } - } - - function combineUsages(usages: Usage[]): Usage { - const combinedProperties = createUnderscoreEscapedMap() - for (const u of usages) { - if (u.properties) { - u.properties.forEach((p,name) => { - if (!combinedProperties.has(name)) { - combinedProperties.set(name, []); - } - combinedProperties.get(name)!.push(p); - }); - } - } - const properties = createUnderscoreEscapedMap() - combinedProperties.forEach((ps,name) => { - properties.set(name, combineUsages(ps)); - }); - return { - isNumber: usages.some(u => u.isNumber), - isString: usages.some(u => u.isString), - isNumberOrString: usages.some(u => u.isNumberOrString), - candidateTypes: flatMap(usages, u => u.candidateTypes) as Type[], - properties, - calls: flatMap(usages, u => u.calls) as CallUsage[], - constructs: flatMap(usages, u => u.constructs) as CallUsage[], - numberIndex: forEach(usages, u => u.numberIndex), - stringIndex: forEach(usages, u => u.stringIndex), - candidateThisTypes: flatMap(usages, u => u.candidateThisTypes) as Type[], - inferredTypes: undefined, // clear type cache - } - } - - function findBuiltinTypes(usage: Usage): Type[] { + function inferNamedTypesFromProperties(usage: Usage): Type[] { if (!usage.properties || !usage.properties.size) return []; - const matches = builtins.filter(t => matchesAllPropertiesOf(t, usage)); + const matches = builtins.filter(t => allPropertiesAreAssignableToUsage(t, usage)); if (0 < matches.length && matches.length < 3) { - return matches.map(m => inferTypeParameterFromUsage(m, usage)); + return matches.map(m => inferInstantiationFromUsage(m, usage)); } return []; } - function matchesAllPropertiesOf(type: Type, usage: Usage) { + function allPropertiesAreAssignableToUsage(type: Type, usage: Usage) { if (!usage.properties) return false; let result = true; usage.properties.forEach((propUsage, name) => { @@ -960,34 +967,34 @@ namespace ts.codefix { return; } if (propUsage.calls) { - const sigs = checker.getSignaturesOfType(source, ts.SignatureKind.Call); + const sigs = checker.getSignaturesOfType(source, SignatureKind.Call); result = result && !!sigs.length && checker.isTypeAssignableTo(source, getFunctionFromCalls(propUsage.calls)); } else { - result = result && checker.isTypeAssignableTo(source, unifyTypes(inferFromUsage(propUsage))); + result = result && checker.isTypeAssignableTo(source, unifyFromUsage(propUsage)); } }); return result; } - // inference is limited to - // 1. generic types with a single parameter - // 2. inference to/from calls with a single signature - function inferTypeParameterFromUsage(type: Type, usage: Usage) { - if (!usage.properties || !(getObjectFlags(type) & ObjectFlags.Reference)) return type; + /** + * inference is limited to + * 1. generic types with a single parameter + * 2. inference to/from calls with a single signature + */ + function inferInstantiationFromUsage(type: Type, usage: Usage) { + if (!(getObjectFlags(type) & ObjectFlags.Reference) || !usage.properties) { + return type; + } const generic = (type as TypeReference).target; const singleTypeParameter = singleOrUndefined(generic.typeParameters); if (!singleTypeParameter) return type; const types: Type[] = []; usage.properties.forEach((propUsage, name) => { - const source = checker.getTypeOfPropertyOfType(generic, name as string); - if (!source) { - return Debug.fail("generic should have all the properties of its reference."); - } - if (!propUsage.calls) return; - - types.push(...infer(source, getFunctionFromCalls(propUsage.calls), singleTypeParameter)); + const genericPropertyType = checker.getTypeOfPropertyOfType(generic, name as string); + Debug.assert(!!genericPropertyType, "generic should have all the properties of its reference."); + types.push(...infer(genericPropertyType!, unifyFromUsage(propUsage), singleTypeParameter)); }); return builtinConstructors[type.symbol.escapedName as string](unifyTypes(types)); } @@ -1033,7 +1040,7 @@ namespace ts.codefix { break; } let sourceType = checker.getTypeOfSymbolAtLocation(sourceParam, sourceParam.valueDeclaration); - let elementType = isRest && checker.getElementTypeOfArrayType(sourceType); + const elementType = isRest && checker.getElementTypeOfArrayType(sourceType); if (elementType) { sourceType = elementType; } @@ -1047,7 +1054,7 @@ namespace ts.codefix { } function getFunctionFromCalls(calls: CallUsage[]) { - return checker.createAnonymousType(undefined!, createSymbolTable(), [getSignatureFromCalls(calls)], emptyArray, undefined, undefined); + return checker.createAnonymousType(undefined!, createSymbolTable(), [getSignatureFromCalls(calls)], emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); } function getSignatureFromCalls(calls: CallUsage[]): Signature { @@ -1061,7 +1068,7 @@ namespace ts.codefix { } parameters.push(symbol); } - const returnType = unifyTypes(inferFromUsage(combineUsages(calls.map(call => call.return_)))); + const returnType = unifyFromUsage(combineUsages(calls.map(call => call.return_))); // TODO: GH#18217 return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } From 1703ae0f46407beb4701e7234c9de558b20e17c0 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 6 Sep 2019 11:27:34 -0700 Subject: [PATCH 028/100] Renames and more cleanup --- src/services/codefixes/inferFromUsage.ts | 63 +++++++++++------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 2e9fb0dfc72..0c711cfa4c4 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -743,7 +743,6 @@ namespace ts.codefix { if (parent.arguments) { for (const argument of parent.arguments) { - // TODO: should recursively infer a usage here, right? call.argumentTypes.push(checker.getTypeAtLocation(argument)); } } @@ -999,57 +998,55 @@ namespace ts.codefix { return builtinConstructors[type.symbol.escapedName as string](unifyTypes(types)); } - // TODO: Source and target are bad names. Should be builtinType and usageType...or something - // and search is a bad name - function infer(source: Type, target: Type, search: Type): readonly Type[] { - if (source === search) { - return [target]; + function infer(genericType: Type, usageType: Type, typeParameter: Type): readonly Type[] { + if (genericType === typeParameter) { + return [usageType]; } - else if (source.flags & TypeFlags.UnionOrIntersection) { - return flatMap((source as UnionOrIntersectionType).types, t => infer(t, target, search)); + else if (genericType.flags & TypeFlags.UnionOrIntersection) { + return flatMap((genericType as UnionOrIntersectionType).types, t => infer(t, usageType, typeParameter)); } - else if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference) { + else if (getObjectFlags(genericType) & ObjectFlags.Reference && getObjectFlags(usageType) & ObjectFlags.Reference) { // this is wrong because we need a reference to the targetType to, so we can check that it's also a reference - const sourceArgs = (source as TypeReference).typeArguments; - const targetArgs = (target as TypeReference).typeArguments; + const genericArgs = (genericType as TypeReference).typeArguments; + const usageArgs = (usageType as TypeReference).typeArguments; const types = []; - if (sourceArgs && targetArgs) { - for (let i = 0; i < sourceArgs.length; i++) { - if (targetArgs[i]) { - types.push(...infer(sourceArgs[i], targetArgs[i], search)); + if (genericArgs && usageArgs) { + for (let i = 0; i < genericArgs.length; i++) { + if (usageArgs[i]) { + types.push(...infer(genericArgs[i], usageArgs[i], typeParameter)); } } } return types; } - const sourceSigs = checker.getSignaturesOfType(source, SignatureKind.Call); - const targetSigs = checker.getSignaturesOfType(target, SignatureKind.Call); - if (sourceSigs.length === 1 && targetSigs.length === 1) { - return inferFromSignatures(sourceSigs[0], targetSigs[0], search); + const genericSigs = checker.getSignaturesOfType(genericType, SignatureKind.Call); + const usageSigs = checker.getSignaturesOfType(usageType, SignatureKind.Call); + if (genericSigs.length === 1 && usageSigs.length === 1) { + return inferFromSignatures(genericSigs[0], usageSigs[0], typeParameter); } return []; } - function inferFromSignatures(sourceSig: Signature, targetSig: Signature, search: Type) { + function inferFromSignatures(genericSig: Signature, usageSig: Signature, typeParameter: Type) { const types = []; - for (let i = 0; i < sourceSig.parameters.length; i++) { - const sourceParam = sourceSig.parameters[i]; - const targetParam = targetSig.parameters[i]; - const isRest = sourceSig.declaration && isRestParameter(sourceSig.declaration.parameters[i]); - if (!targetParam) { + for (let i = 0; i < genericSig.parameters.length; i++) { + const genericParam = genericSig.parameters[i]; + const usageParam = usageSig.parameters[i]; + const isRest = genericSig.declaration && isRestParameter(genericSig.declaration.parameters[i]); + if (!usageParam) { break; } - let sourceType = checker.getTypeOfSymbolAtLocation(sourceParam, sourceParam.valueDeclaration); - const elementType = isRest && checker.getElementTypeOfArrayType(sourceType); + let genericParamType = checker.getTypeOfSymbolAtLocation(genericParam, genericParam.valueDeclaration); + const elementType = isRest && checker.getElementTypeOfArrayType(genericParamType); if (elementType) { - sourceType = elementType; + genericParamType = elementType; } - const targetType = (targetParam as SymbolLinks).type || checker.getTypeOfSymbolAtLocation(targetParam, targetParam.valueDeclaration); - types.push(...infer(sourceType, targetType, search)); + const targetType = (usageParam as SymbolLinks).type || checker.getTypeOfSymbolAtLocation(usageParam, usageParam.valueDeclaration); + types.push(...infer(genericParamType, targetType, typeParameter)); } - const sourceReturn = checker.getReturnTypeOfSignature(sourceSig); - const targetReturn = checker.getReturnTypeOfSignature(targetSig); - types.push(...infer(sourceReturn, targetReturn, search)); + const genericReturn = checker.getReturnTypeOfSignature(genericSig); + const usageReturn = checker.getReturnTypeOfSignature(usageSig); + types.push(...infer(genericReturn, usageReturn, typeParameter)); return types; } From 330e51f09811a41bddd71bfe2eea3baa4e6651bc Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 6 Sep 2019 15:15:19 -0700 Subject: [PATCH 029/100] Add test + reshuffle/rename new code --- src/services/codefixes/inferFromUsage.ts | 63 +++++++------------ .../codeFixInferFromUsageAddition.ts | 9 +++ .../fourslash/codeFixInferFromUsageArray.ts | 14 +++++ .../codeFixInferFromUsageLiteralTypes.ts | 10 +++ .../fourslash/codeFixInferFromUsagePromise.ts | 9 +++ .../fourslash/codeFixInferFromUsageString.ts | 12 ++++ 6 files changed, 77 insertions(+), 40 deletions(-) create mode 100644 tests/cases/fourslash/codeFixInferFromUsageAddition.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageArray.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageLiteralTypes.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsagePromise.ts create mode 100644 tests/cases/fourslash/codeFixInferFromUsageString.ts diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 0c711cfa4c4..520f8520d21 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -899,59 +899,42 @@ namespace ts.codefix { if (usage.isNumberOrString) { types.push(checker.getUnionType([checker.getStringType(), checker.getNumberType()])); } + if (usage.numberIndex) { + types.push(checker.createArrayType(unifyFromUsage(usage.numberIndex))); + } + if (usage.properties && usage.properties.size + || usage.calls && usage.calls.length + || usage.constructs && usage.constructs.length + || usage.stringIndex) { + types.push(inferStructuralType(usage)); + } types.push(...(usage.candidateTypes || []).map(t => checker.getBaseTypeOfLiteralType(t))); types.push(...inferNamedTypesFromProperties(usage)); - if (usage.numberIndex) { - types.push(checker.createArrayType(unifyFromUsage(usage.numberIndex))); - } - const structural = inferStructuralType(usage); - if (structural) { - types.push(structural); - } return types; } function inferStructuralType(usage: Usage) { - if (usage.properties && usage.properties.size - || usage.calls && usage.calls.length - || usage.constructs && usage.constructs.length - || usage.stringIndex) { - const members = createUnderscoreEscapedMap(); - const callSignatures: Signature[] = []; - const constructSignatures: Signature[] = []; - let stringIndexInfo: IndexInfo | undefined; - - if (usage.properties) { - usage.properties.forEach((u, name) => { - const symbol = checker.createSymbol(SymbolFlags.Property, name); - symbol.type = unifyFromUsage(u); - members.set(name, symbol); - }); - } - - if (usage.calls) { - callSignatures.push(getSignatureFromCalls(usage.calls)); - } - - if (usage.constructs) { - constructSignatures.push(getSignatureFromCalls(usage.constructs)); - } - - if (usage.stringIndex) { - stringIndexInfo = checker.createIndexInfo(unifyFromUsage(usage.stringIndex), /*isReadonly*/ false); - } - - return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined); // TODO: GH#18217 + const members = createUnderscoreEscapedMap(); + if (usage.properties) { + usage.properties.forEach((u, name) => { + const symbol = checker.createSymbol(SymbolFlags.Property, name); + symbol.type = unifyFromUsage(u); + members.set(name, symbol); + }); } + const callSignatures: Signature[] = usage.calls ? [getSignatureFromCalls(usage.calls)] : []; + const constructSignatures: Signature[] = usage.constructs ? [getSignatureFromCalls(usage.constructs)] : []; + const stringIndexInfo = usage.stringIndex && checker.createIndexInfo(unifyFromUsage(usage.stringIndex), /*isReadonly*/ false); + return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined); // TODO: GH#18217 } function inferNamedTypesFromProperties(usage: Usage): Type[] { if (!usage.properties || !usage.properties.size) return []; - const matches = builtins.filter(t => allPropertiesAreAssignableToUsage(t, usage)); - if (0 < matches.length && matches.length < 3) { - return matches.map(m => inferInstantiationFromUsage(m, usage)); + const types = builtins.filter(t => allPropertiesAreAssignableToUsage(t, usage)); + if (0 < types.length && types.length < 3) { + return types.map(t => inferInstantiationFromUsage(t, usage)); } return []; } diff --git a/tests/cases/fourslash/codeFixInferFromUsageAddition.ts b/tests/cases/fourslash/codeFixInferFromUsageAddition.ts new file mode 100644 index 00000000000..4b57d0603f1 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageAddition.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +//// function foo([|a, m |]) { +//// return a + m +//// } + +verify.rangeAfterCodeFix("a: any, m: any", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); + diff --git a/tests/cases/fourslash/codeFixInferFromUsageArray.ts b/tests/cases/fourslash/codeFixInferFromUsageArray.ts new file mode 100644 index 00000000000..03d6b09e99b --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageArray.ts @@ -0,0 +1,14 @@ +/// + +// @noImplicitAny: true +//// function foo([|p, a, b, c, d, e |]) { +//// var x: string = a.pop() +//// b.reverse() +//// var rr: boolean[] = c.reverse() +//// d.some(t => t > 1); // can't infer from callbacks right now +//// var y = e.concat(12); // can't infer from overloaded functions right now +//// return p.push(12) +//// } + +verify.rangeAfterCodeFix("p: number[], a: string[], b: any[], c: boolean[], d: any[], e: number[]", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); + diff --git a/tests/cases/fourslash/codeFixInferFromUsageLiteralTypes.ts b/tests/cases/fourslash/codeFixInferFromUsageLiteralTypes.ts new file mode 100644 index 00000000000..3b8c9441159 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageLiteralTypes.ts @@ -0,0 +1,10 @@ +/// + +// @noImplicitAny: true +//// function foo([|a, m |]) { +//// a = 'hi' +//// m = 1 +//// } + +verify.rangeAfterCodeFix("a: string, m: number", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); + diff --git a/tests/cases/fourslash/codeFixInferFromUsagePromise.ts b/tests/cases/fourslash/codeFixInferFromUsagePromise.ts new file mode 100644 index 00000000000..d06bb3b6a0f --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsagePromise.ts @@ -0,0 +1,9 @@ +/// + +// @noImplicitAny: true +//// function foo([|p |]) { +//// return p.then((x: string[]) => x[0]) +//// } + +verify.rangeAfterCodeFix("p: Promise", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); + diff --git a/tests/cases/fourslash/codeFixInferFromUsageString.ts b/tests/cases/fourslash/codeFixInferFromUsageString.ts new file mode 100644 index 00000000000..dc5787dc75b --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageString.ts @@ -0,0 +1,12 @@ +/// + +// @noImplicitAny: true +//// function foo([|p, a, b, c, d |]) { +//// var x +//// p.charAt(x) +//// a.charAt(0) +//// b.concat('hi') +//// } + +verify.rangeAfterCodeFix("p: string, a: string, b: string | string[]", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); + From 21528748c6dd7d46a9a2c428a302495debba119e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Sep 2019 16:24:00 -0700 Subject: [PATCH 030/100] Address CR feedback --- src/compiler/binder.ts | 3 ++- src/compiler/checker.ts | 24 +++++++++++++----------- src/compiler/types.ts | 13 +++++++++---- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b73431f6f56..df312b991c6 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1281,7 +1281,8 @@ namespace ts { function isDottedName(node: Expression): boolean { return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || - node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((node).expression); + node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((node).expression) || + node.kind === SyntaxKind.ParenthesizedExpression && isDottedName((node).expression); } function bindExpressionStatement(node: ExpressionStatement): void { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0af56d7f172..bb59a6143fd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16852,7 +16852,7 @@ namespace ts { return !!(declaration && ( declaration.kind === SyntaxKind.VariableDeclaration || declaration.kind === SyntaxKind.Parameter || declaration.kind === SyntaxKind.PropertyDeclaration || declaration.kind === SyntaxKind.PropertySignature) && - (declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature).type); + getEffectiveTypeAnnotationNode(declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature)); } function getExplicitTypeOfSymbol(symbol: Symbol) { @@ -16861,11 +16861,11 @@ namespace ts { getTypeOfSymbol(symbol) : undefined; } - function getTypeOfDottedName(node: Expression) { - // We require the dotted function name in an assertion expression to be comprised of identifiers - // that reference function, method, class or value module symbols; or variable, property or - // parameter symbols with declarations that have explicit type annotations. Such references are - // resolvable with no possibility of triggering circularities in control flow analysis. + // We require the dotted function name in an assertion expression to be comprised of identifiers + // that reference function, method, class or value module symbols; or variable, property or + // parameter symbols with declarations that have explicit type annotations. Such references are + // resolvable with no possibility of triggering circularities in control flow analysis. + function getTypeOfDottedName(node: Expression): Type | undefined { switch (node.kind) { case SyntaxKind.Identifier: const symbol = getResolvedSymbol(node); @@ -16874,10 +16874,10 @@ namespace ts { return checkThisExpression(node); case SyntaxKind.PropertyAccessExpression: const type = getTypeOfDottedName((node).expression); - if (type) { - const prop = getPropertyOfType(type, (node).name.escapedText); - return prop && getExplicitTypeOfSymbol(prop); - } + const prop = type && getPropertyOfType(type, (node).name.escapedText); + return prop && getExplicitTypeOfSymbol(prop); + case SyntaxKind.ParenthesizedExpression: + return getTypeOfDottedName((node).expression); } } @@ -16886,7 +16886,9 @@ namespace ts { let signature = links.effectsSignature; if (signature === undefined) { // A call expression parented by an expression statement is a potential assertion. Other call - // expressions are potential type predicate function calls. + // expressions are potential type predicate function calls. In order to avoid triggering + // circularities in control flow analysis, we use getTypeOfDottedName when resolving the call + // target expression of an assertion. const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression) : node.expression.kind !== SyntaxKind.SuperKeyword ? checkNonNullExpression(node.expression) : undefined; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b27de58134a..b4e4769ab47 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3518,28 +3518,33 @@ namespace ts { AssertsIdentifier } - export interface ThisTypePredicate { + export interface TypePredicateBase { + kind: TypePredicateKind; + type: Type | undefined; + } + + export interface ThisTypePredicate extends TypePredicateBase { kind: TypePredicateKind.This; parameterName: undefined; parameterIndex: undefined; type: Type; } - export interface IdentifierTypePredicate { + export interface IdentifierTypePredicate extends TypePredicateBase { kind: TypePredicateKind.Identifier; parameterName: string; parameterIndex: number; type: Type; } - export interface AssertsThisTypePredicate { + export interface AssertsThisTypePredicate extends TypePredicateBase { kind: TypePredicateKind.AssertsThis; parameterName: undefined; parameterIndex: undefined; type: Type | undefined; } - export interface AssertsIdentifierTypePredicate { + export interface AssertsIdentifierTypePredicate extends TypePredicateBase { kind: TypePredicateKind.AssertsIdentifier; parameterName: string; parameterIndex: number; From 8791b62c9614b83f23928aa0208fbfe07f508904 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Sep 2019 22:26:36 -0700 Subject: [PATCH 031/100] Accept new baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 12 ++++++++---- tests/baselines/reference/api/typescript.d.ts | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index c458e88300b..35f3d7a7a54 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2097,25 +2097,29 @@ declare namespace ts { AssertsThis = 2, AssertsIdentifier = 3 } - export interface ThisTypePredicate { + export interface TypePredicateBase { + kind: TypePredicateKind; + type: Type | undefined; + } + export interface ThisTypePredicate extends TypePredicateBase { kind: TypePredicateKind.This; parameterName: undefined; parameterIndex: undefined; type: Type; } - export interface IdentifierTypePredicate { + export interface IdentifierTypePredicate extends TypePredicateBase { kind: TypePredicateKind.Identifier; parameterName: string; parameterIndex: number; type: Type; } - export interface AssertsThisTypePredicate { + export interface AssertsThisTypePredicate extends TypePredicateBase { kind: TypePredicateKind.AssertsThis; parameterName: undefined; parameterIndex: undefined; type: Type | undefined; } - export interface AssertsIdentifierTypePredicate { + export interface AssertsIdentifierTypePredicate extends TypePredicateBase { kind: TypePredicateKind.AssertsIdentifier; parameterName: string; parameterIndex: number; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index d8df06e936f..ba196621c14 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2097,25 +2097,29 @@ declare namespace ts { AssertsThis = 2, AssertsIdentifier = 3 } - export interface ThisTypePredicate { + export interface TypePredicateBase { + kind: TypePredicateKind; + type: Type | undefined; + } + export interface ThisTypePredicate extends TypePredicateBase { kind: TypePredicateKind.This; parameterName: undefined; parameterIndex: undefined; type: Type; } - export interface IdentifierTypePredicate { + export interface IdentifierTypePredicate extends TypePredicateBase { kind: TypePredicateKind.Identifier; parameterName: string; parameterIndex: number; type: Type; } - export interface AssertsThisTypePredicate { + export interface AssertsThisTypePredicate extends TypePredicateBase { kind: TypePredicateKind.AssertsThis; parameterName: undefined; parameterIndex: undefined; type: Type | undefined; } - export interface AssertsIdentifierTypePredicate { + export interface AssertsIdentifierTypePredicate extends TypePredicateBase { kind: TypePredicateKind.AssertsIdentifier; parameterName: string; parameterIndex: number; From 07b9715fde05b3d405423a7303ea3d180706cbde Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 4 Sep 2019 13:42:11 -0700 Subject: [PATCH 032/100] Allow .d.ts with --isolatedModules Fixes #29490 --- src/compiler/program.ts | 4 ---- .../reference/isolatedModulesDeclaration.errors.txt | 6 ------ 2 files changed, 10 deletions(-) delete mode 100644 tests/baselines/reference/isolatedModulesDeclaration.errors.txt diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 275acb64641..6a8a36dd590 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2808,10 +2808,6 @@ namespace ts { } if (options.isolatedModules) { - if (getEmitDeclarations(options)) { - createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, getEmitDeclarationOptionName(options), "isolatedModules"); - } - if (options.out) { createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"); } diff --git a/tests/baselines/reference/isolatedModulesDeclaration.errors.txt b/tests/baselines/reference/isolatedModulesDeclaration.errors.txt deleted file mode 100644 index 09a655c6da0..00000000000 --- a/tests/baselines/reference/isolatedModulesDeclaration.errors.txt +++ /dev/null @@ -1,6 +0,0 @@ -error TS5053: Option 'declaration' cannot be specified with option 'isolatedModules'. - - -!!! error TS5053: Option 'declaration' cannot be specified with option 'isolatedModules'. -==== tests/cases/compiler/file1.ts (0 errors) ==== - export var x; \ No newline at end of file From 2692b2e214fa531436a5701e5227c539e987e214 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 4 Sep 2019 15:40:38 -0700 Subject: [PATCH 033/100] Add failing test cases for isolatedModules after enabling declaration emit --- src/testRunner/unittests/tsbuild/helpers.ts | 10 +- .../inferredTypeFromTransitiveModule.ts | 52 ++++++- .../unittests/tscWatch/emitAndErrorUpdates.ts | 144 ++++++++++++++---- ...-transitive-module-with-isolatedModules.js | 82 ++++++++++ ...-transitive-module-with-isolatedModules.js | 135 ++++++++++++++++ 5 files changed, 390 insertions(+), 33 deletions(-) create mode 100644 tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js create mode 100644 tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index e33edf289d3..126b8d2f7d5 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -230,7 +230,7 @@ interface Symbol { } } - interface BuildInput { + export interface BuildInput { fs: vfs.FileSystem; tick: () => void; rootNames: readonly string[]; @@ -239,7 +239,7 @@ interface Symbol { baselineBuildInfo?: true; } - function build({ fs, tick, rootNames, modifyFs, baselineSourceMap, baselineBuildInfo }: BuildInput) { + export function tscBuild({ fs, tick, rootNames, modifyFs, baselineSourceMap, baselineBuildInfo }: BuildInput) { const actualReadFileMap = createMap(); modifyFs(fs); tick(); @@ -344,7 +344,7 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt let host: fakes.SolutionBuilderHost; let initialWrittenFiles: Map; before(() => { - const result = build({ + const result = tscBuild({ fs: projFs().shadow(), tick, rootNames, @@ -390,7 +390,7 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt tick(); newFs = fs.shadow(); tick(); - ({ actualReadFileMap, host } = build({ + ({ actualReadFileMap, host } = tscBuild({ fs: newFs, tick, rootNames, @@ -429,7 +429,7 @@ Mismatch Actual(path, actual, expected): ${JSON.stringify(arrayFrom(mapDefinedIt }); } it(`Verify emit output file text is same when built clean`, () => { - const { fs, writtenFiles } = build({ + const { fs, writtenFiles } = tscBuild({ fs: newFs.shadow(), tick, rootNames, diff --git a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts index 92762dfd49d..5383b7d32be 100644 --- a/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts +++ b/src/testRunner/unittests/tsbuild/inferredTypeFromTransitiveModule.ts @@ -25,7 +25,7 @@ namespace ts { ] }, incrementalDtsChangedBuild: { - modifyFs: fs => replaceText(fs, "/src/bar.ts", "param: string", ""), + modifyFs: changeBarParam, expectedDiagnostics: [ getExpectedDiagnosticForProjectsInBuild("src/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tsconfig.json", "src/obj/bar.js", "src/bar.ts"], @@ -36,5 +36,55 @@ namespace ts { baselineOnly: true, verifyDiagnostics: true }); + + verifyTsbuildOutput({ + scenario: "inferred type from transitive module with isolatedModules", + projFs: () => projFs, + time, + tick, + proj: "inferredTypeFromTransitiveModule", + rootNames: ["/src"], + initialBuild: { modifyFs: changeToIsolatedModules }, + incrementalDtsChangedBuild: { modifyFs: changeBarParam }, + baselineOnly: true, + }); + + it("reports errors in files affected by change in signature", () => { + const { fs, host } = tscBuild({ + fs: projFs.shadow(), + tick, + rootNames: ["/src"], + modifyFs: fs => { + changeToIsolatedModules(fs); + appendText(fs, "/src/lazyIndex.ts", ` +import { default as bar } from './bar'; +bar("hello");`); + } + }); + host.assertErrors(/*empty*/); + + tick(); + const { fs: newFs, host: newHost, writtenFiles } = tscBuild({ + fs: fs.shadow(), + tick, + rootNames: ["/src"], + modifyFs: changeBarParam + }); + // Has errors + newHost.assertErrors({ + message: [Diagnostics.Expected_0_arguments_but_got_1, 0, 1], + location: expectedLocationIndexOf(newFs, "/src/lazyIndex.ts", `"hello"`) + }); + // No written files + assert.equal(writtenFiles.size, 0); + }); }); + + function changeToIsolatedModules(fs: vfs.FileSystem) { + replaceText(fs, "/src/tsconfig.json", `"incremental": true`, `"incremental": true, "isolatedModules": true`); + } + + function changeBarParam(fs: vfs.FileSystem) { + replaceText(fs, "/src/bar.ts", "param: string", ""); + } } diff --git a/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts b/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts index f41b07b157d..908c609e703 100644 --- a/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts +++ b/src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts @@ -12,7 +12,8 @@ namespace ts.tscWatch { file, fileStamp: host.getModifiedTime(file.path.replace(".ts", ".js")), errors: builderProgram.getSemanticDiagnostics(watch().getSourceFileByPath(file.path as Path)), - errorsFromOldState: !!state.semanticDiagnosticsFromOldState && state.semanticDiagnosticsFromOldState.has(file.path) + errorsFromOldState: !!state.semanticDiagnosticsFromOldState && state.semanticDiagnosticsFromOldState.has(file.path), + dtsStamp: host.getModifiedTime(file.path.replace(".ts", ".d.ts")) }; } @@ -24,21 +25,36 @@ namespace ts.tscWatch { return find(stampsAndErrors, info => info.file === file)!; } - function verifyOutputFileStampsAndErrors( - file: File, - emitExpected: boolean, - errorRefershExpected: boolean, - beforeChangeFileStampsAndErrors: readonly ReturnType[], - afterChangeFileStampsAndErrors: readonly ReturnType[] - ) { + interface VerifyOutputFileStampAndErrors { + file: File; + jsEmitExpected: boolean; + dtsEmitExpected: boolean; + errorRefershExpected: boolean; + beforeChangeFileStampsAndErrors: readonly ReturnType[]; + afterChangeFileStampsAndErrors: readonly ReturnType[]; + } + function verifyOutputFileStampsAndErrors({ + file, + jsEmitExpected, + dtsEmitExpected, + errorRefershExpected, + beforeChangeFileStampsAndErrors, + afterChangeFileStampsAndErrors + }: VerifyOutputFileStampAndErrors) { const beforeChange = findStampAndErrors(beforeChangeFileStampsAndErrors, file); const afterChange = findStampAndErrors(afterChangeFileStampsAndErrors, file); - if (emitExpected) { + if (jsEmitExpected) { assert.notStrictEqual(afterChange.fileStamp, beforeChange.fileStamp, `Expected emit for file ${file.path}`); } else { assert.strictEqual(afterChange.fileStamp, beforeChange.fileStamp, `Did not expect new emit for file ${file.path}`); } + if (dtsEmitExpected) { + assert.notStrictEqual(afterChange.dtsStamp, beforeChange.dtsStamp, `Expected emit for file ${file.path}`); + } + else { + assert.strictEqual(afterChange.dtsStamp, beforeChange.dtsStamp, `Did not expect new emit for file ${file.path}`); + } if (errorRefershExpected) { if (afterChange.errors !== emptyArray || beforeChange.errors !== emptyArray) { assert.notStrictEqual(afterChange.errors, beforeChange.errors, `Expected new errors for file ${file.path}`); @@ -51,19 +67,22 @@ namespace ts.tscWatch { } } - interface VerifyEmitAndErrorUpdates { - change: (host: WatchedSystem) => void; - getInitialErrors: (watch: Watch) => readonly Diagnostic[] | readonly string[]; - getIncrementalErrors: (watch: Watch) => readonly Diagnostic[] | readonly string[]; - filesWithNewEmit: readonly File[]; - filesWithOnlyErrorRefresh: readonly File[]; - filesNotTouched: readonly File[]; - configFile?: File; + interface VerifyEmitAndErrorUpdatesWorker extends VerifyEmitAndErrorUpdates { + configFile: File; } - - function verifyEmitAndErrorUpdates({ filesWithNewEmit, filesWithOnlyErrorRefresh, filesNotTouched, configFile = config, change, getInitialErrors, getIncrementalErrors }: VerifyEmitAndErrorUpdates) { + function verifyEmitAndErrorUpdatesWorker({ + fileWithChange, + filesWithNewEmit, + filesWithOnlyErrorRefresh, + filesNotTouched, + configFile, + change, + getInitialErrors, + getIncrementalErrors + }: VerifyEmitAndErrorUpdatesWorker) { const nonLibFiles = [...filesWithNewEmit, ...filesWithOnlyErrorRefresh, ...filesNotTouched]; const files = [...nonLibFiles, configFile, libFile]; + const compilerOptions = (JSON.parse(configFile.content).compilerOptions || {}) as CompilerOptions; const host = createWatchedSystem(files, { currentDirectory }); const watch = createWatchOfConfigFile("tsconfig.json", host); checkProgramActualFiles(watch(), [...nonLibFiles.map(f => f.path), libFile.path]); @@ -73,9 +92,77 @@ namespace ts.tscWatch { host.runQueuedTimeoutCallbacks(); checkOutputErrorsIncremental(host, getIncrementalErrors(watch)); const afterChange = getOutputFileStampsAndErrors(host, watch, nonLibFiles); - filesWithNewEmit.forEach(file => verifyOutputFileStampsAndErrors(file, /*emitExpected*/ true, /*errorRefershExpected*/ true, beforeChange, afterChange)); - filesWithOnlyErrorRefresh.forEach(file => verifyOutputFileStampsAndErrors(file, /*emitExpected*/ false, /*errorRefershExpected*/ true, beforeChange, afterChange)); - filesNotTouched.forEach(file => verifyOutputFileStampsAndErrors(file, /*emitExpected*/ false, /*errorRefershExpected*/ false, beforeChange, afterChange)); + filesWithNewEmit.forEach(file => verifyOutputFileStampsAndErrors({ + file, + jsEmitExpected: !compilerOptions.isolatedModules || fileWithChange === file, + dtsEmitExpected: getEmitDeclarations(compilerOptions), + errorRefershExpected: true, + beforeChangeFileStampsAndErrors: beforeChange, + afterChangeFileStampsAndErrors: afterChange + })); + filesWithOnlyErrorRefresh.forEach(file => verifyOutputFileStampsAndErrors({ + file, + jsEmitExpected: false, + dtsEmitExpected: getEmitDeclarations(compilerOptions) && !file.path.endsWith(".d.ts"), + errorRefershExpected: true, + beforeChangeFileStampsAndErrors: beforeChange, + afterChangeFileStampsAndErrors: afterChange + })); + filesNotTouched.forEach(file => verifyOutputFileStampsAndErrors({ + file, + jsEmitExpected: false, + dtsEmitExpected: false, + errorRefershExpected: false, + beforeChangeFileStampsAndErrors: beforeChange, + afterChangeFileStampsAndErrors: afterChange + })); + } + + function changeCompilerOptions(input: VerifyEmitAndErrorUpdates, additionalOptions: CompilerOptions): File { + const configFile = input.configFile || config; + const content = JSON.parse(configFile.content); + content.compilerOptions = { ...content.compilerOptions, ...additionalOptions }; + return { path: configFile.path, content: JSON.stringify(content) }; + } + + interface VerifyEmitAndErrorUpdates { + change: (host: WatchedSystem) => void; + getInitialErrors: (watch: Watch) => readonly Diagnostic[] | readonly string[]; + getIncrementalErrors: (watch: Watch) => readonly Diagnostic[] | readonly string[]; + fileWithChange: File; + filesWithNewEmit: readonly File[]; + filesWithOnlyErrorRefresh: readonly File[]; + filesNotTouched: readonly File[]; + configFile?: File; + } + function verifyEmitAndErrorUpdates(input: VerifyEmitAndErrorUpdates) { + it("with default config", () => { + verifyEmitAndErrorUpdatesWorker({ + ...input, + configFile: input.configFile || config + }); + }); + + it("with default config and --declaration", () => { + verifyEmitAndErrorUpdatesWorker({ + ...input, + configFile: changeCompilerOptions(input, { declaration: true }) + }); + }); + + it("config with --isolatedModules", () => { + verifyEmitAndErrorUpdatesWorker({ + ...input, + configFile: changeCompilerOptions(input, { isolatedModules: true }) + }); + }); + + it("config with --isolatedModules and --declaration", () => { + verifyEmitAndErrorUpdatesWorker({ + ...input, + configFile: changeCompilerOptions(input, { isolatedModules: true, declaration: true }) + }); + }); } describe("deep import changes", () => { @@ -93,6 +180,7 @@ console.log(b.c.d);` addImportedModule(bFile); addImportedModule(cFile); verifyEmitAndErrorUpdates({ + fileWithChange: cFile, filesWithNewEmit, filesWithOnlyErrorRefresh, filesNotTouched: emptyArray, @@ -113,7 +201,7 @@ console.log(b.c.d);` } } - it("updates errors when deep import file changes", () => { + describe("updates errors when deep import file changes", () => { const bFile: File = { path: `${currentDirectory}/b.ts`, content: `import {C} from './c'; @@ -132,7 +220,7 @@ export class B verifyDeepImportChange(bFile, cFile); }); - it("updates errors when deep import through declaration file changes", () => { + describe("updates errors when deep import through declaration file changes", () => { const bFile: File = { path: `${currentDirectory}/b.d.ts`, content: `import {C} from './c'; @@ -152,7 +240,7 @@ export class B }); }); - it("updates errors in file not exporting a deep multilevel import that changes", () => { + describe("updates errors in file not exporting a deep multilevel import that changes", () => { const aFile: File = { path: `${currentDirectory}/a.ts`, content: `export interface Point { @@ -193,6 +281,7 @@ getPoint().c.x;` content: `import "./d";` }; verifyEmitAndErrorUpdates({ + fileWithChange: aFile, filesWithNewEmit: [aFile, bFile], filesWithOnlyErrorRefresh: [cFile, dFile], filesNotTouched: [eFile], @@ -265,6 +354,7 @@ export class Data { filesWithOnlyErrorRefresh.push(lib2Data2); } verifyEmitAndErrorUpdates({ + fileWithChange: lib1ToolsInterface, filesWithNewEmit, filesWithOnlyErrorRefresh, filesNotTouched: emptyArray, @@ -276,11 +366,11 @@ export class Data { ] }); } - it("when there are no circular import and exports", () => { + describe("when there are no circular import and exports", () => { verifyTransitiveExports(lib2Data); }); - it("when there are circular import and exports", () => { + describe("when there are circular import and exports", () => { const lib2Data: File = { path: `${currentDirectory}/lib2/data.ts`, content: `import { ITest } from "lib1/public"; import { Data2 } from "./data2"; diff --git a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js new file mode 100644 index 00000000000..bf9b03d9b2d --- /dev/null +++ b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js @@ -0,0 +1,82 @@ +//// [/src/bar.ts] +interface RawAction { + (...args: any[]): Promise | void; +} +interface ActionFactory { + (target: T): T; +} +declare function foo(): ActionFactory; +export default foo()(function foobar(): void { +}); + +//// [/src/obj/bar.d.ts] +declare const _default: () => void; +export default _default; + + +//// [/src/obj/bar.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = foo()(function foobar() { +}); + + +//// [/src/obj/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };" + }, + "../bar.ts": { + "version": "747071916-interface RawAction {\r\n (...args: any[]): Promise | void;\r\n}\r\ninterface ActionFactory {\r\n (target: T): T;\r\n}\r\ndeclare function foo(): ActionFactory;\r\nexport default foo()(function foobar(): void {\r\n});", + "signature": "-9232740537-declare const _default: () => void;\r\nexport default _default;\r\n" + }, + "../bundling.ts": { + "version": "-21659820217-export class LazyModule {\r\n constructor(private importCallback: () => Promise) {}\r\n}\r\n\r\nexport class LazyAction<\r\n TAction extends (...args: any[]) => any,\r\n TModule\r\n> {\r\n constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction) {\r\n }\r\n}\r\n", + "signature": "-40032907372-export declare class LazyModule {\r\n private importCallback;\r\n constructor(importCallback: () => Promise);\r\n}\r\nexport declare class LazyAction any, TModule> {\r\n constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction);\r\n}\r\n" + }, + "../global.d.ts": { + "version": "-9780226215-interface PromiseConstructor {\r\n new (): Promise;\r\n}\r\ndeclare var Promise: PromiseConstructor;\r\ninterface Promise {\r\n}", + "signature": "-9780226215-interface PromiseConstructor {\r\n new (): Promise;\r\n}\r\ndeclare var Promise: PromiseConstructor;\r\ninterface Promise {\r\n}" + }, + "../lazyindex.ts": { + "version": "-6956449754-export { default as bar } from './bar';\n", + "signature": "-6224542381-export { default as bar } from './bar';\r\n" + }, + "../index.ts": { + "version": "-11602502901-import { LazyAction, LazyModule } from './bundling';\r\nconst lazyModule = new LazyModule(() =>\r\n import('./lazyIndex')\r\n);\r\nexport const lazyBar = new LazyAction(lazyModule, m => m.bar);", + "signature": "18468008756-import { LazyAction } from './bundling';\r\nexport declare const lazyBar: LazyAction<(param: string) => void, typeof import(\"./lazyIndex\")>;\r\n" + } + }, + "options": { + "target": 1, + "declaration": true, + "outDir": "./", + "incremental": true, + "isolatedModules": true, + "configFilePath": "../tsconfig.json" + }, + "referencedMap": { + "../index.ts": [ + "../bundling.ts", + "../lazyindex.ts" + ], + "../lazyindex.ts": [ + "../bar.ts" + ] + }, + "exportedModulesMap": { + "../index.ts": [ + "../bundling.ts", + "../lazyindex.ts" + ], + "../lazyindex.ts": [ + "../bar.ts" + ] + } + }, + "version": "FakeTSVersion" +} + diff --git a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js new file mode 100644 index 00000000000..3ebfc183fa9 --- /dev/null +++ b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js @@ -0,0 +1,135 @@ +//// [/src/obj/bar.d.ts] +declare const _default: (param: string) => void; +export default _default; + + +//// [/src/obj/bar.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = foo()(function foobar(param) { +}); + + +//// [/src/obj/bundling.d.ts] +export declare class LazyModule { + private importCallback; + constructor(importCallback: () => Promise); +} +export declare class LazyAction any, TModule> { + constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction); +} + + +//// [/src/obj/bundling.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var LazyModule = /** @class */ (function () { + function LazyModule(importCallback) { + this.importCallback = importCallback; + } + return LazyModule; +}()); +exports.LazyModule = LazyModule; +var LazyAction = /** @class */ (function () { + function LazyAction(_lazyModule, _getter) { + } + return LazyAction; +}()); +exports.LazyAction = LazyAction; + + +//// [/src/obj/index.d.ts] +import { LazyAction } from './bundling'; +export declare const lazyBar: LazyAction<(param: string) => void, typeof import("./lazyIndex")>; + + +//// [/src/obj/index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bundling_1 = require("./bundling"); +var lazyModule = new bundling_1.LazyModule(function () { + return Promise.resolve().then(function () { return require('./lazyIndex'); }); +}); +exports.lazyBar = new bundling_1.LazyAction(lazyModule, function (m) { return m.bar; }); + + +//// [/src/obj/lazyIndex.d.ts] +export { default as bar } from './bar'; + + +//// [/src/obj/lazyIndex.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var bar_1 = require("./bar"); +exports.bar = bar_1.default; + + +//// [/src/obj/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };" + }, + "../bar.ts": { + "version": "5936740878-interface RawAction {\r\n (...args: any[]): Promise | void;\r\n}\r\ninterface ActionFactory {\r\n (target: T): T;\r\n}\r\ndeclare function foo(): ActionFactory;\r\nexport default foo()(function foobar(param: string): void {\r\n});", + "signature": "11191036521-declare const _default: (param: string) => void;\r\nexport default _default;\r\n" + }, + "../bundling.ts": { + "version": "-21659820217-export class LazyModule {\r\n constructor(private importCallback: () => Promise) {}\r\n}\r\n\r\nexport class LazyAction<\r\n TAction extends (...args: any[]) => any,\r\n TModule\r\n> {\r\n constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction) {\r\n }\r\n}\r\n", + "signature": "-40032907372-export declare class LazyModule {\r\n private importCallback;\r\n constructor(importCallback: () => Promise);\r\n}\r\nexport declare class LazyAction any, TModule> {\r\n constructor(_lazyModule: LazyModule, _getter: (module: TModule) => TAction);\r\n}\r\n" + }, + "../global.d.ts": { + "version": "-9780226215-interface PromiseConstructor {\r\n new (): Promise;\r\n}\r\ndeclare var Promise: PromiseConstructor;\r\ninterface Promise {\r\n}", + "signature": "-9780226215-interface PromiseConstructor {\r\n new (): Promise;\r\n}\r\ndeclare var Promise: PromiseConstructor;\r\ninterface Promise {\r\n}" + }, + "../lazyindex.ts": { + "version": "-6956449754-export { default as bar } from './bar';\n", + "signature": "-6224542381-export { default as bar } from './bar';\r\n" + }, + "../index.ts": { + "version": "-11602502901-import { LazyAction, LazyModule } from './bundling';\r\nconst lazyModule = new LazyModule(() =>\r\n import('./lazyIndex')\r\n);\r\nexport const lazyBar = new LazyAction(lazyModule, m => m.bar);", + "signature": "18468008756-import { LazyAction } from './bundling';\r\nexport declare const lazyBar: LazyAction<(param: string) => void, typeof import(\"./lazyIndex\")>;\r\n" + } + }, + "options": { + "target": 1, + "declaration": true, + "outDir": "./", + "incremental": true, + "isolatedModules": true, + "configFilePath": "../tsconfig.json" + }, + "referencedMap": { + "../index.ts": [ + "../bundling.ts", + "../lazyindex.ts" + ], + "../lazyindex.ts": [ + "../bar.ts" + ] + }, + "exportedModulesMap": { + "../index.ts": [ + "../bundling.ts", + "../lazyindex.ts" + ], + "../lazyindex.ts": [ + "../bar.ts" + ] + } + }, + "version": "FakeTSVersion" +} + +//// [/src/tsconfig.json] +{ + "compilerOptions": { + "target": "es5", + "declaration": true, + "outDir": "obj", + "incremental": true, "isolatedModules": true + } +} + From 0019cee6de55842fe56d8e58ab4f85a8c2adabd2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 11 Sep 2019 12:11:59 -0700 Subject: [PATCH 034/100] Handle --isolatedModules and d.ts emit in the builder --- src/compiler/builder.ts | 32 +++++++++++++++++-- src/compiler/builderState.ts | 2 +- ...-transitive-module-with-isolatedModules.js | 18 +++++++++-- ...-transitive-module-with-isolatedModules.js | 10 +++++- 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 653832c8dbd..72526fc4b90 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -173,8 +173,7 @@ namespace ts { const compilerOptions = newProgram.getCompilerOptions(); state.compilerOptions = compilerOptions; // With --out or --outFile, any change affects all semantic diagnostics so no need to cache them - // With --isolatedModules, emitting changed file doesnt emit dependent files so we cant know of dependent files to retrieve errors so dont cache the errors - if (!compilerOptions.outFile && !compilerOptions.out && !compilerOptions.isolatedModules) { + if (!compilerOptions.outFile && !compilerOptions.out) { state.semanticDiagnosticsPerFile = createMap(); } state.changedFilesSet = createMap(); @@ -483,16 +482,43 @@ namespace ts { return !state.semanticDiagnosticsFromOldState.size; } + function isChangedSignagure(state: BuilderProgramState, path: Path) { + const newSignature = Debug.assertDefined(state.currentAffectedFilesSignatures).get(path); + const oldSignagure = Debug.assertDefined(state.fileInfos.get(path)).signature; + return newSignature !== oldSignagure; + } + /** * Iterate on referencing modules that export entities from affected file */ function forEachReferencingModulesOfExportOfAffectedFile(state: BuilderProgramState, affectedFile: SourceFile, fn: (state: BuilderProgramState, filePath: Path) => boolean) { // If there was change in signature (dts output) for the changed file, // then only we need to handle pending file emit - if (!state.exportedModulesMap || state.affectedFiles!.length === 1 || !state.changedFilesSet.has(affectedFile.path)) { + if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.path)) { return; } + if (!isChangedSignagure(state, affectedFile.path)) return; + + // Since isolated modules dont change js files, files affected by change in signature is itself + // But we need to cleanup semantic diagnostics and queue dts emit for affected files + if (state.compilerOptions.isolatedModules) { + const seenFileNamesMap = createMap(); + seenFileNamesMap.set(affectedFile.path, true); + const queue = BuilderState.getReferencedByPaths(state, affectedFile.resolvedPath); + while (queue.length > 0) { + const currentPath = queue.pop()!; + if (!seenFileNamesMap.has(currentPath)) { + seenFileNamesMap.set(currentPath, true); + const result = fn(state, currentPath); + if (result && isChangedSignagure(state, currentPath)) { + const currentSourceFile = Debug.assertDefined(state.program).getSourceFileByPath(currentPath)!; + queue.push(...BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath)); + } + } + } + } + Debug.assert(!!state.currentAffectedFilesExportedModulesMap); const seenFileAndExportsOfFile = createMap(); // Go through exported modules from cache first diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index 189d801777d..b34a0bf8370 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -466,7 +466,7 @@ namespace ts.BuilderState { /** * Gets the files referenced by the the file path */ - function getReferencedByPaths(state: Readonly, referencedFilePath: Path) { + export function getReferencedByPaths(state: Readonly, referencedFilePath: Path) { return arrayFrom(mapDefinedIterator(state.referencedMap!.entries(), ([filePath, referencesInFile]) => referencesInFile.has(referencedFilePath) ? filePath as Path : undefined )); diff --git a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js index bf9b03d9b2d..f8dfdc7e146 100644 --- a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js +++ b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/incremental-declaration-changes/inferred-type-from-transitive-module-with-isolatedModules.js @@ -21,6 +21,12 @@ exports.default = foo()(function foobar() { }); +//// [/src/obj/index.d.ts] +import { LazyAction } from './bundling'; +export declare const lazyBar: LazyAction<() => void, typeof import("./lazyIndex")>; + + +//// [/src/obj/lazyIndex.d.ts] file written with same contents //// [/src/obj/tsconfig.tsbuildinfo] { "program": { @@ -47,7 +53,7 @@ exports.default = foo()(function foobar() { }, "../index.ts": { "version": "-11602502901-import { LazyAction, LazyModule } from './bundling';\r\nconst lazyModule = new LazyModule(() =>\r\n import('./lazyIndex')\r\n);\r\nexport const lazyBar = new LazyAction(lazyModule, m => m.bar);", - "signature": "18468008756-import { LazyAction } from './bundling';\r\nexport declare const lazyBar: LazyAction<(param: string) => void, typeof import(\"./lazyIndex\")>;\r\n" + "signature": "6256067474-import { LazyAction } from './bundling';\r\nexport declare const lazyBar: LazyAction<() => void, typeof import(\"./lazyIndex\")>;\r\n" } }, "options": { @@ -75,7 +81,15 @@ exports.default = foo()(function foobar() { "../lazyindex.ts": [ "../bar.ts" ] - } + }, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "../bar.ts", + "../bundling.ts", + "../global.d.ts", + "../index.ts", + "../lazyindex.ts" + ] }, "version": "FakeTSVersion" } diff --git a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js index 3ebfc183fa9..568116485a4 100644 --- a/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js +++ b/tests/baselines/reference/tsbuild/inferredTypeFromTransitiveModule/initial-Build/inferred-type-from-transitive-module-with-isolatedModules.js @@ -118,7 +118,15 @@ exports.bar = bar_1.default; "../lazyindex.ts": [ "../bar.ts" ] - } + }, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "../bar.ts", + "../bundling.ts", + "../global.d.ts", + "../index.ts", + "../lazyindex.ts" + ] }, "version": "FakeTSVersion" } From 436339ddef241c3ae9da802ecddb9782e768cdc7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 12 Sep 2019 07:41:47 -0700 Subject: [PATCH 035/100] Use declared type for references in unreachable code --- src/compiler/checker.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d2a106b903d..c7e11e5be6a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -671,6 +671,7 @@ namespace ts { const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType); const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); + const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]); const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType; @@ -17008,7 +17009,7 @@ namespace ts { // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } return resultType; @@ -17144,8 +17145,11 @@ namespace ts { // Assignments only narrow the computed type if the declared type is a union type. Thus, we // only need to evaluate the assigned type if the declared type is a union type. if (isMatchingReference(reference, node)) { + const flowType = getTypeAtFlowNode(flow.antecedent); + if (flowType === unreachableNeverType) { + return flowType; + } if (getAssignmentTargetKind(node) === AssignmentKind.Compound) { - const flowType = getTypeAtFlowNode(flow.antecedent); return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType)); } if (declaredType === autoType || declaredType === autoArrayType) { @@ -17165,12 +17169,16 @@ namespace ts { // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case, // return the declared type. if (containsMatchingReference(reference, node)) { + const flowType = getTypeAtFlowNode(flow.antecedent); + if (flowType === unreachableNeverType) { + return flowType; + } // A matching dotted name might also be an expando property on a function *expression*, // in which case we continue control flow analysis back to the function's declaration if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) { const init = getDeclaredExpandoInitializer(node); if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) { - return getTypeAtFlowNode(flow.antecedent); + return flowType; } } return declaredType; @@ -17209,7 +17217,7 @@ namespace ts { return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType)); } if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) { - return neverType; + return unreachableNeverType; } } return undefined; From a9336ba8a5df106fd40ca8816735b6a98cd7381e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 12 Sep 2019 09:15:43 -0700 Subject: [PATCH 036/100] Revert "Use declared type for references in unreachable code" This reverts commit 436339ddef241c3ae9da802ecddb9782e768cdc7. --- src/compiler/checker.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c7e11e5be6a..d2a106b903d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -671,7 +671,6 @@ namespace ts { const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType); const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); - const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]); const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType; @@ -17009,7 +17008,7 @@ namespace ts { // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } return resultType; @@ -17145,11 +17144,8 @@ namespace ts { // Assignments only narrow the computed type if the declared type is a union type. Thus, we // only need to evaluate the assigned type if the declared type is a union type. if (isMatchingReference(reference, node)) { - const flowType = getTypeAtFlowNode(flow.antecedent); - if (flowType === unreachableNeverType) { - return flowType; - } if (getAssignmentTargetKind(node) === AssignmentKind.Compound) { + const flowType = getTypeAtFlowNode(flow.antecedent); return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType)); } if (declaredType === autoType || declaredType === autoArrayType) { @@ -17169,16 +17165,12 @@ namespace ts { // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case, // return the declared type. if (containsMatchingReference(reference, node)) { - const flowType = getTypeAtFlowNode(flow.antecedent); - if (flowType === unreachableNeverType) { - return flowType; - } // A matching dotted name might also be an expando property on a function *expression*, // in which case we continue control flow analysis back to the function's declaration if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) { const init = getDeclaredExpandoInitializer(node); if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) { - return flowType; + return getTypeAtFlowNode(flow.antecedent); } } return declaredType; @@ -17217,7 +17209,7 @@ namespace ts { return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType)); } if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) { - return unreachableNeverType; + return neverType; } } return undefined; From 3c79225f48773cccdf247578cf2297111f0ccd2a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 12 Sep 2019 11:18:47 -0700 Subject: [PATCH 037/100] Update baselines with any[] inferences --- tests/cases/fourslash/codeFixInferFromUsageArray.ts | 2 +- tests/cases/fourslash/codeFixInferFromUsageString.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cases/fourslash/codeFixInferFromUsageArray.ts b/tests/cases/fourslash/codeFixInferFromUsageArray.ts index 03d6b09e99b..75f923d5aee 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageArray.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageArray.ts @@ -10,5 +10,5 @@ //// return p.push(12) //// } -verify.rangeAfterCodeFix("p: number[], a: string[], b: any[], c: boolean[], d: any[], e: number[]", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); +verify.rangeAfterCodeFix("p: number[], a: string[], b: any[], c: boolean[], d: any[], e: any[]", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); diff --git a/tests/cases/fourslash/codeFixInferFromUsageString.ts b/tests/cases/fourslash/codeFixInferFromUsageString.ts index dc5787dc75b..d58998cf4a3 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageString.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageString.ts @@ -1,12 +1,12 @@ /// // @noImplicitAny: true -//// function foo([|p, a, b, c, d |]) { +//// function foo([|p, a, b |]) { //// var x //// p.charAt(x) //// a.charAt(0) //// b.concat('hi') //// } -verify.rangeAfterCodeFix("p: string, a: string, b: string | string[]", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); +verify.rangeAfterCodeFix("p: string, a: string, b: string | any[]", /*includeWhiteSpace*/ undefined, /*errorCode*/ undefined, /*index*/0); From de7d68a6d8704545fa4d04e3e0cf3072bda887c2 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 12 Sep 2019 11:30:51 -0700 Subject: [PATCH 038/100] Even more renaming --- src/services/codefixes/inferFromUsage.ts | 46 ++++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 00b95c57d1a..090c241b05d 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -481,7 +481,7 @@ namespace ts.codefix { } function single(): Type { - return unifyTypes(inferTypesFromReferencesSingle(references)); + return combineTypes(inferTypesFromReferencesSingle(references)); } function parameters(declaration: FunctionLike): ParameterInference[] | undefined { @@ -517,7 +517,7 @@ namespace ts.codefix { const inferred = inferTypesFromReferencesSingle(getReferences(parameter.name, program, cancellationToken)); types.push(...(isRest ? mapDefined(inferred, checker.getElementTypeOfArrayType) : inferred)); } - const type = unifyTypes(types); + const type = combineTypes(types); return { type: isRest ? checker.createArrayType(type) : type, isOptional: isOptional && !isRest, @@ -533,7 +533,7 @@ namespace ts.codefix { calculateUsageOfNode(reference, usage); } - return unifyTypes(usage.candidateThisTypes || emptyArray); + return combineTypes(usage.candidateThisTypes || emptyArray); } function inferTypesFromReferencesSingle(references: readonly Identifier[]): Type[] { @@ -542,7 +542,7 @@ namespace ts.codefix { cancellationToken.throwIfCancellationRequested(); calculateUsageOfNode(reference, usage); } - return inferFromUsage(usage); + return inferTypes(usage); } function calculateUsageOfNode(node: Expression, usage: Usage): void { @@ -819,11 +819,11 @@ namespace ts.codefix { return inferences.filter(i => toRemove.every(f => !f(i))); } - function unifyFromUsage(usage: Usage) { - return unifyTypes(inferFromUsage(usage)); + function combineFromUsage(usage: Usage) { + return combineTypes(inferTypes(usage)); } - function unifyTypes(inferences: readonly Type[]): Type { + function combineTypes(inferences: readonly Type[]): Type { if (!inferences.length) return checker.getAnyType(); // 1. string or number individually override string | number @@ -847,12 +847,12 @@ namespace ts.codefix { const anons = good.filter(i => checker.getObjectFlags(i) & ObjectFlags.Anonymous) as AnonymousType[]; if (anons.length) { good = good.filter(i => !(checker.getObjectFlags(i) & ObjectFlags.Anonymous)); - good.push(unifyAnonymousTypes(anons)); + good.push(combineAnonymousTypes(anons)); } return checker.getWidenedType(checker.getUnionType(good.map(checker.getBaseTypeOfLiteralType), UnionReduction.Subtype)); } - function unifyAnonymousTypes(anons: AnonymousType[]) { + function combineAnonymousTypes(anons: AnonymousType[]) { if (anons.length === 1) { return anons[0]; } @@ -893,7 +893,7 @@ namespace ts.codefix { numberIndices.length ? checker.createIndexInfo(checker.getUnionType(numberIndices), numberIndexReadonly) : undefined); } - function inferFromUsage(usage: Usage): Type[] { + function inferTypes(usage: Usage): Type[] { const types = []; if (usage.isNumber) { @@ -906,7 +906,7 @@ namespace ts.codefix { types.push(checker.getUnionType([checker.getStringType(), checker.getNumberType()])); } if (usage.numberIndex) { - types.push(checker.createArrayType(unifyFromUsage(usage.numberIndex))); + types.push(checker.createArrayType(combineFromUsage(usage.numberIndex))); } if (usage.properties && usage.properties.size || usage.calls && usage.calls.length @@ -926,13 +926,13 @@ namespace ts.codefix { if (usage.properties) { usage.properties.forEach((u, name) => { const symbol = checker.createSymbol(SymbolFlags.Property, name); - symbol.type = unifyFromUsage(u); + symbol.type = combineFromUsage(u); members.set(name, symbol); }); } const callSignatures: Signature[] = usage.calls ? [getSignatureFromCalls(usage.calls)] : []; const constructSignatures: Signature[] = usage.constructs ? [getSignatureFromCalls(usage.constructs)] : []; - const stringIndexInfo = usage.stringIndex && checker.createIndexInfo(unifyFromUsage(usage.stringIndex), /*isReadonly*/ false); + const stringIndexInfo = usage.stringIndex && checker.createIndexInfo(combineFromUsage(usage.stringIndex), /*isReadonly*/ false); return checker.createAnonymousType(/*symbol*/ undefined!, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined); // TODO: GH#18217 } @@ -959,7 +959,7 @@ namespace ts.codefix { result = result && !!sigs.length && checker.isTypeAssignableTo(source, getFunctionFromCalls(propUsage.calls)); } else { - result = result && checker.isTypeAssignableTo(source, unifyFromUsage(propUsage)); + result = result && checker.isTypeAssignableTo(source, combineFromUsage(propUsage)); } }); return result; @@ -982,17 +982,17 @@ namespace ts.codefix { usage.properties.forEach((propUsage, name) => { const genericPropertyType = checker.getTypeOfPropertyOfType(generic, name as string); Debug.assert(!!genericPropertyType, "generic should have all the properties of its reference."); - types.push(...infer(genericPropertyType!, unifyFromUsage(propUsage), singleTypeParameter)); + types.push(...inferTypeParameters(genericPropertyType!, combineFromUsage(propUsage), singleTypeParameter)); }); - return builtinConstructors[type.symbol.escapedName as string](unifyTypes(types)); + return builtinConstructors[type.symbol.escapedName as string](combineTypes(types)); } - function infer(genericType: Type, usageType: Type, typeParameter: Type): readonly Type[] { + function inferTypeParameters(genericType: Type, usageType: Type, typeParameter: Type): readonly Type[] { if (genericType === typeParameter) { return [usageType]; } else if (genericType.flags & TypeFlags.UnionOrIntersection) { - return flatMap((genericType as UnionOrIntersectionType).types, t => infer(t, usageType, typeParameter)); + return flatMap((genericType as UnionOrIntersectionType).types, t => inferTypeParameters(t, usageType, typeParameter)); } else if (getObjectFlags(genericType) & ObjectFlags.Reference && getObjectFlags(usageType) & ObjectFlags.Reference) { // this is wrong because we need a reference to the targetType to, so we can check that it's also a reference @@ -1002,7 +1002,7 @@ namespace ts.codefix { if (genericArgs && usageArgs) { for (let i = 0; i < genericArgs.length; i++) { if (usageArgs[i]) { - types.push(...infer(genericArgs[i], usageArgs[i], typeParameter)); + types.push(...inferTypeParameters(genericArgs[i], usageArgs[i], typeParameter)); } } } @@ -1031,11 +1031,11 @@ namespace ts.codefix { genericParamType = elementType; } const targetType = (usageParam as SymbolLinks).type || checker.getTypeOfSymbolAtLocation(usageParam, usageParam.valueDeclaration); - types.push(...infer(genericParamType, targetType, typeParameter)); + types.push(...inferTypeParameters(genericParamType, targetType, typeParameter)); } const genericReturn = checker.getReturnTypeOfSignature(genericSig); const usageReturn = checker.getReturnTypeOfSignature(usageSig); - types.push(...infer(genericReturn, usageReturn, typeParameter)); + types.push(...inferTypeParameters(genericReturn, usageReturn, typeParameter)); return types; } @@ -1048,13 +1048,13 @@ namespace ts.codefix { const length = Math.max(...calls.map(c => c.argumentTypes.length)); for (let i = 0; i < length; i++) { const symbol = checker.createSymbol(SymbolFlags.FunctionScopedVariable, escapeLeadingUnderscores(`arg${i}`)); - symbol.type = unifyTypes(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType())); + symbol.type = combineTypes(calls.map(call => call.argumentTypes[i] || checker.getUndefinedType())); if (calls.some(call => call.argumentTypes[i] === undefined)) { symbol.flags |= SymbolFlags.Optional; } parameters.push(symbol); } - const returnType = unifyFromUsage(combineUsages(calls.map(call => call.return_))); + const returnType = combineFromUsage(combineUsages(calls.map(call => call.return_))); // TODO: GH#18217 return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } From d94d715cdfd33295e5789490d7cd5ec8d3e5b4fd Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 12 Sep 2019 13:31:11 -0700 Subject: [PATCH 039/100] Make perf count functions public Previously they were internal --- src/compiler/types.ts | 10 +++++----- tests/baselines/reference/api/tsserverlibrary.d.ts | 9 +++++++++ tests/baselines/reference/api/typescript.d.ts | 9 +++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5acc831f127..1828d056405 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3007,11 +3007,11 @@ namespace ts { /* @internal */ getClassifiableNames(): UnderscoreEscapedMap; - /* @internal */ getNodeCount(): number; - /* @internal */ getIdentifierCount(): number; - /* @internal */ getSymbolCount(): number; - /* @internal */ getTypeCount(): number; - /* @internal */ getRelationCacheSizes(): { assignable: number, identity: number, subtype: number }; + getNodeCount(): number; + getIdentifierCount(): number; + getSymbolCount(): number; + getTypeCount(): number; + getRelationCacheSizes(): { assignable: number, identity: number, subtype: number }; /* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection; /* @internal */ getResolvedTypeReferenceDirectives(): Map; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6620848321c..41ea5756204 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1883,6 +1883,15 @@ declare namespace ts { * Gets a type checker that can be used to semantically analyze source files in the program. */ getTypeChecker(): TypeChecker; + getNodeCount(): number; + getIdentifierCount(): number; + getSymbolCount(): number; + getTypeCount(): number; + getRelationCacheSizes(): { + assignable: number; + identity: number; + subtype: number; + }; isSourceFileFromExternalLibrary(file: SourceFile): boolean; isSourceFileDefaultLibrary(file: SourceFile): boolean; getProjectReferences(): readonly ProjectReference[] | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index eaef5a454e2..8402150f2a0 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1883,6 +1883,15 @@ declare namespace ts { * Gets a type checker that can be used to semantically analyze source files in the program. */ getTypeChecker(): TypeChecker; + getNodeCount(): number; + getIdentifierCount(): number; + getSymbolCount(): number; + getTypeCount(): number; + getRelationCacheSizes(): { + assignable: number; + identity: number; + subtype: number; + }; isSourceFileFromExternalLibrary(file: SourceFile): boolean; isSourceFileDefaultLibrary(file: SourceFile): boolean; getProjectReferences(): readonly ProjectReference[] | undefined; From 971b0df80a3bacf9d6108c5053cabb18f0ae74f6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 13 Sep 2019 07:12:19 -0700 Subject: [PATCH 040/100] Use declared type for references in unreachable code (again) --- src/compiler/checker.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d2a106b903d..2e792040bb4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -671,6 +671,7 @@ namespace ts { const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonInferrableType = createIntrinsicType(TypeFlags.Never, "never", ObjectFlags.NonInferrableType); const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); + const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]); const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType; @@ -17008,7 +17009,7 @@ namespace ts { // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } return resultType; @@ -17037,6 +17038,7 @@ namespace ts { if (key) { const id = getFlowNodeId(flow); if (flowAssignmentKeys[id] === key) { + flowDepth--; return flowAssignmentTypes[id]; } } @@ -17144,8 +17146,11 @@ namespace ts { // Assignments only narrow the computed type if the declared type is a union type. Thus, we // only need to evaluate the assigned type if the declared type is a union type. if (isMatchingReference(reference, node)) { + const flowType = getTypeAtFlowNode(flow.antecedent); + if (flowType === unreachableNeverType) { + return flowType; + } if (getAssignmentTargetKind(node) === AssignmentKind.Compound) { - const flowType = getTypeAtFlowNode(flow.antecedent); return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType)); } if (declaredType === autoType || declaredType === autoArrayType) { @@ -17165,12 +17170,16 @@ namespace ts { // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case, // return the declared type. if (containsMatchingReference(reference, node)) { + const flowType = getTypeAtFlowNode(flow.antecedent); + if (flowType === unreachableNeverType) { + return flowType; + } // A matching dotted name might also be an expando property on a function *expression*, // in which case we continue control flow analysis back to the function's declaration if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) { const init = getDeclaredExpandoInitializer(node); if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) { - return getTypeAtFlowNode(flow.antecedent); + return flowType; } } return declaredType; @@ -17209,7 +17218,7 @@ namespace ts { return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType)); } if (getReturnTypeOfSignature(signature).flags & TypeFlags.Never) { - return neverType; + return unreachableNeverType; } } return undefined; From 93a250b9a6d5c1869d5c7c9d9633d049484b7427 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sat, 14 Sep 2019 02:22:59 +0800 Subject: [PATCH 041/100] fix duplicate async modifier codefix --- src/services/codefixes/fixAwaitInSyncFunction.ts | 13 ++++++++----- .../fourslash/codeFixAwaitInSyncFunction_all.ts | 4 ++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts index e5b3a24dbea..55dd4bd0556 100644 --- a/src/services/codefixes/fixAwaitInSyncFunction.ts +++ b/src/services/codefixes/fixAwaitInSyncFunction.ts @@ -15,11 +15,14 @@ namespace ts.codefix { return [createCodeFixAction(fixId, changes, Diagnostics.Add_async_modifier_to_containing_function, fixId, Diagnostics.Add_all_missing_async_modifiers)]; }, fixIds: [fixId], - getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { - const nodes = getNodes(diag.file, diag.start); - if (!nodes) return; - doChange(changes, context.sourceFile, nodes); - }), + getAllCodeActions: context => { + const seen = createMap(); + return codeFixAll(context, errorCodes, (changes, diag) => { + const nodes = getNodes(diag.file, diag.start); + if (!nodes || !addToSeen(seen, getNodeId(nodes.insertBefore))) return; + doChange(changes, context.sourceFile, nodes); + }); + }, }); function getReturnType(expr: FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction) { diff --git a/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts b/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts index 4b5f7aea0a3..fadb5f30ca8 100644 --- a/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts +++ b/tests/cases/fourslash/codeFixAwaitInSyncFunction_all.ts @@ -2,10 +2,12 @@ ////function f() { //// await Promise.resolve(); +//// await Promise.resolve(); ////} //// ////const g = () => { //// await f(); +//// await f(); ////} verify.codeFixAll({ @@ -14,9 +16,11 @@ verify.codeFixAll({ newFileContent: `async function f() { await Promise.resolve(); + await Promise.resolve(); } const g = async () => { await f(); + await f(); }`, }); From 3749de60195f0bce34ac5ed4f265102cbc425193 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 13 Sep 2019 11:33:16 -0700 Subject: [PATCH 042/100] Dedicated isReachableFlowNode function to determine reachability --- src/compiler/checker.ts | 48 +++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2e792040bb4..b5630a6ef10 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -842,6 +842,7 @@ namespace ts { const flowLoopTypes: Type[][] = []; const sharedFlowNodes: FlowNode[] = []; const sharedFlowTypes: FlowType[] = []; + const flowNodeReachable: (boolean | undefined)[] = []; const potentialThisCollisions: Node[] = []; const potentialNewTargetCollisions: Node[] = []; const awaitedTypeStack: number[] = []; @@ -16991,6 +16992,40 @@ namespace ts { diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis)); } + function isReachableFlowNode(flow: FlowNode) { + return isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false); + } + + function isReachableFlowNodeWorker(flow: FlowNode, skipCacheCheck: boolean): boolean { + while (true) { + const flags = flow.flags; + if (flags & FlowFlags.Shared && !skipCacheCheck) { + const id = getFlowNodeId(flow); + const reachable = flowNodeReachable[id]; + return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ true)); + } + if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.SwitchClause | FlowFlags.ArrayMutation | FlowFlags.PreFinally | FlowFlags.AfterFinally)) { + flow = (flow).antecedent; + } + else if (flags & FlowFlags.Call) { + const signature = getEffectsSignature((flow).node); + if (signature && getReturnTypeOfSignature(signature).flags & TypeFlags.Never) { + return false; + } + flow = (flow).antecedent; + } + else if (flags & FlowFlags.LoopLabel) { + flow = (flow).antecedents![0]; + } + else if (flags & FlowFlags.BranchLabel) { + return every((flow).antecedents!, isReachableFlowNode); + } + else { + return true; + } + } + } + function getFlowTypeOfReference(reference: Node, declaredType: Type, initialType = declaredType, flowContainer?: Node, couldBeUninitialized?: boolean) { let key: string | undefined; let keySet = false; @@ -17146,11 +17181,11 @@ namespace ts { // Assignments only narrow the computed type if the declared type is a union type. Thus, we // only need to evaluate the assigned type if the declared type is a union type. if (isMatchingReference(reference, node)) { - const flowType = getTypeAtFlowNode(flow.antecedent); - if (flowType === unreachableNeverType) { - return flowType; + if (!isReachableFlowNode(flow)) { + return unreachableNeverType; } if (getAssignmentTargetKind(node) === AssignmentKind.Compound) { + const flowType = getTypeAtFlowNode(flow.antecedent); return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType)); } if (declaredType === autoType || declaredType === autoArrayType) { @@ -17170,16 +17205,15 @@ namespace ts { // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case, // return the declared type. if (containsMatchingReference(reference, node)) { - const flowType = getTypeAtFlowNode(flow.antecedent); - if (flowType === unreachableNeverType) { - return flowType; + if (!isReachableFlowNode(flow)) { + return unreachableNeverType; } // A matching dotted name might also be an expando property on a function *expression*, // in which case we continue control flow analysis back to the function's declaration if (isVariableDeclaration(node) && (isInJSFile(node) || isVarConst(node))) { const init = getDeclaredExpandoInitializer(node); if (init && (init.kind === SyntaxKind.FunctionExpression || init.kind === SyntaxKind.ArrowFunction)) { - return flowType; + return getTypeAtFlowNode(flow.antecedent); } } return declaredType; From 1755db4d8129b521a4a7a4a35882dcb9b9a24040 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 13 Sep 2019 14:38:10 -0700 Subject: [PATCH 043/100] Add build-eslint-rules to npm prepare script (#33417) * Add build-eslint-rules to local build * Switch to prepare script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 478538926ce..7a59b95a130 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "xml2js": "^0.4.19" }, "scripts": { + "prepare": "gulp build-eslint-rules", "pretest": "gulp tests", "test": "gulp runtests-parallel --light=false", "test:eslint-rules": "gulp run-eslint-rules-tests", From 3a89c8cc5c06669c7d53e4e382db4390df1dfb59 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 13 Sep 2019 14:38:12 -0700 Subject: [PATCH 044/100] Use isReachableFlowNode to check for implicit return --- src/compiler/binder.ts | 6 ++---- src/compiler/checker.ts | 11 +++-------- src/compiler/types.ts | 2 +- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 77ad55a20c9..bb3b7b10508 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -569,7 +569,7 @@ namespace ts { } // We create a return control flow graph for IIFEs and constructors. For constructors // we use the return control flow graph in strict property initialization checks. - currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined; + currentReturnTarget = containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((node).body) ? createBranchLabel() : undefined; currentBreakTarget = undefined; currentContinueTarget = undefined; activeLabels = undefined; @@ -589,9 +589,7 @@ namespace ts { if (currentReturnTarget) { addAntecedent(currentReturnTarget, currentFlow); currentFlow = finishFlowLabel(currentReturnTarget); - if (node.kind === SyntaxKind.Constructor) { - (node).returnFlowNode = currentFlow; - } + (node).returnFlowNode = currentFlow; } if (!isIIFE) { currentFlow = saveCurrentFlow; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b5630a6ef10..5e491b2e730 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23803,15 +23803,10 @@ namespace ts { return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes); } - function isNeverFunctionCall(expr: Expression) { - const signature = expr.kind === SyntaxKind.CallExpression && getEffectsSignature(expr); - return !!(signature && getReturnTypeOfSignature(signature).flags & TypeFlags.Never); - } - function functionHasImplicitReturn(func: FunctionLikeDeclaration) { - return !!(func.flags & NodeFlags.HasImplicitReturn) && !some((func.body).statements, statement => - statement.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(statement) || - statement.kind === SyntaxKind.ExpressionStatement && isNeverFunctionCall((statement).expression)); + return !!(func.flags & NodeFlags.HasImplicitReturn && + !some((func.body).statements, s => s.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(s)) && + !(func.returnFlowNode && !isReachableFlowNode(func.returnFlowNode))); } /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */ diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7486af7148d..214c2d58788 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1040,6 +1040,7 @@ namespace ts { questionToken?: QuestionToken; exclamationToken?: ExclamationToken; body?: Block | Expression; + /* @internal */ returnFlowNode?: FlowNode; } export type FunctionLikeDeclaration = @@ -1085,7 +1086,6 @@ namespace ts { kind: SyntaxKind.Constructor; parent: ClassLikeDeclaration; body?: FunctionBody; - /* @internal */ returnFlowNode?: FlowNode; } /** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */ From 99229f88dd785f0eb559a668663843db782eff4e Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Fri, 13 Sep 2019 15:14:25 -0700 Subject: [PATCH 045/100] Update user baselines (#33411) --- .../baselines/reference/docker/azure-sdk.log | 4 ++-- .../reference/docker/office-ui-fabric.log | 7 +++++-- tests/baselines/reference/docker/vscode.log | 20 ++++++++++++++----- tests/baselines/reference/user/jimp.log | 6 +----- tests/baselines/reference/user/prettier.log | 8 +++++--- tests/baselines/reference/user/webpack.log | 10 ++++++++++ tests/cases/user/axios-src/axios-src | 2 +- .../user/create-react-app/create-react-app | 2 +- tests/cases/user/prettier/prettier | 2 +- tests/cases/user/puppeteer/puppeteer | 2 +- tests/cases/user/webpack/webpack | 2 +- 11 files changed, 43 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/user/webpack.log diff --git a/tests/baselines/reference/docker/azure-sdk.log b/tests/baselines/reference/docker/azure-sdk.log index 347a6c188a9..ad0dbf4e9d6 100644 --- a/tests/baselines/reference/docker/azure-sdk.log +++ b/tests/baselines/reference/docker/azure-sdk.log @@ -24,7 +24,7 @@ Warning: You have changed the public API signature for this project. Updating re dist-esm/index.js → dist/index.js... (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency -tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) +tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js) @azure/cosmos-sign (imported by dist-esm/auth.js) universal-user-agent (imported by dist-esm/common/platform.js) uuid/v4 (imported by dist-esm/ClientContext.js, dist-esm/client/Item/Items.js) @@ -96,7 +96,7 @@ Warning: You have changed the public API signature for this project. Updating re dist-esm/index.js → dist/index.js... (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency -tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) +tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js) @azure/cosmos-sign (imported by dist-esm/auth.js) universal-user-agent (imported by dist-esm/common/platform.js) uuid/v4 (imported by dist-esm/ClientContext.js, dist-esm/client/Item/Items.js) diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index b36e3e50ffc..67398753776 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -34,6 +34,10 @@ Standard output: @uifabric/migration: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/migration/tsconfig.json @uifabric/migration: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib --module commonjs --project "/office-ui-fabric-react/packages/migration/tsconfig.json" @uifabric/migration: Done in ?s. +@uifabric/monaco-editor: yarn run vX.X.X +@uifabric/monaco-editor: $ just-scripts build --production --lint +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Removing [lib] +@uifabric/monaco-editor: Done in ?s. @uifabric/set-version: yarn run vX.X.X @uifabric/set-version: $ just-scripts build --production --lint @uifabric/set-version: [XX:XX:XX XM] ■ Removing [lib, temp, dist, lib-amd, lib-commonjs, lib-es2015, coverage, src/**/*.scss.ts] @@ -84,7 +88,6 @@ Standard output: @uifabric/merge-styles: PASS src/Stylesheet.test.ts @uifabric/merge-styles: PASS src/extractStyleParts.test.ts @uifabric/merge-styles: PASS src/server.test.ts -@uifabric/merge-styles: PASS src/fontFace.test.ts @uifabric/merge-styles: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/merge-styles/lib/index.d.ts' @uifabric/merge-styles: Done in ?s. @uifabric/jest-serializer-merge-styles: yarn run vX.X.X @@ -223,7 +226,7 @@ Standard output: Standard error: info cli using local version of lerna lerna notice cli vX.X.X -lerna info Executing command in 41 packages: "yarn run build --production --lint" +lerna info Executing command in 42 packages: "yarn run build --production --lint" @uifabric/codepen-loader: ts-jest[versions] (WARN) Version X.X.X-insiders.xxxxxxxx of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=2.7.0 <4.0.0). Please do not report issues in ts-jest if you are using unsupported versions. @uifabric/codepen-loader: Force exiting Jest @uifabric/codepen-loader: diff --git a/tests/baselines/reference/docker/vscode.log b/tests/baselines/reference/docker/vscode.log index 8bc85ffef12..fdd7db9d713 100644 --- a/tests/baselines/reference/docker/vscode.log +++ b/tests/baselines/reference/docker/vscode.log @@ -1,14 +1,24 @@ -Exit Code: 0 +Exit Code: 1 Standard output: yarn run vX.X.X $ gulp compile --max_old_space_size=4095 [XX:XX:XX] Node flags detected: --max_old_space_size=4095 [XX:XX:XX] Using gulpfile /vscode/gulpfile.js -Done in ?s. +info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. Standard error: -{"type":"warning","data":"package.json: No license field"} -{"type":"warning","data":"../package.json: No license field"} -{"type":"warning","data":"vscode-web@X.X.X: No license field"} +[XX:XX:XX] 'compile' errored after ?s +[XX:XX:XX] TypeError: Cannot read property 'text' of undefined + at DeclarationResolver._getDeclarationSourceFile (/vscode/build/monaco/api.js:519:75) + at DeclarationResolver.getDeclarationSourceFile (/vscode/build/monaco/api.js:493:52) + at sourceFileGetter (/vscode/build/monaco/api.js:525:53) + at lines.forEach.line (/vscode/build/monaco/api.js:330:32) + at Array.forEach () + at generateDeclarationFile (/vscode/build/monaco/api.js:319:11) + at _run (/vscode/build/monaco/api.js:438:15) + at Object.run3 (/vscode/build/monaco/api.js:526:12) + at MonacoGenerator._run (/vscode/build/lib/compilation.js:142:27) + at MonacoGenerator.execute (/vscode/build/lib/compilation.js:154:29) +error Command failed with exit code 1. diff --git a/tests/baselines/reference/user/jimp.log b/tests/baselines/reference/user/jimp.log index 94ca297844b..d9a47363e22 100644 --- a/tests/baselines/reference/user/jimp.log +++ b/tests/baselines/reference/user/jimp.log @@ -1,10 +1,6 @@ Exit Code: 1 Standard output: -node_modules/@jimp/core/index.d.ts(200,3): error TS2411: Property 'class' of type 'undefined' is not assignable to string index type 'Function'. -node_modules/@jimp/core/index.d.ts(201,3): error TS2411: Property 'constants' of type 'undefined' is not assignable to string index type 'Function'. -node_modules/@jimp/core/index.d.ts(255,42): error TS2344: Type 'T' does not satisfy the constraint 'WellFormedPlugin'. - Type 'JimpType | undefined' is not assignable to type 'WellFormedPlugin'. - Type 'undefined' is not assignable to type 'WellFormedPlugin'. +index.ts(1,23): error TS2307: Cannot find module 'jimp'. diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log index 6e7cf800473..743c7a71167 100644 --- a/tests/baselines/reference/user/prettier.log +++ b/tests/baselines/reference/user/prettier.log @@ -244,9 +244,11 @@ src/language-js/printer-estree.js(4201,24): error TS2532: Object is possibly 'un src/language-js/printer-estree.js(4557,5): error TS2345: Argument of type '"" | { type: string; parts: any; } | { type: string; contents: any; }' is not assignable to parameter of type 'string'. Type '{ type: string; parts: any; }' is not assignable to type 'string'. src/language-js/printer-estree.js(4561,16): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. -src/language-js/printer-estree.js(4603,9): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. -src/language-js/printer-estree.js(4905,9): error TS2554: Expected 0-2 arguments, but got 3. -src/language-js/printer-estree.js(6112,7): error TS2769: No overload matches this call. +src/language-js/printer-estree.js(4609,11): error TS2322: Type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }' is not assignable to type 'string'. +src/language-js/printer-estree.js(4624,11): error TS2322: Type '{ type: string; parts: any; }' is not assignable to type 'string'. +src/language-js/printer-estree.js(4636,9): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(4923,9): error TS2554: Expected 0-2 arguments, but got 3. +src/language-js/printer-estree.js(6130,7): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<(childPath: any) => any>[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type 'ConcatArray<(childPath: any) => any>'. Types of property 'slice' are incompatible. diff --git a/tests/baselines/reference/user/webpack.log b/tests/baselines/reference/user/webpack.log new file mode 100644 index 00000000000..d1fbc9df903 --- /dev/null +++ b/tests/baselines/reference/user/webpack.log @@ -0,0 +1,10 @@ +Exit Code: 1 +Standard output: +lib/Compilation.js(575,5): error TS2322: Type 'number | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | ... 29 more ... | "trimRight"' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +lib/Compiler.js(228,48): error TS2345: Argument of type 'number | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | ... 29 more ... | "trimRight"' is not assignable to parameter of type 'string'. + Type 'number' is not assignable to type 'string'. + + + +Standard error: diff --git a/tests/cases/user/axios-src/axios-src b/tests/cases/user/axios-src/axios-src index 6a4a85c57fc..d74385f1c8f 160000 --- a/tests/cases/user/axios-src/axios-src +++ b/tests/cases/user/axios-src/axios-src @@ -1 +1 @@ -Subproject commit 6a4a85c57fcaba912eee61b87ba34d07323bc60c +Subproject commit d74385f1c8f944a6d94ae0680d3841859a2fcb38 diff --git a/tests/cases/user/create-react-app/create-react-app b/tests/cases/user/create-react-app/create-react-app index c9b95047b97..74eb65a4626 160000 --- a/tests/cases/user/create-react-app/create-react-app +++ b/tests/cases/user/create-react-app/create-react-app @@ -1 +1 @@ -Subproject commit c9b95047b979bebe89ee70590b2a32ab67ef68af +Subproject commit 74eb65a46269d5c2cc5483841e271281477c650e diff --git a/tests/cases/user/prettier/prettier b/tests/cases/user/prettier/prettier index 9f5bd298db2..e83b4537fea 160000 --- a/tests/cases/user/prettier/prettier +++ b/tests/cases/user/prettier/prettier @@ -1 +1 @@ -Subproject commit 9f5bd298db26f76e95ad17f8406edd7ebefacc5a +Subproject commit e83b4537feaa6c063a1598b8d3972b6ad600f2a7 diff --git a/tests/cases/user/puppeteer/puppeteer b/tests/cases/user/puppeteer/puppeteer index c2651c2b5cc..a5f03ce1c85 160000 --- a/tests/cases/user/puppeteer/puppeteer +++ b/tests/cases/user/puppeteer/puppeteer @@ -1 +1 @@ -Subproject commit c2651c2b5cc888ebd0ca6be87063d9f98b9eb59c +Subproject commit a5f03ce1c85c2630739f2a894a303c68632aa250 diff --git a/tests/cases/user/webpack/webpack b/tests/cases/user/webpack/webpack index 77cd3d0cff3..e4c7d8c0ae0 160000 --- a/tests/cases/user/webpack/webpack +++ b/tests/cases/user/webpack/webpack @@ -1 +1 @@ -Subproject commit 77cd3d0cff39def2f8bd6355dcd270dd80bc5da2 +Subproject commit e4c7d8c0ae0c93306f07920bc28fe72119bc098a From 038d95144d8b93c2799d1732181c89c3d84362d5 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 13 Sep 2019 16:14:33 -0700 Subject: [PATCH 046/100] Remove all submodules - just force clone and reset on run instead (#33425) --- .gitignore | 12 +++++- .gitmodules | 40 ------------------- src/testRunner/externalCompileRunner.ts | 15 ++++--- .../TypeScript-Node-Starter | 1 - .../user/TypeScript-Node-Starter/test.json | 1 + .../TypeScript-React-Native-Starter | 1 - .../TypeScript-React-Native-Starter/test.json | 1 + .../TypeScript-React-Starter | 1 - .../user/TypeScript-React-Starter/test.json | 1 + .../TypeScript-Vue-Starter | 1 - .../user/TypeScript-Vue-Starter/test.json | 1 + .../TypeScript-WeChat-Starter | 1 - .../user/TypeScript-WeChat-Starter/test.json | 1 + tests/cases/user/axios-src/axios-src | 1 - tests/cases/user/axios-src/test.json | 1 + .../user/create-react-app/create-react-app | 1 - tests/cases/user/create-react-app/test.json | 1 + tests/cases/user/prettier/prettier | 1 - tests/cases/user/prettier/test.json | 1 + tests/cases/user/puppeteer/puppeteer | 1 - tests/cases/user/puppeteer/test.json | 1 + tests/cases/user/webpack/test.json | 1 + tests/cases/user/webpack/webpack | 1 - 23 files changed, 31 insertions(+), 56 deletions(-) delete mode 160000 tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter delete mode 160000 tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter delete mode 160000 tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter delete mode 160000 tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter delete mode 160000 tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter delete mode 160000 tests/cases/user/axios-src/axios-src delete mode 160000 tests/cases/user/create-react-app/create-react-app delete mode 160000 tests/cases/user/prettier/prettier delete mode 160000 tests/cases/user/puppeteer/puppeteer delete mode 160000 tests/cases/user/webpack/webpack diff --git a/.gitignore b/.gitignore index a220522b5f0..da243079549 100644 --- a/.gitignore +++ b/.gitignore @@ -81,4 +81,14 @@ tests/cases/user/*/**/*.d.ts tests/baselines/reference/dt .failed-tests TEST-results.xml -package-lock.json \ No newline at end of file +package-lock.json +tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter +tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter +tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter +tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter +tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter +tests/cases/user/create-react-app/create-react-app +tests/cases/user/webpack/webpack +tests/cases/user/puppeteer/puppeteer +tests/cases/user/axios-src/axios-src +tests/cases/user/prettier/prettier \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 0e4e0b3ed77..e69de29bb2d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,40 +0,0 @@ -[submodule "tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter"] - path = tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter - url = https://github.com/Microsoft/TypeScript-React-Starter - ignore = all -[submodule "tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter"] - path = tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter - url = https://github.com/Microsoft/TypeScript-Node-Starter.git - ignore = all -[submodule "tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter"] - path = tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter - url = https://github.com/Microsoft/TypeScript-React-Native-Starter.git - ignore = all -[submodule "tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter"] - path = tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter - url = https://github.com/Microsoft/TypeScript-Vue-Starter.git - ignore = all -[submodule "tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter"] - path = tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter - url = https://github.com/Microsoft/TypeScript-WeChat-Starter.git - ignore = all -[submodule "tests/cases/user/create-react-app/create-react-app"] - path = tests/cases/user/create-react-app/create-react-app - url = https://github.com/facebook/create-react-app.git - ignore = all -[submodule "tests/cases/user/webpack/webpack"] - path = tests/cases/user/webpack/webpack - url = https://github.com/webpack/webpack.git - ignore = all -[submodule "tests/cases/user/puppeteer/puppeteer"] - path = tests/cases/user/puppeteer/puppeteer - url = https://github.com/GoogleChrome/puppeteer.git - ignore = all -[submodule "tests/cases/user/axios-src/axios-src"] - path = tests/cases/user/axios-src/axios-src - url = https://github.com/axios/axios.git - ignore = all -[submodule "tests/cases/user/prettier/prettier"] - path = tests/cases/user/prettier/prettier - url = https://github.com/prettier/prettier.git - ignore = all diff --git a/src/testRunner/externalCompileRunner.ts b/src/testRunner/externalCompileRunner.ts index c9e800713c3..7698fc3f086 100644 --- a/src/testRunner/externalCompileRunner.ts +++ b/src/testRunner/externalCompileRunner.ts @@ -10,6 +10,7 @@ interface ExecResult { interface UserConfig { types: string[]; + cloneUrl: string; path?: string; } @@ -49,13 +50,17 @@ abstract class ExternalCompileRunnerBase extends RunnerBase { const stdio = isWorker ? "pipe" : "inherit"; let types: string[] | undefined; if (fs.existsSync(path.join(cwd, "test.json"))) { - const submoduleDir = path.join(cwd, directoryName); - exec("git", ["reset", "HEAD", "--hard"], { cwd: submoduleDir }); - exec("git", ["clean", "-f"], { cwd: submoduleDir }); - exec("git", ["submodule", "update", "--init", "--remote", "."], { cwd: originalCwd }); - const config = JSON.parse(fs.readFileSync(path.join(cwd, "test.json"), { encoding: "utf8" })) as UserConfig; ts.Debug.assert(!!config.types, "Bad format from test.json: Types field must be present."); + ts.Debug.assert(!!config.cloneUrl, "Bad format from test.json: cloneUrl field must be present."); + const submoduleDir = path.join(cwd, directoryName); + if (!fs.existsSync(submoduleDir)) { + exec("git", ["clone", config.cloneUrl, directoryName], { cwd }); + } + exec("git", ["reset", "HEAD", "--hard"], { cwd: submoduleDir }); + exec("git", ["clean", "-f"], { cwd: submoduleDir }); + exec("git", ["pull", "-f"], { cwd: submoduleDir }); + types = config.types; cwd = config.path ? path.join(cwd, config.path) : submoduleDir; diff --git a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter deleted file mode 160000 index ca14e7ccbca..00000000000 --- a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ca14e7ccbca8a821d3b860ebb6f3c81c68ccbd06 diff --git a/tests/cases/user/TypeScript-Node-Starter/test.json b/tests/cases/user/TypeScript-Node-Starter/test.json index 11d2aa87c59..c37bf34ad15 100644 --- a/tests/cases/user/TypeScript-Node-Starter/test.json +++ b/tests/cases/user/TypeScript-Node-Starter/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/Microsoft/TypeScript-Node-Starter.git", "types": ["jquery"] } diff --git a/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter b/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter deleted file mode 160000 index 30acce5e136..00000000000 --- a/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 30acce5e136e86bcf4eff1df151742f78142aa1a diff --git a/tests/cases/user/TypeScript-React-Native-Starter/test.json b/tests/cases/user/TypeScript-React-Native-Starter/test.json index cbe38c569ee..a87cd1ed89e 100644 --- a/tests/cases/user/TypeScript-React-Native-Starter/test.json +++ b/tests/cases/user/TypeScript-React-Native-Starter/test.json @@ -1,4 +1,5 @@ { + "cloneUrl": "https://github.com/Microsoft/TypeScript-React-Native-Starter.git", "types": ["jest"], "path": "TypeScript-React-Native-Starter/ExampleProject" } diff --git a/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter b/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter deleted file mode 160000 index 19c71f2c6a2..00000000000 --- a/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 19c71f2c6a2b874b1b2bb28a8526b19185b8eece diff --git a/tests/cases/user/TypeScript-React-Starter/test.json b/tests/cases/user/TypeScript-React-Starter/test.json index f3613bf3b01..caa97357cb7 100644 --- a/tests/cases/user/TypeScript-React-Starter/test.json +++ b/tests/cases/user/TypeScript-React-Starter/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/Microsoft/TypeScript-React-Starter", "types": ["jest", "node"] } diff --git a/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter b/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter deleted file mode 160000 index 56024cfe414..00000000000 --- a/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 56024cfe414491a9097e9dd33661a5ad5d51d975 diff --git a/tests/cases/user/TypeScript-Vue-Starter/test.json b/tests/cases/user/TypeScript-Vue-Starter/test.json index e0d4d26bdca..4504c4c1cd5 100644 --- a/tests/cases/user/TypeScript-Vue-Starter/test.json +++ b/tests/cases/user/TypeScript-Vue-Starter/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/Microsoft/TypeScript-Vue-Starter.git", "types": [] } diff --git a/tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter b/tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter deleted file mode 160000 index 3fb8b460102..00000000000 --- a/tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3fb8b4601022f7e2df899eb0ac0178f531e6f027 diff --git a/tests/cases/user/TypeScript-WeChat-Starter/test.json b/tests/cases/user/TypeScript-WeChat-Starter/test.json index e0d4d26bdca..92c47595d1a 100644 --- a/tests/cases/user/TypeScript-WeChat-Starter/test.json +++ b/tests/cases/user/TypeScript-WeChat-Starter/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/Microsoft/TypeScript-React-Starter", "types": [] } diff --git a/tests/cases/user/axios-src/axios-src b/tests/cases/user/axios-src/axios-src deleted file mode 160000 index d74385f1c8f..00000000000 --- a/tests/cases/user/axios-src/axios-src +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d74385f1c8f944a6d94ae0680d3841859a2fcb38 diff --git a/tests/cases/user/axios-src/test.json b/tests/cases/user/axios-src/test.json index b6495a1b80b..36c01c495bd 100644 --- a/tests/cases/user/axios-src/test.json +++ b/tests/cases/user/axios-src/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/axios/axios.git", "types": ["node"] } diff --git a/tests/cases/user/create-react-app/create-react-app b/tests/cases/user/create-react-app/create-react-app deleted file mode 160000 index 74eb65a4626..00000000000 --- a/tests/cases/user/create-react-app/create-react-app +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 74eb65a46269d5c2cc5483841e271281477c650e diff --git a/tests/cases/user/create-react-app/test.json b/tests/cases/user/create-react-app/test.json index e0d4d26bdca..98888de7fdb 100644 --- a/tests/cases/user/create-react-app/test.json +++ b/tests/cases/user/create-react-app/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/facebook/create-react-app.git", "types": [] } diff --git a/tests/cases/user/prettier/prettier b/tests/cases/user/prettier/prettier deleted file mode 160000 index e83b4537fea..00000000000 --- a/tests/cases/user/prettier/prettier +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e83b4537feaa6c063a1598b8d3972b6ad600f2a7 diff --git a/tests/cases/user/prettier/test.json b/tests/cases/user/prettier/test.json index b6495a1b80b..7b041238424 100644 --- a/tests/cases/user/prettier/test.json +++ b/tests/cases/user/prettier/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/prettier/prettier.git", "types": ["node"] } diff --git a/tests/cases/user/puppeteer/puppeteer b/tests/cases/user/puppeteer/puppeteer deleted file mode 160000 index a5f03ce1c85..00000000000 --- a/tests/cases/user/puppeteer/puppeteer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a5f03ce1c85c2630739f2a894a303c68632aa250 diff --git a/tests/cases/user/puppeteer/test.json b/tests/cases/user/puppeteer/test.json index e0d4d26bdca..f2e61aca5f9 100644 --- a/tests/cases/user/puppeteer/test.json +++ b/tests/cases/user/puppeteer/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/GoogleChrome/puppeteer.git", "types": [] } diff --git a/tests/cases/user/webpack/test.json b/tests/cases/user/webpack/test.json index e0d4d26bdca..a3fcf317a74 100644 --- a/tests/cases/user/webpack/test.json +++ b/tests/cases/user/webpack/test.json @@ -1,3 +1,4 @@ { + "cloneUrl": "https://github.com/webpack/webpack.git", "types": [] } diff --git a/tests/cases/user/webpack/webpack b/tests/cases/user/webpack/webpack deleted file mode 160000 index e4c7d8c0ae0..00000000000 --- a/tests/cases/user/webpack/webpack +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e4c7d8c0ae0c93306f07920bc28fe72119bc098a From cc6e4938aedaa017a999c4c53bd5e560999f6fde Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Sep 2019 15:30:09 -0700 Subject: [PATCH 047/100] Treat exhaustive switch statements like non-returning functions in CFA --- src/compiler/binder.ts | 7 +++++-- src/compiler/checker.ts | 39 +++++++++++++++++++++++++-------------- src/compiler/types.ts | 3 ++- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index bb3b7b10508..e93fef838e8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -569,7 +569,7 @@ namespace ts { } // We create a return control flow graph for IIFEs and constructors. For constructors // we use the return control flow graph in strict property initialization checks. - currentReturnTarget = containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((node).body) ? createBranchLabel() : undefined; + currentReturnTarget = isIIFE || node.kind === SyntaxKind.Constructor ? createBranchLabel() : undefined; currentBreakTarget = undefined; currentContinueTarget = undefined; activeLabels = undefined; @@ -581,6 +581,7 @@ namespace ts { if (!(currentFlow.flags & FlowFlags.Unreachable) && containerFlags & ContainerFlags.IsFunctionLike && nodeIsPresent((node).body)) { node.flags |= NodeFlags.HasImplicitReturn; if (hasExplicitReturn) node.flags |= NodeFlags.HasExplicitReturn; + (node).endFlowNode = currentFlow; } if (node.kind === SyntaxKind.SourceFile) { node.flags |= emitFlags; @@ -589,7 +590,9 @@ namespace ts { if (currentReturnTarget) { addAntecedent(currentReturnTarget, currentFlow); currentFlow = finishFlowLabel(currentReturnTarget); - (node).returnFlowNode = currentFlow; + if (node.kind === SyntaxKind.Constructor) { + (node).returnFlowNode = currentFlow; + } } if (!isIIFE) { currentFlow = saveCurrentFlow; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5e491b2e730..0d9397eb6b3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16996,16 +16996,19 @@ namespace ts { return isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false); } - function isReachableFlowNodeWorker(flow: FlowNode, skipCacheCheck: boolean): boolean { + function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean { while (true) { const flags = flow.flags; - if (flags & FlowFlags.Shared && !skipCacheCheck) { - const id = getFlowNodeId(flow); - const reachable = flowNodeReachable[id]; - return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ true)); + if (flags & FlowFlags.Shared | flags & FlowFlags.SwitchClause) { + if (!noCacheCheck) { + const id = getFlowNodeId(flow); + const reachable = flowNodeReachable[id]; + return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ true)); + } + noCacheCheck = false; } - if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.SwitchClause | FlowFlags.ArrayMutation | FlowFlags.PreFinally | FlowFlags.AfterFinally)) { - flow = (flow).antecedent; + if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation | FlowFlags.PreFinally | FlowFlags.AfterFinally)) { + flow = (flow).antecedent; } else if (flags & FlowFlags.Call) { const signature = getEffectsSignature((flow).node); @@ -17014,14 +17017,20 @@ namespace ts { } flow = (flow).antecedent; } + else if (flags & FlowFlags.BranchLabel) { + return some((flow).antecedents!, isReachableFlowNode); + } else if (flags & FlowFlags.LoopLabel) { flow = (flow).antecedents![0]; } - else if (flags & FlowFlags.BranchLabel) { - return every((flow).antecedents!, isReachableFlowNode); + else if (flags & FlowFlags.SwitchClause) { + if ((flow).clauseStart === (flow).clauseEnd && isExhaustiveSwitchStatement((flow).switchStatement)) { + return false; + } + flow = (flow).antecedent; } else { - return true; + return !(flags & FlowFlags.Unreachable); } } } @@ -17044,7 +17053,11 @@ namespace ts { // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + if (resultType === unreachableNeverType) { + error(reference, Diagnostics.Unreachable_code_detected); + return declaredType; + } + if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } return resultType; @@ -23804,9 +23817,7 @@ namespace ts { } function functionHasImplicitReturn(func: FunctionLikeDeclaration) { - return !!(func.flags & NodeFlags.HasImplicitReturn && - !some((func.body).statements, s => s.kind === SyntaxKind.SwitchStatement && isExhaustiveSwitchStatement(s)) && - !(func.returnFlowNode && !isReachableFlowNode(func.returnFlowNode))); + return func.endFlowNode && isReachableFlowNode(func.endFlowNode); } /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */ diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 214c2d58788..3ba88e3e45d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1040,7 +1040,7 @@ namespace ts { questionToken?: QuestionToken; exclamationToken?: ExclamationToken; body?: Block | Expression; - /* @internal */ returnFlowNode?: FlowNode; + /* @internal */ endFlowNode?: FlowNode; } export type FunctionLikeDeclaration = @@ -1086,6 +1086,7 @@ namespace ts { kind: SyntaxKind.Constructor; parent: ClassLikeDeclaration; body?: FunctionBody; + /* @internal */ returnFlowNode?: FlowNode; } /** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */ From 0060964fba457f83eb77c48b60909e23184b59d7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 15 Sep 2019 08:25:07 -0700 Subject: [PATCH 048/100] Further CFA handling of exhaustive switch statements --- src/compiler/binder.ts | 3 ++- src/compiler/checker.ts | 17 +++++++++++++---- src/compiler/types.ts | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e93fef838e8..6efc4ae05b0 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1224,7 +1224,8 @@ namespace ts { addAntecedent(postSwitchLabel, currentFlow); const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); // We mark a switch statement as possibly exhaustive if it has no default clause and if all - // case clauses have unreachable end points (e.g. they all return). + // case clauses have unreachable end points (e.g. they all return). Note, we no longer need + // this property in control flow analysis, it's there only for backwards compatibility. node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents; if (!hasDefault) { addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0)); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0d9397eb6b3..e5204350742 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16999,7 +16999,7 @@ namespace ts { function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean { while (true) { const flags = flow.flags; - if (flags & FlowFlags.Shared | flags & FlowFlags.SwitchClause) { + if (flags & FlowFlags.Shared) { if (!noCacheCheck) { const id = getFlowNodeId(flow); const reachable = flowNodeReachable[id]; @@ -17018,12 +17018,16 @@ namespace ts { flow = (flow).antecedent; } else if (flags & FlowFlags.BranchLabel) { + // A branching point is reachable if any branch is reachable. return some((flow).antecedents!, isReachableFlowNode); } else if (flags & FlowFlags.LoopLabel) { + // A loop is reachable if the control flow path that leads to the top is reachable. flow = (flow).antecedents![0]; } else if (flags & FlowFlags.SwitchClause) { + // The control flow path representing an unmatched value in a switch statement with + // no default clause is unreachable if the switch statement is exhaustive. if ((flow).clauseStart === (flow).clauseEnd && isExhaustiveSwitchStatement((flow).switchStatement)) { return false; } @@ -17327,6 +17331,9 @@ namespace ts { } function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType { + if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement((flow).switchStatement)) { + return neverType; + } const expr = flow.switchStatement.expression; const flowType = getTypeAtFlowNode(flow.antecedent); let type = getTypeFromFlowType(flowType); @@ -23793,9 +23800,11 @@ namespace ts { } function isExhaustiveSwitchStatement(node: SwitchStatement): boolean { - if (!node.possiblyExhaustive) { - return false; - } + const links = getNodeLinks(node); + return links.isExhaustive !== undefined ? links.isExhaustive : (links.isExhaustive = computeExhaustiveSwitchStatement(node)); + } + + function computeExhaustiveSwitchStatement(node: SwitchStatement): boolean { if (node.expression.kind === SyntaxKind.TypeOfExpression) { const operandType = getTypeOfExpression((node.expression as TypeOfExpression).expression); // This cast is safe because the switch is possibly exhaustive and does not contain a default case, so there can be no undefined. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3ba88e3e45d..f80126b64c5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4016,6 +4016,7 @@ namespace ts { contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive deferredNodes?: Map; // Set of nodes whose checking has been deferred capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement + isExhaustive?: boolean; // Is node an exhaustive switch statement } export const enum TypeFlags { From 51dcce212498a8cb8f6a8ca3d846501252f649fa Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 15 Sep 2019 08:28:17 -0700 Subject: [PATCH 049/100] Accept new baselines --- tests/baselines/reference/narrowingByTypeofInSwitch.types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.types b/tests/baselines/reference/narrowingByTypeofInSwitch.types index f823c57770c..fbfe7fe92ee 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.types +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.types @@ -208,7 +208,7 @@ function testExtendsUnion(x: T) { assertAll(x); >assertAll(x) : Basic >assertAll : (x: Basic) => Basic ->x : T +>x : never } function testAny(x: any) { From 59b76cee89254dba2dd36abea850ecd9e578f3c7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 15 Sep 2019 08:38:17 -0700 Subject: [PATCH 050/100] Fix call to Debug.fail in compiler --- src/compiler/checker.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e5204350742..58b6d2e4ceb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31531,8 +31531,7 @@ namespace ts { const nameType = checkComputedPropertyName(name); return isTypeAssignableToKind(nameType, TypeFlags.ESSymbolLike) ? nameType : stringType; default: - Debug.fail("Unsupported property name."); - return errorType; + return Debug.fail("Unsupported property name."); } } From 945babbaacb0cbb09c39f554c4141bed9647a9c0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 15 Sep 2019 09:49:57 -0700 Subject: [PATCH 051/100] Fix inference circularity error triggered by exhaustive switch analysis --- src/compiler/transformers/generators.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 3b1a8379e07..cc16aef6009 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -2871,7 +2871,7 @@ namespace ts { function tryEnterOrLeaveBlock(operationIndex: number): void { if (blocks) { for (; blockIndex < blockActions!.length && blockOffsets![blockIndex] <= operationIndex; blockIndex++) { - const block = blocks[blockIndex]; + const block: CodeBlock = blocks[blockIndex]; const blockAction = blockActions![blockIndex]; switch (block.kind) { case CodeBlockKind.Exception: From d26afd7273c8aabfb92157df55eadbc907c6fb65 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 15 Sep 2019 11:07:51 -0700 Subject: [PATCH 052/100] for-in or for-of expression is evaluated before loop back edge --- src/compiler/binder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6efc4ae05b0..5006e841dc7 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1032,12 +1032,12 @@ namespace ts { function bindForInOrForOfStatement(node: ForInOrOfStatement): void { const preLoopLabel = createLoopLabel(); const postLoopLabel = createBranchLabel(); + bind(node.expression); addAntecedent(preLoopLabel, currentFlow); currentFlow = preLoopLabel; if (node.kind === SyntaxKind.ForOfStatement) { bind(node.awaitModifier); } - bind(node.expression); addAntecedent(postLoopLabel, currentFlow); bind(node.initializer); if (node.initializer.kind !== SyntaxKind.VariableDeclarationList) { From 05d1e68e6296d1b951010e8bad6168b88cef05f1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 15 Sep 2019 18:13:49 -0700 Subject: [PATCH 053/100] Fix linting issues --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 58b6d2e4ceb..ba06e08a301 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17019,7 +17019,7 @@ namespace ts { } else if (flags & FlowFlags.BranchLabel) { // A branching point is reachable if any branch is reachable. - return some((flow).antecedents!, isReachableFlowNode); + return some((flow).antecedents, isReachableFlowNode); } else if (flags & FlowFlags.LoopLabel) { // A loop is reachable if the control flow path that leads to the top is reachable. @@ -17331,7 +17331,7 @@ namespace ts { } function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType { - if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement((flow).switchStatement)) { + if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) { return neverType; } const expr = flow.switchStatement.expression; From f06f32d945bc5a07a443840ddccc7838a9a49125 Mon Sep 17 00:00:00 2001 From: typescript-bot Date: Mon, 16 Sep 2019 14:10:30 +0000 Subject: [PATCH 054/100] Update user baselines --- .../baselines/reference/docker/azure-sdk.log | 4 +- .../reference/docker/office-ui-fabric.log | 27 ++++- .../user/TypeScript-WeChat-Starter.log | 17 +++ tests/baselines/reference/user/axios-src.log | 22 ++-- tests/baselines/reference/user/jimp.log | 47 +++++++- tests/baselines/reference/user/prettier.log | 114 ++++++++++-------- 6 files changed, 166 insertions(+), 65 deletions(-) create mode 100644 tests/baselines/reference/user/TypeScript-WeChat-Starter.log diff --git a/tests/baselines/reference/docker/azure-sdk.log b/tests/baselines/reference/docker/azure-sdk.log index ad0dbf4e9d6..347a6c188a9 100644 --- a/tests/baselines/reference/docker/azure-sdk.log +++ b/tests/baselines/reference/docker/azure-sdk.log @@ -24,7 +24,7 @@ Warning: You have changed the public API signature for this project. Updating re dist-esm/index.js → dist/index.js... (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency -tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js) +tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) @azure/cosmos-sign (imported by dist-esm/auth.js) universal-user-agent (imported by dist-esm/common/platform.js) uuid/v4 (imported by dist-esm/ClientContext.js, dist-esm/client/Item/Items.js) @@ -96,7 +96,7 @@ Warning: You have changed the public API signature for this project. Updating re dist-esm/index.js → dist/index.js... (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency -tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js) +tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) @azure/cosmos-sign (imported by dist-esm/auth.js) universal-user-agent (imported by dist-esm/common/platform.js) uuid/v4 (imported by dist-esm/ClientContext.js, dist-esm/client/Item/Items.js) diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index 67398753776..56cc33c98c6 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -164,6 +164,26 @@ Standard output: @uifabric/utilities: PASS src/keyboard.test.ts @uifabric/utilities: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/utilities/lib/index.d.ts' @uifabric/utilities: Done in ?s. +@uifabric/react-hooks: yarn run vX.X.X +@uifabric/react-hooks: $ just-scripts build --production --lint +@uifabric/react-hooks: [XX:XX:XX XM] ■ Removing [lib, temp, dist, lib-amd, lib-commonjs, lib-es2015, coverage, src/**/*.scss.ts] +@uifabric/react-hooks: [XX:XX:XX XM] ■ Running tslint +@uifabric/react-hooks: [XX:XX:XX XM] ■ /usr/local/bin/node "/office-ui-fabric-react/node_modules/tslint/lib/tslintCli.js" --project "/office-ui-fabric-react/packages/react-hooks/tsconfig.json" -t stylish -r /office-ui-fabric-react/node_modules/tslint-microsoft-contrib +@uifabric/react-hooks: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/react-hooks/tsconfig.json +@uifabric/react-hooks: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib-commonjs --module commonjs --project "/office-ui-fabric-react/packages/react-hooks/tsconfig.json" +@uifabric/react-hooks: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/react-hooks/tsconfig.json +@uifabric/react-hooks: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib --module esnext --project "/office-ui-fabric-react/packages/react-hooks/tsconfig.json" +@uifabric/react-hooks: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/react-hooks/tsconfig.json +@uifabric/react-hooks: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib-amd --module amd --project "/office-ui-fabric-react/packages/react-hooks/tsconfig.json" +@uifabric/react-hooks: [XX:XX:XX XM] ■ Running Jest +@uifabric/react-hooks: [XX:XX:XX XM] ■ /usr/local/bin/node "/office-ui-fabric-react/node_modules/jest/bin/jest.js" --config "/office-ui-fabric-react/packages/react-hooks/jest.config.js" --passWithNoTests --colors --forceExit +@uifabric/react-hooks: [XX:XX:XX XM] ■ Running Webpack +@uifabric/react-hooks: [XX:XX:XX XM] ■ Webpack Config Path: /office-ui-fabric-react/packages/react-hooks/webpack.config.js +@uifabric/react-hooks: Webpack version: 4.29.5 +@uifabric/react-hooks: PASS src/useConst.test.tsx +@uifabric/react-hooks: PASS src/useId.test.tsx +@uifabric/react-hooks: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/react-hooks/lib/index.d.ts' +@uifabric/react-hooks: Done in ?s. @uifabric/styling: yarn run vX.X.X @uifabric/styling: $ just-scripts build --production --lint @uifabric/styling: [XX:XX:XX XM] ■ Removing [lib, temp, dist, lib-amd, lib-commonjs, lib-es2015, coverage, src/**/*.scss.ts] @@ -226,7 +246,7 @@ Standard output: Standard error: info cli using local version of lerna lerna notice cli vX.X.X -lerna info Executing command in 42 packages: "yarn run build --production --lint" +lerna info Executing command in 43 packages: "yarn run build --production --lint" @uifabric/codepen-loader: ts-jest[versions] (WARN) Version X.X.X-insiders.xxxxxxxx of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=2.7.0 <4.0.0). Please do not report issues in ts-jest if you are using unsupported versions. @uifabric/codepen-loader: Force exiting Jest @uifabric/codepen-loader: @@ -247,6 +267,11 @@ lerna info Executing command in 42 packages: "yarn run build --production --lint @uifabric/utilities: Force exiting Jest @uifabric/utilities: @uifabric/utilities: Have you considered using `--detectOpenHandles` to detect async operations that kept running after all tests finished? +@uifabric/react-hooks: [XX:XX:XX XM] ▲ One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect +@uifabric/react-hooks: ts-jest[versions] (WARN) Version X.X.X-insiders.xxxxxxxx of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=2.7.0 <4.0.0). Please do not report issues in ts-jest if you are using unsupported versions. +@uifabric/react-hooks: Force exiting Jest +@uifabric/react-hooks: +@uifabric/react-hooks: Have you considered using `--detectOpenHandles` to detect async operations that kept running after all tests finished? @uifabric/styling: [XX:XX:XX XM] ▲ One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect @uifabric/styling: ts-jest[versions] (WARN) Version X.X.X-insiders.xxxxxxxx of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=2.7.0 <4.0.0). Please do not report issues in ts-jest if you are using unsupported versions. @uifabric/styling: Force exiting Jest diff --git a/tests/baselines/reference/user/TypeScript-WeChat-Starter.log b/tests/baselines/reference/user/TypeScript-WeChat-Starter.log new file mode 100644 index 00000000000..825eae70a53 --- /dev/null +++ b/tests/baselines/reference/user/TypeScript-WeChat-Starter.log @@ -0,0 +1,17 @@ +Exit Code: 1 +Standard output: +src/App.test.tsx(5,1): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +src/components/Hello.test.tsx(5,1): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +src/components/Hello.test.tsx(7,3): error TS2304: Cannot find name 'expect'. +src/components/Hello.test.tsx(10,1): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +src/components/Hello.test.tsx(12,3): error TS2304: Cannot find name 'expect'. +src/components/Hello.test.tsx(15,1): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +src/components/Hello.test.tsx(17,3): error TS2304: Cannot find name 'expect'. +src/components/Hello.test.tsx(20,1): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +src/components/Hello.test.tsx(21,3): error TS2304: Cannot find name 'expect'. +src/components/Hello.test.tsx(26,1): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +src/components/Hello.test.tsx(27,3): error TS2304: Cannot find name 'expect'. + + + +Standard error: diff --git a/tests/baselines/reference/user/axios-src.log b/tests/baselines/reference/user/axios-src.log index adc8d7e0a48..d24af763712 100644 --- a/tests/baselines/reference/user/axios-src.log +++ b/tests/baselines/reference/user/axios-src.log @@ -1,18 +1,18 @@ Exit Code: 1 Standard output: lib/adapters/http.js(13,19): error TS2732: Cannot find module './../../package.json'. Consider using '--resolveJsonModule' to import module with '.json' extension -lib/adapters/http.js(87,22): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. +lib/adapters/http.js(84,22): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'. -lib/adapters/http.js(123,17): error TS2532: Object is possibly 'undefined'. -lib/adapters/http.js(123,40): error TS2532: Object is possibly 'undefined'. -lib/adapters/http.js(124,17): error TS2531: Object is possibly 'null'. -lib/adapters/http.js(124,54): error TS2531: Object is possibly 'null'. -lib/adapters/http.js(124,54): error TS2532: Object is possibly 'undefined'. -lib/adapters/http.js(223,23): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. -lib/adapters/http.js(229,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. -lib/adapters/http.js(235,13): error TS2322: Type 'string' is not assignable to type 'Buffer'. -lib/adapters/http.js(247,40): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. -lib/adapters/http.js(271,42): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(120,17): error TS2532: Object is possibly 'undefined'. +lib/adapters/http.js(120,40): error TS2532: Object is possibly 'undefined'. +lib/adapters/http.js(121,17): error TS2531: Object is possibly 'null'. +lib/adapters/http.js(121,54): error TS2531: Object is possibly 'null'. +lib/adapters/http.js(121,54): error TS2532: Object is possibly 'undefined'. +lib/adapters/http.js(220,23): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(226,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(232,13): error TS2322: Type 'string' is not assignable to type 'Buffer'. +lib/adapters/http.js(244,40): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(273,42): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. lib/adapters/xhr.js(64,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. lib/adapters/xhr.js(76,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. lib/adapters/xhr.js(83,51): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. diff --git a/tests/baselines/reference/user/jimp.log b/tests/baselines/reference/user/jimp.log index d9a47363e22..8aa96e8bb82 100644 --- a/tests/baselines/reference/user/jimp.log +++ b/tests/baselines/reference/user/jimp.log @@ -1,6 +1,51 @@ Exit Code: 1 Standard output: -index.ts(1,23): error TS2307: Cannot find module 'jimp'. +node_modules/@jimp/bmp/index.d.ts(1,38): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/gif/index.d.ts(1,27): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/jpeg/index.d.ts(1,59): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-blit/index.d.ts(1,54): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-blur/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-color/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-contain/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-cover/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-crop/index.d.ts(1,37): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-displace/index.d.ts(1,54): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-dither/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-flip/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-gaussian/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-invert/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-mask/index.d.ts(1,54): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-normalize/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-print/index.d.ts(1,54): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-resize/index.d.ts(1,37): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-rotate/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/plugin-scale/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/png/index.d.ts(1,59): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/@jimp/tiff/index.d.ts(1,38): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` +node_modules/jimp/types/ts3.1/index.d.ts(16,8): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. + Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log index 743c7a71167..93ccd99a0d6 100644 --- a/tests/baselines/reference/user/prettier.log +++ b/tests/baselines/reference/user/prettier.log @@ -55,16 +55,18 @@ src/doc/doc-printer.js(501,37): error TS2345: Argument of type 'any[][]' is not src/index.js(3,25): error TS2732: Cannot find module '../package.json'. Consider using '--resolveJsonModule' to import module with '.json' extension src/index.js(30,17): error TS2339: Property 'sync' does not exist on type '(...args: any[]) => any'. src/language-css/clean.js(3,30): error TS2307: Cannot find module 'html-tag-names'. -src/language-css/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/css'. -src/language-css/index.js(8,58): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-css/index.js(15,26): error TS2307: Cannot find module 'linguist-languages/data/postcss'. -src/language-css/index.js(25,26): error TS2307: Cannot find module 'linguist-languages/data/less'. -src/language-css/index.js(25,59): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-css/index.js(32,26): error TS2307: Cannot find module 'linguist-languages/data/scss'. -src/language-css/index.js(32,59): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. +src/language-css/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/CSS'. +src/language-css/index.js(8,58): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-css/index.js(15,26): error TS2307: Cannot find module 'linguist-languages/data/PostCSS'. +src/language-css/index.js(15,62): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { extensions: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Property 'exclude' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { extensions: string[]; }; }' but required in type '{ extend: any; override: any; exclude: any; }'. +src/language-css/index.js(25,26): error TS2307: Cannot find module 'linguist-languages/data/Less'. +src/language-css/index.js(25,59): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-css/index.js(32,26): error TS2307: Cannot find module 'linguist-languages/data/SCSS'. +src/language-css/index.js(32,59): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude src/language-css/parser-postcss.js(64,32): error TS2345: Argument of type '{ groups: never[]; type: string; }' is not assignable to parameter of type 'never'. src/language-css/parser-postcss.js(74,30): error TS2345: Argument of type '{ open: null; close: null; groups: never[]; type: string; }' is not assignable to parameter of type 'never'. src/language-css/parser-postcss.js(79,30): error TS2345: Argument of type '{ groups: never[]; type: string; }' is not assignable to parameter of type 'never'. @@ -72,12 +74,12 @@ src/language-css/parser-postcss.js(86,30): error TS2345: Argument of type 'any' src/language-css/parser-postcss.js(90,28): error TS2345: Argument of type '{ groups: never[]; type: string; }' is not assignable to parameter of type 'never'. src/language-css/parser-postcss.js(449,32): error TS2531: Object is possibly 'null'. src/language-css/utils.js(3,30): error TS2307: Cannot find module 'html-tag-names'. -src/language-graphql/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/graphql'. -src/language-graphql/index.js(8,62): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-handlebars/index.js(7,26): error TS2307: Cannot find module 'linguist-languages/data/handlebars'. -src/language-handlebars/index.js(7,65): error TS2345: Argument of type '{ override: { since: null; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: null; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. +src/language-graphql/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/GraphQL'. +src/language-graphql/index.js(8,62): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-handlebars/index.js(7,26): error TS2307: Cannot find module 'linguist-languages/data/Handlebars'. +src/language-handlebars/index.js(7,65): error TS2345: Argument of type '{ override: { since: null; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: null; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude src/language-html/ast.js(53,11): error TS2536: Type 'Extract' cannot be used to index type 'Node'. src/language-html/ast.js(56,15): error TS2339: Property 'index' does not exist on type 'Node'. src/language-html/ast.js(56,22): error TS2339: Property 'siblings' does not exist on type 'Node'. @@ -100,16 +102,18 @@ src/language-html/ast.js(90,69): error TS2339: Property 'name' does not exist on src/language-html/conditional-comment.js(23,16): error TS2349: This expression is not callable. Not all constituents of type 'RegExp | ((node: any) => { type: string; sourceSpan: any; })' are callable. Type 'RegExp' has no call signatures. -src/language-html/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/html'. -src/language-html/index.js(8,59): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: string[]; filenames: never[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: string[]; filenames: never[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-html/index.js(19,26): error TS2307: Cannot find module 'linguist-languages/data/html'. -src/language-html/index.js(31,26): error TS2307: Cannot find module 'linguist-languages/data/html'. -src/language-html/index.js(31,59): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: never[]; filenames: never[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: never[]; filenames: never[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-html/index.js(42,26): error TS2307: Cannot find module 'linguist-languages/data/vue'. -src/language-html/index.js(42,58): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. +src/language-html/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/HTML'. +src/language-html/index.js(8,59): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: string[]; filenames: never[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: string[]; filenames: never[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-html/index.js(19,26): error TS2307: Cannot find module 'linguist-languages/data/HTML'. +src/language-html/index.js(19,59): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { extensions: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Property 'exclude' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { extensions: string[]; }; }' but required in type '{ extend: any; override: any; exclude: any; }'. +src/language-html/index.js(31,26): error TS2307: Cannot find module 'linguist-languages/data/HTML'. +src/language-html/index.js(31,59): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: never[]; filenames: never[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: never[]; filenames: never[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-html/index.js(42,26): error TS2307: Cannot find module 'linguist-languages/data/Vue'. +src/language-html/index.js(42,58): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude src/language-html/parser-html.js(52,12): error TS2339: Property 'type' does not exist on type 'Attribute'. src/language-html/parser-html.js(54,12): error TS2339: Property 'type' does not exist on type 'CDATA'. src/language-html/parser-html.js(56,12): error TS2339: Property 'type' does not exist on type 'Comment'. @@ -166,24 +170,33 @@ src/language-html/utils.js(10,30): error TS2307: Cannot find module 'html-tag-na src/language-html/utils.js(11,39): error TS2307: Cannot find module 'html-element-attributes'. src/language-html/utils.js(444,17): error TS2554: Expected 0 arguments, but got 1. src/language-js/comments.js(864,64): error TS2554: Expected 0 arguments, but got 1. -src/language-js/index.js(9,26): error TS2307: Cannot find module 'linguist-languages/data/javascript'. -src/language-js/index.js(19,26): error TS2307: Cannot find module 'linguist-languages/data/javascript'. -src/language-js/index.js(19,65): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; aliases: never[]; filenames: never[]; extensions: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; aliases: never[]; filenames: never[]; extensions: string[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-js/index.js(31,26): error TS2307: Cannot find module 'linguist-languages/data/jsx'. -src/language-js/index.js(31,58): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-js/index.js(38,26): error TS2307: Cannot find module 'linguist-languages/data/typescript'. -src/language-js/index.js(38,65): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-js/index.js(45,26): error TS2307: Cannot find module 'linguist-languages/data/json'. -src/language-js/index.js(45,59): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: never[]; filenames: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: never[]; filenames: string[]; }; }' but required in type '{ extend: any; override: any; }'. -src/language-js/index.js(56,26): error TS2307: Cannot find module 'linguist-languages/data/json'. -src/language-js/index.js(66,26): error TS2307: Cannot find module 'linguist-languages/data/json-with-comments'. -src/language-js/index.js(76,26): error TS2307: Cannot find module 'linguist-languages/data/json5'. -src/language-js/index.js(76,60): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. +src/language-js/index.js(9,26): error TS2307: Cannot find module 'linguist-languages/data/JavaScript'. +src/language-js/index.js(9,65): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { interpreters: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Property 'exclude' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { interpreters: string[]; }; }' but required in type '{ extend: any; override: any; exclude: any; }'. +src/language-js/index.js(19,26): error TS2307: Cannot find module 'linguist-languages/data/JavaScript'. +src/language-js/index.js(19,65): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; aliases: never[]; filenames: never[]; extensions: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; aliases: never[]; filenames: never[]; extensions: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-js/index.js(30,26): error TS2307: Cannot find module 'linguist-languages/data/JSX'. +src/language-js/index.js(30,58): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-js/index.js(37,26): error TS2307: Cannot find module 'linguist-languages/data/TypeScript'. +src/language-js/index.js(37,65): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-js/index.js(44,26): error TS2307: Cannot find module 'linguist-languages/data/TSX'. +src/language-js/index.js(44,58): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-js/index.js(51,26): error TS2307: Cannot find module 'linguist-languages/data/JSON'. +src/language-js/index.js(51,59): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: never[]; filenames: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; extensions: never[]; filenames: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude +src/language-js/index.js(61,26): error TS2307: Cannot find module 'linguist-languages/data/JSON'. +src/language-js/index.js(61,59): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { filenames: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Property 'exclude' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { filenames: string[]; }; }' but required in type '{ extend: any; override: any; exclude: any; }'. +src/language-js/index.js(71,26): error TS2307: Cannot find module 'linguist-languages/data/JSON with Comments'. +src/language-js/index.js(71,73): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { filenames: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Property 'exclude' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { filenames: string[]; }; }' but required in type '{ extend: any; override: any; exclude: any; }'. +src/language-js/index.js(81,26): error TS2307: Cannot find module 'linguist-languages/data/JSON5'. +src/language-js/index.js(81,60): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude src/language-js/needs-parens.js(871,14): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<(childPath: any) => any>[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type 'ConcatArray<(childPath: any) => any>'. @@ -260,17 +273,18 @@ src/language-js/printer-estree.js(6130,7): error TS2769: No overload matches thi Argument of type '(string | number)[]' is not assignable to parameter of type '((childPath: any) => any) | ConcatArray<(childPath: any) => any>'. Type '(string | number)[]' is not assignable to type 'ConcatArray<(childPath: any) => any>'. src/language-js/utils.js(107,55): error TS2554: Expected 0-1 arguments, but got 2. -src/language-markdown/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/markdown'. -src/language-markdown/index.js(20,5): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. +src/language-markdown/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/Markdown'. +src/language-markdown/index.js(21,26): error TS2307: Cannot find module 'linguist-languages/data/Markdown'. +src/language-markdown/index.js(21,63): error TS2345: Argument of type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; filenames: never[]; extensions: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { name: string; since: string; parsers: string[]; vscodeLanguageIds: string[]; filenames: never[]; extensions: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude src/language-markdown/printer-markdown.js(278,18): error TS2532: Object is possibly 'undefined'. src/language-markdown/printer-markdown.js(279,17): error TS2532: Object is possibly 'undefined'. src/language-markdown/printer-markdown.js(300,14): error TS2532: Object is possibly 'undefined'. src/language-markdown/utils.js(203,5): error TS2322: Type 'never[]' is not assignable to type 'null'. src/language-markdown/utils.js(213,47): error TS2345: Argument of type 'any[]' is not assignable to parameter of type 'null'. -src/language-yaml/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/yaml'. -src/language-yaml/index.js(8,59): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; }'. - Property 'extend' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' but required in type '{ extend: any; override: any; }'. +src/language-yaml/index.js(8,26): error TS2307: Cannot find module 'linguist-languages/data/YAML'. +src/language-yaml/index.js(8,59): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. + Type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; }' is missing the following properties from type '{ extend: any; override: any; exclude: any; }': extend, exclude src/language-yaml/printer-yaml.js(226,41): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type '"" | { type: string; parts: any; }' is not assignable to parameter of type 'ConcatArray'. From e97ebb7f1c6ee93ce3ed6a4f996e54f346a0ff44 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 16 Sep 2019 13:04:22 -0700 Subject: [PATCH 055/100] More efficient scheme for caching flow node reachability --- src/compiler/checker.ts | 20 ++++++++++++++------ src/compiler/types.ts | 4 ++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ba06e08a301..c49ef71c19d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6,6 +6,7 @@ namespace ts { let nextNodeId = 1; let nextMergeId = 1; let nextFlowId = 1; + let nextCheckerId = 1; const enum IterationUse { AllowsSyncIterablesFlag = 1 << 0, @@ -298,6 +299,7 @@ namespace ts { let instantiationDepth = 0; let constraintDepth = 0; let currentNode: Node | undefined; + let checkerId: number; const emptySymbols = createSymbolTable(); const identityMapper: (type: Type) => Type = identity; @@ -842,7 +844,6 @@ namespace ts { const flowLoopTypes: Type[][] = []; const sharedFlowNodes: FlowNode[] = []; const sharedFlowTypes: FlowType[] = []; - const flowNodeReachable: (boolean | undefined)[] = []; const potentialThisCollisions: Node[] = []; const potentialNewTargetCollisions: Node[] = []; const awaitedTypeStack: number[] = []; @@ -16993,17 +16994,21 @@ namespace ts { } function isReachableFlowNode(flow: FlowNode) { - return isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false); + return isReachableFlowNodeWorker(flow, /*noCacheCheck*/ false); } function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean { while (true) { const flags = flow.flags; - if (flags & FlowFlags.Shared) { + if (flags & (FlowFlags.Shared | FlowFlags.Assignment | FlowFlags.Label)) { if (!noCacheCheck) { - const id = getFlowNodeId(flow); - const reachable = flowNodeReachable[id]; - return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ true)); + if (flow.checkerId === checkerId) { + return !!(flow.flags & FlowFlags.Reachable); + } + const reachable = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ true); + flow.checkerId = checkerId; + flow.flags = (flow.flags & ~FlowFlags.Reachable) | (reachable ? FlowFlags.Reachable : 0); + return reachable; } noCacheCheck = false; } @@ -32287,6 +32292,9 @@ namespace ts { } function initializeTypeChecker() { + checkerId = nextCheckerId; + nextCheckerId++; + // Bind all source files and propagate errors for (const file of host.getSourceFiles()) { bindSourceFile(file, compilerOptions); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f80126b64c5..b9931adb604 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2582,6 +2582,8 @@ namespace ts { AfterFinally = 1 << 13, // Injected edge that links post-finally flow with the rest of the graph /** @internal */ Cached = 1 << 14, // Indicates that at least one cross-call cache entry exists for this node, even if not a loop participant + /** @internal */ + Reachable = 1 << 15, // Reachability as computed by isReachableFlowNode Label = BranchLabel | LoopLabel, Condition = TrueCondition | FalseCondition } @@ -2600,6 +2602,8 @@ namespace ts { export interface FlowNodeBase { flags: FlowFlags; id?: number; // Node id used by flow type cache in checker + /** @internal */ + checkerId?: number; // Checker id for FlowFlags.Reachable } export interface FlowLock { From def5e37e6a03d42dd5c0093b70ab22eda36b5c10 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 16 Sep 2019 14:20:53 -0700 Subject: [PATCH 056/100] Revert "More efficient scheme for caching flow node reachability" This reverts commit e97ebb7f1c6ee93ce3ed6a4f996e54f346a0ff44. --- src/compiler/checker.ts | 20 ++++++-------------- src/compiler/types.ts | 4 ---- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c49ef71c19d..ba06e08a301 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6,7 +6,6 @@ namespace ts { let nextNodeId = 1; let nextMergeId = 1; let nextFlowId = 1; - let nextCheckerId = 1; const enum IterationUse { AllowsSyncIterablesFlag = 1 << 0, @@ -299,7 +298,6 @@ namespace ts { let instantiationDepth = 0; let constraintDepth = 0; let currentNode: Node | undefined; - let checkerId: number; const emptySymbols = createSymbolTable(); const identityMapper: (type: Type) => Type = identity; @@ -844,6 +842,7 @@ namespace ts { const flowLoopTypes: Type[][] = []; const sharedFlowNodes: FlowNode[] = []; const sharedFlowTypes: FlowType[] = []; + const flowNodeReachable: (boolean | undefined)[] = []; const potentialThisCollisions: Node[] = []; const potentialNewTargetCollisions: Node[] = []; const awaitedTypeStack: number[] = []; @@ -16994,21 +16993,17 @@ namespace ts { } function isReachableFlowNode(flow: FlowNode) { - return isReachableFlowNodeWorker(flow, /*noCacheCheck*/ false); + return isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false); } function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean { while (true) { const flags = flow.flags; - if (flags & (FlowFlags.Shared | FlowFlags.Assignment | FlowFlags.Label)) { + if (flags & FlowFlags.Shared) { if (!noCacheCheck) { - if (flow.checkerId === checkerId) { - return !!(flow.flags & FlowFlags.Reachable); - } - const reachable = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ true); - flow.checkerId = checkerId; - flow.flags = (flow.flags & ~FlowFlags.Reachable) | (reachable ? FlowFlags.Reachable : 0); - return reachable; + const id = getFlowNodeId(flow); + const reachable = flowNodeReachable[id]; + return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ true)); } noCacheCheck = false; } @@ -32292,9 +32287,6 @@ namespace ts { } function initializeTypeChecker() { - checkerId = nextCheckerId; - nextCheckerId++; - // Bind all source files and propagate errors for (const file of host.getSourceFiles()) { bindSourceFile(file, compilerOptions); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b9931adb604..f80126b64c5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2582,8 +2582,6 @@ namespace ts { AfterFinally = 1 << 13, // Injected edge that links post-finally flow with the rest of the graph /** @internal */ Cached = 1 << 14, // Indicates that at least one cross-call cache entry exists for this node, even if not a loop participant - /** @internal */ - Reachable = 1 << 15, // Reachability as computed by isReachableFlowNode Label = BranchLabel | LoopLabel, Condition = TrueCondition | FalseCondition } @@ -2602,8 +2600,6 @@ namespace ts { export interface FlowNodeBase { flags: FlowFlags; id?: number; // Node id used by flow type cache in checker - /** @internal */ - checkerId?: number; // Checker id for FlowFlags.Reachable } export interface FlowLock { From 6d6c620cc2e047047f8aba4eb7fe6acea81d77b4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 16 Sep 2019 15:30:45 -0700 Subject: [PATCH 057/100] Report grammatic and type-based unreachable code errors in the same way --- src/compiler/binder.ts | 3 +++ src/compiler/checker.ts | 10 +++++----- src/compiler/types.ts | 4 +++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5006e841dc7..cf93ee17ebd 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -672,6 +672,9 @@ namespace ts { bindJSDoc(node); return; } + if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement) { + node.flowNode = currentFlow; + } switch (node.kind) { case SyntaxKind.WhileStatement: bindWhileStatement(node); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ba06e08a301..501e6c4d92e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17057,11 +17057,7 @@ namespace ts { // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType); - if (resultType === unreachableNeverType) { - error(reference, Diagnostics.Unreachable_code_detected); - return declaredType; - } - if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { + if (resultType === unreachableNeverType|| reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) { return declaredType; } return resultType; @@ -30533,6 +30529,10 @@ namespace ts { cancellationToken.throwIfCancellationRequested(); } } + if (kind >= SyntaxKind.FirstStatement && kind <= SyntaxKind.LastStatement && + !compilerOptions.allowUnreachableCode && node.flowNode && !isReachableFlowNode(node.flowNode)) { + errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, Diagnostics.Unreachable_code_detected); + } switch (kind) { case SyntaxKind.TypeParameter: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f80126b64c5..afb53aea7a3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -363,8 +363,8 @@ namespace ts { SemicolonClassElement, // Element Block, - VariableStatement, EmptyStatement, + VariableStatement, ExpressionStatement, IfStatement, DoStatement, @@ -514,6 +514,8 @@ namespace ts { LastTemplateToken = TemplateTail, FirstBinaryOperator = LessThanToken, LastBinaryOperator = CaretEqualsToken, + FirstStatement = VariableStatement, + LastStatement = DebuggerStatement, FirstNode = QualifiedName, FirstJSDocNode = JSDocTypeExpression, LastJSDocNode = JSDocPropertyTag, From d9c9129720536f2d989772ab2498b900471d83e2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 16 Sep 2019 15:56:55 -0700 Subject: [PATCH 058/100] Ignore references in with statements in getTypeOfDottedName --- src/compiler/checker.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 501e6c4d92e..ca55f755b7b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16945,18 +16945,20 @@ namespace ts { // parameter symbols with declarations that have explicit type annotations. Such references are // resolvable with no possibility of triggering circularities in control flow analysis. function getTypeOfDottedName(node: Expression): Type | undefined { - switch (node.kind) { - case SyntaxKind.Identifier: - const symbol = getResolvedSymbol(node); - return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); - case SyntaxKind.ThisKeyword: - return checkThisExpression(node); - case SyntaxKind.PropertyAccessExpression: - const type = getTypeOfDottedName((node).expression); - const prop = type && getPropertyOfType(type, (node).name.escapedText); - return prop && getExplicitTypeOfSymbol(prop); - case SyntaxKind.ParenthesizedExpression: - return getTypeOfDottedName((node).expression); + if (!(node.flags & NodeFlags.InWithStatement)) { + switch (node.kind) { + case SyntaxKind.Identifier: + const symbol = getResolvedSymbol(node); + return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol); + case SyntaxKind.ThisKeyword: + return checkThisExpression(node); + case SyntaxKind.PropertyAccessExpression: + const type = getTypeOfDottedName((node).expression); + const prop = type && getPropertyOfType(type, (node).name.escapedText); + return prop && getExplicitTypeOfSymbol(prop); + case SyntaxKind.ParenthesizedExpression: + return getTypeOfDottedName((node).expression); + } } } From 282a7aff6e984ddee05561a557b08034f35f113f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 16 Sep 2019 15:58:42 -0700 Subject: [PATCH 059/100] Accept new API baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 6 ++++-- tests/baselines/reference/api/typescript.d.ts | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 121c14b4056..3ebd9418f8b 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -298,8 +298,8 @@ declare namespace ts { TemplateSpan = 218, SemicolonClassElement = 219, Block = 220, - VariableStatement = 221, - EmptyStatement = 222, + EmptyStatement = 221, + VariableStatement = 222, ExpressionStatement = 223, IfStatement = 224, DoStatement = 225, @@ -423,6 +423,8 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 28, LastBinaryOperator = 72, + FirstStatement = 222, + LastStatement = 238, FirstNode = 150, FirstJSDocNode = 290, LastJSDocNode = 314, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 22ed36d7ff9..e4d4648b172 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -298,8 +298,8 @@ declare namespace ts { TemplateSpan = 218, SemicolonClassElement = 219, Block = 220, - VariableStatement = 221, - EmptyStatement = 222, + EmptyStatement = 221, + VariableStatement = 222, ExpressionStatement = 223, IfStatement = 224, DoStatement = 225, @@ -423,6 +423,8 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 28, LastBinaryOperator = 72, + FirstStatement = 222, + LastStatement = 238, FirstNode = 150, FirstJSDocNode = 290, LastJSDocNode = 314, From 58e0469252a244b3b1fae44b133657495dca03a6 Mon Sep 17 00:00:00 2001 From: xiaofa Date: Tue, 17 Sep 2019 18:56:19 +0800 Subject: [PATCH 060/100] fix typo --- src/services/codefixes/convertConstToLet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/codefixes/convertConstToLet.ts b/src/services/codefixes/convertConstToLet.ts index df027f7d8c8..610aaf5daa4 100644 --- a/src/services/codefixes/convertConstToLet.ts +++ b/src/services/codefixes/convertConstToLet.ts @@ -7,14 +7,14 @@ namespace ts.codefix { errorCodes, getCodeActions: context => { const { sourceFile, span, program } = context; - const variableStatement = getVaribleStatement(sourceFile, span.start, program); + const variableStatement = getVariableStatement(sourceFile, span.start, program); const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, variableStatement)); return [createCodeFixAction(fixId, changes, Diagnostics.Convert_const_to_let, fixId, Diagnostics.Convert_const_to_let)]; }, fixIds: [fixId] }); - function getVaribleStatement(sourceFile: SourceFile, pos: number, program: Program) { + function getVariableStatement(sourceFile: SourceFile, pos: number, program: Program) { const token = getTokenAtPosition(sourceFile, pos); const checker = program.getTypeChecker(); const symbol = checker.getSymbolAtLocation(token); From 8cbf69489cd1974354ae07c81a4f03dc251d84b3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 17 Sep 2019 07:01:07 -0700 Subject: [PATCH 061/100] Cache last isReachableFlowNode result + switch statement CFA fix --- src/compiler/checker.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca55f755b7b..9e331dd0854 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -820,6 +820,8 @@ namespace ts { let flowLoopCount = 0; let sharedFlowCount = 0; let flowAnalysisDisabled = false; + let lastFlowNode: FlowNode | undefined; + let lastFlowNodeReachable: boolean; const emptyStringType = getLiteralType(""); const zeroType = getLiteralType(0); @@ -16995,11 +16997,17 @@ namespace ts { } function isReachableFlowNode(flow: FlowNode) { - return isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false); + const result = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false); + lastFlowNode = flow; + lastFlowNodeReachable = result; + return result; } function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean { while (true) { + if (flow === lastFlowNode) { + return lastFlowNodeReachable; + } const flags = flow.flags; if (flags & FlowFlags.Shared) { if (!noCacheCheck) { @@ -17329,9 +17337,6 @@ namespace ts { } function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType { - if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) { - return neverType; - } const expr = flow.switchStatement.expression; const flowType = getTypeAtFlowNode(flow.antecedent); let type = getTypeFromFlowType(flowType); @@ -17350,6 +17355,9 @@ namespace ts { else if (containsMatchingReferenceDiscriminant(reference, expr)) { type = declaredType; } + else if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) { + return unreachableNeverType; + } return createFlowType(type, isIncomplete(flowType)); } From 946602599611aa542d558f0b68436f7cac0584df Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 17 Sep 2019 07:41:36 -0700 Subject: [PATCH 062/100] Accept new baselines --- tests/baselines/reference/narrowingByTypeofInSwitch.types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/narrowingByTypeofInSwitch.types b/tests/baselines/reference/narrowingByTypeofInSwitch.types index fbfe7fe92ee..f823c57770c 100644 --- a/tests/baselines/reference/narrowingByTypeofInSwitch.types +++ b/tests/baselines/reference/narrowingByTypeofInSwitch.types @@ -208,7 +208,7 @@ function testExtendsUnion(x: T) { assertAll(x); >assertAll(x) : Basic >assertAll : (x: Basic) => Basic ->x : never +>x : T } function testAny(x: any) { From f10e38fea7996f746b79fc86f6fd47c1516cb307 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Mon, 16 Sep 2019 19:08:01 -0700 Subject: [PATCH 063/100] Make extractSymbol explicitly drop JSDoc nodes Fixes #33332 --- src/compiler/utilities.ts | 2 ++ src/services/refactors/extractSymbol.ts | 5 +++++ src/testRunner/unittests/services/extract/ranges.ts | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b338d3ba657..cb71df1fa93 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -975,6 +975,8 @@ namespace ts { return getSpanOfTokenAtPosition(sourceFile, node.pos); } + Debug.assert(!isJSDoc(errorNode)); + const isMissing = nodeIsMissing(errorNode); const pos = isMissing || isJsxText(node) ? errorNode.pos diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 859f7e1d3cc..e7f57a57351 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -116,6 +116,7 @@ namespace ts.refactor.extractSymbol { export const cannotExtractRange: DiagnosticMessage = createMessage("Cannot extract range."); export const cannotExtractImport: DiagnosticMessage = createMessage("Cannot extract import statement."); export const cannotExtractSuper: DiagnosticMessage = createMessage("Cannot extract super call."); + export const cannotExtractJSDoc: DiagnosticMessage = createMessage("Cannot extract JSDoc."); export const cannotExtractEmpty: DiagnosticMessage = createMessage("Cannot extract empty range."); export const expressionExpected: DiagnosticMessage = createMessage("expression expected."); export const uselessConstantType: DiagnosticMessage = createMessage("No reason to extract constant of type."); @@ -246,6 +247,10 @@ namespace ts.refactor.extractSymbol { return { targetRange: { range: statements, facts: rangeFacts, declarations } }; } + if (isJSDoc(start)) { + return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractJSDoc)] }; + } + if (isReturnStatement(start) && !start.expression) { // Makes no sense to extract an expression-less return statement. return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; diff --git a/src/testRunner/unittests/services/extract/ranges.ts b/src/testRunner/unittests/services/extract/ranges.ts index d2ac6a0a883..ab205288b33 100644 --- a/src/testRunner/unittests/services/extract/ranges.ts +++ b/src/testRunner/unittests/services/extract/ranges.ts @@ -380,6 +380,10 @@ switch (x) { `[#|{ 1;|] }`, [refactor.extractSymbol.Messages.cannotExtractRange.message]); + testExtractRangeFailed("extractRangeFailed19", + `[#|/** @type {number} */|] const foo = 1;`, + [refactor.extractSymbol.Messages.cannotExtractJSDoc.message]); + testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.cannotExtractIdentifier.message]); }); } From 800eaedbfa9d34eb136496e24bc026e5ad1dc9d5 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Tue, 17 Sep 2019 11:36:09 -0700 Subject: [PATCH 064/100] =?UTF-8?q?=F0=9F=A4=96=20User=20test=20baselines?= =?UTF-8?q?=20have=20changed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/baselines/reference/docker/azure-sdk.log | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/docker/azure-sdk.log b/tests/baselines/reference/docker/azure-sdk.log index 347a6c188a9..fb911c5a367 100644 --- a/tests/baselines/reference/docker/azure-sdk.log +++ b/tests/baselines/reference/docker/azure-sdk.log @@ -9,12 +9,11 @@ XX of XX: [@azure/abort-controller] completed successfully in ? seconds XX of XX: [@azure/core-auth] completed successfully in ? seconds XX of XX: [@azure/core-tracing] completed successfully in ? seconds XX of XX: [@azure/core-http] completed successfully in ? seconds -XX of XX: [@azure/identity] completed successfully in ? seconds -XX of XX: [@azure/core-amqp] completed successfully in ? seconds XX of XX: [@azure/core-arm] completed successfully in ? seconds XX of XX: [@azure/core-paging] completed successfully in ? seconds +XX of XX: [@azure/identity] completed successfully in ? seconds XX of XX: [@azure/test-utils-recorder] completed successfully in ? seconds -XX of XX: [@azure/event-hubs] completed successfully in ? seconds +XX of XX: [@azure/core-amqp] completed successfully in ? seconds XX of XX: [@azure/event-processor-host] completed successfully in ? seconds XX of XX: [@azure/keyvault-keys] completed successfully in ? seconds XX of XX: [@azure/keyvault-secrets] completed successfully in ? seconds @@ -56,6 +55,7 @@ atob (guessing 'atob') (!) Circular dependency: dist-esm/index.js -> dist-esm/CosmosClient.js -> dist-esm/client/Database/index.js -> dist-esm/client/Database/Database.js -> dist-esm/client/Container/index.js -> dist-esm/client/Container/Container.js -> dist-esm/client/Script/Scripts.js -> dist-esm/index.js (!) Circular dependency: dist-esm/request/RequestHandler.js -> dist-esm/retry/retryUtility.js -> dist-esm/request/RequestHandler.js created dist/index.js in ?s +XX of XX: [@azure/event-hubs] completed successfully in ? seconds XX of XX: [@azure/eventhubs-checkpointstore-blob] completed successfully in ? seconds XX of XX: [@azure/keyvault-certificates] completed successfully in ? seconds Warning: You have changed the public API signature for this project. Updating review/service-bus.api.md @@ -70,17 +70,17 @@ SUCCESS (22) @azure/core-auth (? seconds) @azure/core-tracing (? seconds) @azure/core-http (? seconds) -@azure/identity (? seconds) -@azure/core-amqp (? seconds) @azure/core-arm (? seconds) @azure/core-paging (? seconds) +@azure/identity (? seconds) @azure/test-utils-recorder (? seconds) -@azure/event-hubs (? seconds) +@azure/core-amqp (? seconds) @azure/event-processor-host (? seconds) @azure/keyvault-keys (? seconds) @azure/keyvault-secrets (? seconds) @azure/app-configuration (? seconds) @azure/core-asynciterator-polyfill (? seconds) +@azure/event-hubs (? seconds) @azure/eventhubs-checkpointstore-blob (? seconds) @azure/keyvault-certificates (? seconds) @azure/storage-blob (? seconds) From 6bb7e5c086ecbe40dfda84c75b5b5b46a8a389c2 Mon Sep 17 00:00:00 2001 From: Martin Probst Date: Mon, 9 Sep 2019 14:08:00 +0200 Subject: [PATCH 065/100] Handle parentless nodes in isParameterPropertyDeclaration Fixes #33295. This follows a similar pattern as in #20314 by requiring an explicit `parent` parameter. Where possible, it uses the appopriate variable at the call sites. In several locations there is no context available though (e.g. inspecting `valueDeclarations`) and we access `.parent` as the code previously did. From a cursory inspection this seems correct, these callpaths originate in phases where there must be a `parent` (i.e. in checker, binder, etc). Change-Id: I28e4726777b57237bec776e4001e9e69ac591b11 --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 4 +-- src/compiler/transformers/classFields.ts | 2 +- .../transformers/declarations/diagnostics.ts | 2 +- src/compiler/transformers/ts.ts | 4 +-- src/compiler/utilities.ts | 6 ++-- src/services/findAllReferences.ts | 4 +-- src/services/navigationBar.ts | 2 +- .../generateGetAccessorAndSetAccessor.ts | 4 +-- src/testRunner/unittests/transform.ts | 30 ++++++++++++++++++- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- ...rmsCorrectly.transformParameterProperty.js | 18 +++++++++++ 13 files changed, 64 insertions(+), 18 deletions(-) create mode 100644 tests/baselines/reference/transformApi/transformsCorrectly.transformParameterProperty.js diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 3bc03cdbab9..705ec3b75f4 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2859,7 +2859,7 @@ namespace ts { // If this is a property-parameter, then also declare the property symbol into the // containing class. - if (isParameterPropertyDeclaration(node)) { + if (isParameterPropertyDeclaration(node, node.parent)) { const classDeclaration = node.parent.parent; declareSymbol(classDeclaration.symbol.members!, classDeclaration.symbol, node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8c88178885..2fa1d8acf4a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25705,7 +25705,7 @@ namespace ts { for (const member of node.members) { if (member.kind === SyntaxKind.Constructor) { for (const param of (member as ConstructorDeclaration).parameters) { - if (isParameterPropertyDeclaration(param) && !isBindingPattern(param.name)) { + if (isParameterPropertyDeclaration(param, member) && !isBindingPattern(param.name)) { addName(instanceNames, param.name, param.name.escapedText, DeclarationMeaning.GetOrSetAccessor); } } @@ -27469,7 +27469,7 @@ namespace ts { const parameter = local.valueDeclaration && tryGetRootParameterDeclaration(local.valueDeclaration); const name = local.valueDeclaration && getNameOfDeclaration(local.valueDeclaration); if (parameter && name) { - if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) { + if (!isParameterPropertyDeclaration(parameter, parameter.parent) && !parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) { addDiagnostic(parameter, UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local))); } } diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 4efe4ad7b38..37473d9bb20 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -337,7 +337,7 @@ namespace ts { if (constructor && constructor.body) { let parameterPropertyDeclarationCount = 0; for (let i = indexOfFirstStatement; i < constructor.body.statements.length; i++) { - if (isParameterPropertyDeclaration(getOriginalNode(constructor.body.statements[i]))) { + if (isParameterPropertyDeclaration(getOriginalNode(constructor.body.statements[i]), constructor)) { parameterPropertyDeclarationCount++; } else { diff --git a/src/compiler/transformers/declarations/diagnostics.ts b/src/compiler/transformers/declarations/diagnostics.ts index 61d4dd30a67..91c960ea942 100644 --- a/src/compiler/transformers/declarations/diagnostics.ts +++ b/src/compiler/transformers/declarations/diagnostics.ts @@ -135,7 +135,7 @@ namespace ts { return getReturnTypeVisibilityError; } else if (isParameter(node)) { - if (isParameterPropertyDeclaration(node) && hasModifier(node.parent, ModifierFlags.Private)) { + if (isParameterPropertyDeclaration(node, node.parent) && hasModifier(node.parent, ModifierFlags.Private)) { return getVariableDeclarationTypeVisibilityError; } return getParameterDeclarationTypeVisibilityError; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 4cbc8e565df..06b3fb53ec1 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -895,7 +895,7 @@ namespace ts { const members: ClassElement[] = []; const constructor = getFirstConstructorWithBody(node); const parametersWithPropertyAssignments = constructor && - filter(constructor.parameters, isParameterPropertyDeclaration); + filter(constructor.parameters, p => isParameterPropertyDeclaration(p, constructor)); if (parametersWithPropertyAssignments) { for (const parameter of parametersWithPropertyAssignments) { @@ -1907,7 +1907,7 @@ namespace ts { function transformConstructorBody(body: Block, constructor: ConstructorDeclaration) { const parametersWithPropertyAssignments = constructor && - filter(constructor.parameters, isParameterPropertyDeclaration); + filter(constructor.parameters, p => isParameterPropertyDeclaration(p, constructor)); if (!some(parametersWithPropertyAssignments)) { return visitFunctionBody(body, visitor, context); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index cb71df1fa93..1645b9339ae 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1009,7 +1009,7 @@ namespace ts { } export function isDeclarationReadonly(declaration: Declaration): boolean { - return !!(getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration)); + return !!(getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration, declaration.parent)); } export function isVarConst(node: VariableDeclaration | VariableDeclarationList): boolean { @@ -4983,8 +4983,8 @@ namespace ts { } export type ParameterPropertyDeclaration = ParameterDeclaration & { parent: ConstructorDeclaration, name: Identifier }; - export function isParameterPropertyDeclaration(node: Node): node is ParameterPropertyDeclaration { - return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && node.parent.kind === SyntaxKind.Constructor; + export function isParameterPropertyDeclaration(node: Node, parent: Node): node is ParameterPropertyDeclaration { + return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && parent.kind === SyntaxKind.Constructor; } export function isEmptyBindingPattern(node: BindingName): node is BindingPattern { diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 5d667ee55a4..f98fb2f75b8 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1145,7 +1145,7 @@ namespace ts.FindAllReferences.Core { } export function eachSymbolReferenceInFile(definition: Identifier, checker: TypeChecker, sourceFile: SourceFile, cb: (token: Identifier) => T): T | undefined { - const symbol = isParameterPropertyDeclaration(definition.parent) + const symbol = isParameterPropertyDeclaration(definition.parent, definition.parent.parent) ? first(checker.getSymbolsOfParameterPropertyDeclaration(definition.parent, definition.text)) : checker.getSymbolAtLocation(definition); if (!symbol) return undefined; @@ -1886,7 +1886,7 @@ namespace ts.FindAllReferences.Core { const res = fromRoot(symbol); if (res) return res; - if (symbol.valueDeclaration && isParameterPropertyDeclaration(symbol.valueDeclaration)) { + if (symbol.valueDeclaration && isParameterPropertyDeclaration(symbol.valueDeclaration, symbol.valueDeclaration.parent)) { // For a parameter property, now try on the other symbol (property if this was a parameter, parameter if this was a property). const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(cast(symbol.valueDeclaration, isParameter), symbol.name); Debug.assert(paramProps.length === 2 && !!(paramProps[0].flags & SymbolFlags.FunctionScopedVariable) && !!(paramProps[1].flags & SymbolFlags.Property)); // is [parameter, property] diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 7a91fcdcad2..dd3bdcffd32 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -197,7 +197,7 @@ namespace ts.NavigationBar { // Parameter properties are children of the class, not the constructor. for (const param of ctr.parameters) { - if (isParameterPropertyDeclaration(param)) { + if (isParameterPropertyDeclaration(param, ctr)) { addLeafNode(param); } } diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 7e4ca1a6645..a1bd32b37fc 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -92,7 +92,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { } function isAcceptedDeclaration(node: Node): node is AcceptedDeclaration { - return isParameterPropertyDeclaration(node) || isPropertyDeclaration(node) || isPropertyAssignment(node); + return isParameterPropertyDeclaration(node, node.parent) || isPropertyDeclaration(node) || isPropertyAssignment(node); } function createPropertyName (name: string, originalName: AcceptedNameType) { @@ -214,7 +214,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { } function insertAccessor(changeTracker: textChanges.ChangeTracker, file: SourceFile, accessor: AccessorDeclaration, declaration: AcceptedDeclaration, container: ContainerDeclaration) { - isParameterPropertyDeclaration(declaration) ? changeTracker.insertNodeAtClassStart(file, container, accessor) : + isParameterPropertyDeclaration(declaration, declaration.parent) ? changeTracker.insertNodeAtClassStart(file, container, accessor) : isPropertyAssignment(declaration) ? changeTracker.insertNodeAfterComma(file, declaration, accessor) : changeTracker.insertNodeAfter(file, declaration, accessor); } diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 5203e69e813..ffd5ba7609f 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -300,6 +300,34 @@ namespace ts { }); }); + // https://github.com/microsoft/TypeScript/issues/33295 + testBaseline("transformParameterProperty", () => { + return transpileModule("", { + transformers: { + before: [transformAddParameterProperty], + }, + compilerOptions: { + target: ScriptTarget.ES5, + newLine: NewLineKind.CarriageReturnLineFeed, + } + }).outputText; + + function transformAddParameterProperty(_context: TransformationContext) { + return (sourceFile: SourceFile): SourceFile => { + return visitNode(sourceFile); + }; + function visitNode(sf: SourceFile) { + // produce `class Foo { constructor(@Dec private x) {} }`; + // The decorator is required to trigger ts.ts transformations. + const classDecl = createClassDeclaration([], [], "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [ + createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, [ + createParameter(/*decorators*/ [createDecorator(createIdentifier("Dec"))], /*modifiers*/ [createModifier(SyntaxKind.PrivateKeyword)], /*dotDotDotToken*/ undefined, "x")], createBlock([])) + ]); + return updateSourceFileNode(sf, [classDecl]); + } + } + }); + function baselineDeclarationTransform(text: string, opts: TranspileOptions) { const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true, { documents: [new documents.TextDocument("/.src/index.ts", text)] }); const host = new fakes.CompilerHost(fs, opts.compilerOptions); @@ -389,7 +417,7 @@ class Clazz { } `, { transformers: { - before: [addSyntheticComment(n => isPropertyDeclaration(n) || isParameterPropertyDeclaration(n) || isClassDeclaration(n) || isConstructorDeclaration(n))], + before: [addSyntheticComment(n => isPropertyDeclaration(n) || isParameterPropertyDeclaration(n, n.parent) || isClassDeclaration(n) || isConstructorDeclaration(n))], }, compilerOptions: { target: ScriptTarget.ES2015, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 41ea5756204..58d513b2e0a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3274,7 +3274,7 @@ declare namespace ts { parent: ConstructorDeclaration; name: Identifier; }; - function isParameterPropertyDeclaration(node: Node): node is ParameterPropertyDeclaration; + function isParameterPropertyDeclaration(node: Node, parent: Node): node is ParameterPropertyDeclaration; function isEmptyBindingPattern(node: BindingName): node is BindingPattern; function isEmptyBindingElement(node: BindingElement): boolean; function walkUpBindingElementsAndPatterns(binding: BindingElement): VariableDeclaration | ParameterDeclaration; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 8402150f2a0..bc71eaffa37 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3274,7 +3274,7 @@ declare namespace ts { parent: ConstructorDeclaration; name: Identifier; }; - function isParameterPropertyDeclaration(node: Node): node is ParameterPropertyDeclaration; + function isParameterPropertyDeclaration(node: Node, parent: Node): node is ParameterPropertyDeclaration; function isEmptyBindingPattern(node: BindingName): node is BindingPattern; function isEmptyBindingElement(node: BindingElement): boolean; function walkUpBindingElementsAndPatterns(binding: BindingElement): VariableDeclaration | ParameterDeclaration; diff --git a/tests/baselines/reference/transformApi/transformsCorrectly.transformParameterProperty.js b/tests/baselines/reference/transformApi/transformsCorrectly.transformParameterProperty.js new file mode 100644 index 00000000000..d121694872f --- /dev/null +++ b/tests/baselines/reference/transformApi/transformsCorrectly.transformParameterProperty.js @@ -0,0 +1,18 @@ +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __param = (this && this.__param) || function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +}; +var Foo = /** @class */ (function () { + function Foo(x) { + this.x = x; + } + Foo = __decorate([ + __param(0, Dec) + ], Foo); + return Foo; +}()); From 56e2cb31ad95b08fa4f4c9578522777c18b687b2 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 17 Sep 2019 15:36:00 -0700 Subject: [PATCH 066/100] Reverse mapped types should have inferable indexes if their source had an inferable index (#33450) --- src/compiler/checker.ts | 6 +-- .../reverseMappedTypeAssignableToIndex.js | 22 ++++++++ ...reverseMappedTypeAssignableToIndex.symbols | 54 +++++++++++++++++++ .../reverseMappedTypeAssignableToIndex.types | 42 +++++++++++++++ .../reverseMappedTypeAssignableToIndex.ts | 19 +++++++ 5 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/reverseMappedTypeAssignableToIndex.js create mode 100644 tests/baselines/reference/reverseMappedTypeAssignableToIndex.symbols create mode 100644 tests/baselines/reference/reverseMappedTypeAssignableToIndex.types create mode 100644 tests/cases/compiler/reverseMappedTypeAssignableToIndex.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2fa1d8acf4a..e3907885a4c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15004,9 +15004,9 @@ namespace ts { * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module * with no call or construct signatures. */ - function isObjectTypeWithInferableIndex(type: Type) { - return type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.Enum | SymbolFlags.ValueModule)) !== 0 && - !typeHasCallOrConstructSignatures(type); + function isObjectTypeWithInferableIndex(type: Type): boolean { + return !!(type.symbol && (type.symbol.flags & (SymbolFlags.ObjectLiteral | SymbolFlags.TypeLiteral | SymbolFlags.Enum | SymbolFlags.ValueModule)) !== 0 && + !typeHasCallOrConstructSignatures(type)) || !!(getObjectFlags(type) & ObjectFlags.ReverseMapped && isObjectTypeWithInferableIndex((type as ReverseMappedType).source)); } function createSymbolWithType(source: Symbol, type: Type | undefined) { diff --git a/tests/baselines/reference/reverseMappedTypeAssignableToIndex.js b/tests/baselines/reference/reverseMappedTypeAssignableToIndex.js new file mode 100644 index 00000000000..b3ee2dcda2e --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeAssignableToIndex.js @@ -0,0 +1,22 @@ +//// [reverseMappedTypeAssignableToIndex.ts] +// Simple mapped type and inferrence +type Mapped = { [K in keyof T]: { name: T[K] } }; +type InferFromMapped = T extends Mapped ? R : never; + +// Object literal type and associated mapped type +// Note that in the real code we don't have a direct reference to LiteralType +type LiteralType = { + first: "first"; + second: "second"; +} +type MappedLiteralType = { + first: { name: "first" }, + second: { name: "second" }, +}; + +type Inferred = InferFromMapped; + +// UNEXPECTED resolves to false +type Test1 = Inferred extends Record ? true : false; + +//// [reverseMappedTypeAssignableToIndex.js] diff --git a/tests/baselines/reference/reverseMappedTypeAssignableToIndex.symbols b/tests/baselines/reference/reverseMappedTypeAssignableToIndex.symbols new file mode 100644 index 00000000000..38ed9ff039f --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeAssignableToIndex.symbols @@ -0,0 +1,54 @@ +=== tests/cases/compiler/reverseMappedTypeAssignableToIndex.ts === +// Simple mapped type and inferrence +type Mapped = { [K in keyof T]: { name: T[K] } }; +>Mapped : Symbol(Mapped, Decl(reverseMappedTypeAssignableToIndex.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedTypeAssignableToIndex.ts, 1, 12)) +>K : Symbol(K, Decl(reverseMappedTypeAssignableToIndex.ts, 1, 20)) +>T : Symbol(T, Decl(reverseMappedTypeAssignableToIndex.ts, 1, 12)) +>name : Symbol(name, Decl(reverseMappedTypeAssignableToIndex.ts, 1, 36)) +>T : Symbol(T, Decl(reverseMappedTypeAssignableToIndex.ts, 1, 12)) +>K : Symbol(K, Decl(reverseMappedTypeAssignableToIndex.ts, 1, 20)) + +type InferFromMapped = T extends Mapped ? R : never; +>InferFromMapped : Symbol(InferFromMapped, Decl(reverseMappedTypeAssignableToIndex.ts, 1, 52)) +>T : Symbol(T, Decl(reverseMappedTypeAssignableToIndex.ts, 2, 21)) +>T : Symbol(T, Decl(reverseMappedTypeAssignableToIndex.ts, 2, 21)) +>Mapped : Symbol(Mapped, Decl(reverseMappedTypeAssignableToIndex.ts, 0, 0)) +>R : Symbol(R, Decl(reverseMappedTypeAssignableToIndex.ts, 2, 48)) +>R : Symbol(R, Decl(reverseMappedTypeAssignableToIndex.ts, 2, 48)) + +// Object literal type and associated mapped type +// Note that in the real code we don't have a direct reference to LiteralType +type LiteralType = { +>LiteralType : Symbol(LiteralType, Decl(reverseMappedTypeAssignableToIndex.ts, 2, 64)) + + first: "first"; +>first : Symbol(first, Decl(reverseMappedTypeAssignableToIndex.ts, 6, 20)) + + second: "second"; +>second : Symbol(second, Decl(reverseMappedTypeAssignableToIndex.ts, 7, 16)) +} +type MappedLiteralType = { +>MappedLiteralType : Symbol(MappedLiteralType, Decl(reverseMappedTypeAssignableToIndex.ts, 9, 1)) + + first: { name: "first" }, +>first : Symbol(first, Decl(reverseMappedTypeAssignableToIndex.ts, 10, 26)) +>name : Symbol(name, Decl(reverseMappedTypeAssignableToIndex.ts, 11, 9)) + + second: { name: "second" }, +>second : Symbol(second, Decl(reverseMappedTypeAssignableToIndex.ts, 11, 26)) +>name : Symbol(name, Decl(reverseMappedTypeAssignableToIndex.ts, 12, 10)) + +}; + +type Inferred = InferFromMapped; +>Inferred : Symbol(Inferred, Decl(reverseMappedTypeAssignableToIndex.ts, 13, 2)) +>InferFromMapped : Symbol(InferFromMapped, Decl(reverseMappedTypeAssignableToIndex.ts, 1, 52)) +>MappedLiteralType : Symbol(MappedLiteralType, Decl(reverseMappedTypeAssignableToIndex.ts, 9, 1)) + +// UNEXPECTED resolves to false +type Test1 = Inferred extends Record ? true : false; +>Test1 : Symbol(Test1, Decl(reverseMappedTypeAssignableToIndex.ts, 15, 51)) +>Inferred : Symbol(Inferred, Decl(reverseMappedTypeAssignableToIndex.ts, 13, 2)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + diff --git a/tests/baselines/reference/reverseMappedTypeAssignableToIndex.types b/tests/baselines/reference/reverseMappedTypeAssignableToIndex.types new file mode 100644 index 00000000000..589e9ff3477 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeAssignableToIndex.types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/reverseMappedTypeAssignableToIndex.ts === +// Simple mapped type and inferrence +type Mapped = { [K in keyof T]: { name: T[K] } }; +>Mapped : Mapped +>name : T[K] + +type InferFromMapped = T extends Mapped ? R : never; +>InferFromMapped : InferFromMapped + +// Object literal type and associated mapped type +// Note that in the real code we don't have a direct reference to LiteralType +type LiteralType = { +>LiteralType : LiteralType + + first: "first"; +>first : "first" + + second: "second"; +>second : "second" +} +type MappedLiteralType = { +>MappedLiteralType : MappedLiteralType + + first: { name: "first" }, +>first : { name: "first"; } +>name : "first" + + second: { name: "second" }, +>second : { name: "second"; } +>name : "second" + +}; + +type Inferred = InferFromMapped; +>Inferred : { first: "first"; second: "second"; } + +// UNEXPECTED resolves to false +type Test1 = Inferred extends Record ? true : false; +>Test1 : true +>true : true +>false : false + diff --git a/tests/cases/compiler/reverseMappedTypeAssignableToIndex.ts b/tests/cases/compiler/reverseMappedTypeAssignableToIndex.ts new file mode 100644 index 00000000000..a1244fe8eb2 --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeAssignableToIndex.ts @@ -0,0 +1,19 @@ +// Simple mapped type and inferrence +type Mapped = { [K in keyof T]: { name: T[K] } }; +type InferFromMapped = T extends Mapped ? R : never; + +// Object literal type and associated mapped type +// Note that in the real code we don't have a direct reference to LiteralType +type LiteralType = { + first: "first"; + second: "second"; +} +type MappedLiteralType = { + first: { name: "first" }, + second: { name: "second" }, +}; + +type Inferred = InferFromMapped; + +// UNEXPECTED resolves to false +type Test1 = Inferred extends Record ? true : false; \ No newline at end of file From 344dba8809e82ff74b9616c872fa5a781c264d42 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Tue, 17 Sep 2019 21:02:12 -0700 Subject: [PATCH 067/100] Fix incorrect parameter types for AsyncIterator next/return (#33354) --- src/compiler/checker.ts | 6 ++-- src/lib/es2018.asyncgenerator.d.ts | 2 +- src/lib/es2018.asynciterable.d.ts | 2 +- .../reference/customAsyncIterator.js | 26 ++++++++++++++ .../reference/customAsyncIterator.symbols | 35 +++++++++++++++++++ .../reference/customAsyncIterator.types | 32 +++++++++++++++++ .../types.asyncGenerators.es2018.1.symbols | 9 +++++ .../types.asyncGenerators.es2018.1.types | 9 +++++ .../types.asyncGenerators.es2018.2.errors.txt | 20 +++++------ tests/cases/compiler/customAsyncIterator.ts | 13 +++++++ .../types.asyncGenerators.es2018.1.ts | 3 ++ 11 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 tests/baselines/reference/customAsyncIterator.js create mode 100644 tests/baselines/reference/customAsyncIterator.symbols create mode 100644 tests/baselines/reference/customAsyncIterator.types create mode 100644 tests/cases/compiler/customAsyncIterator.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e3907885a4c..9a8cf2f8038 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28740,11 +28740,13 @@ namespace ts { let nextType: Type | undefined; if (methodName !== "throw") { const methodParameterType = methodParameterTypes ? getUnionType(methodParameterTypes) : unknownType; - const resolvedMethodParameterType = resolver.resolveIterationType(methodParameterType, errorNode) || anyType; if (methodName === "next") { - nextType = resolvedMethodParameterType; + // The value of `next(value)` is *not* awaited by async generators + nextType = methodParameterType; } else if (methodName === "return") { + // The value of `return(value)` *is* awaited by async generators + const resolvedMethodParameterType = resolver.resolveIterationType(methodParameterType, errorNode) || anyType; returnTypes = append(returnTypes, resolvedMethodParameterType); } } diff --git a/src/lib/es2018.asyncgenerator.d.ts b/src/lib/es2018.asyncgenerator.d.ts index 76275c92575..f6966264c8b 100644 --- a/src/lib/es2018.asyncgenerator.d.ts +++ b/src/lib/es2018.asyncgenerator.d.ts @@ -2,7 +2,7 @@ interface AsyncGenerator extends AsyncIterator { // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places. - next(...args: [] | [TNext | PromiseLike]): Promise>; + next(...args: [] | [TNext]): Promise>; return(value: TReturn | PromiseLike): Promise>; throw(e: any): Promise>; [Symbol.asyncIterator](): AsyncGenerator; diff --git a/src/lib/es2018.asynciterable.d.ts b/src/lib/es2018.asynciterable.d.ts index d5d83f31893..19a31c72ca4 100644 --- a/src/lib/es2018.asynciterable.d.ts +++ b/src/lib/es2018.asynciterable.d.ts @@ -11,7 +11,7 @@ interface SymbolConstructor { interface AsyncIterator { // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places. - next(...args: [] | [TNext | PromiseLike]): Promise>; + next(...args: [] | [TNext]): Promise>; return?(value?: TReturn | PromiseLike): Promise>; throw?(e?: any): Promise>; } diff --git a/tests/baselines/reference/customAsyncIterator.js b/tests/baselines/reference/customAsyncIterator.js new file mode 100644 index 00000000000..c0a86218e8d --- /dev/null +++ b/tests/baselines/reference/customAsyncIterator.js @@ -0,0 +1,26 @@ +//// [customAsyncIterator.ts] +// GH: https://github.com/microsoft/TypeScript/issues/33239 +class ConstantIterator implements AsyncIterator { + constructor(private constant: T) { + } + async next(value?: T): Promise> { + if (value != null) { + throw new Error("ConstantIterator.prototype.next may not take any values"); + } + return { value: this.constant, done: false }; + } +} + +//// [customAsyncIterator.js] +// GH: https://github.com/microsoft/TypeScript/issues/33239 +class ConstantIterator { + constructor(constant) { + this.constant = constant; + } + async next(value) { + if (value != null) { + throw new Error("ConstantIterator.prototype.next may not take any values"); + } + return { value: this.constant, done: false }; + } +} diff --git a/tests/baselines/reference/customAsyncIterator.symbols b/tests/baselines/reference/customAsyncIterator.symbols new file mode 100644 index 00000000000..59c099ec403 --- /dev/null +++ b/tests/baselines/reference/customAsyncIterator.symbols @@ -0,0 +1,35 @@ +=== tests/cases/compiler/customAsyncIterator.ts === +// GH: https://github.com/microsoft/TypeScript/issues/33239 +class ConstantIterator implements AsyncIterator { +>ConstantIterator : Symbol(ConstantIterator, Decl(customAsyncIterator.ts, 0, 0)) +>T : Symbol(T, Decl(customAsyncIterator.ts, 1, 23)) +>AsyncIterator : Symbol(AsyncIterator, Decl(lib.es2018.asynciterable.d.ts, --, --)) +>T : Symbol(T, Decl(customAsyncIterator.ts, 1, 23)) +>T : Symbol(T, Decl(customAsyncIterator.ts, 1, 23)) + + constructor(private constant: T) { +>constant : Symbol(ConstantIterator.constant, Decl(customAsyncIterator.ts, 2, 16)) +>T : Symbol(T, Decl(customAsyncIterator.ts, 1, 23)) + } + async next(value?: T): Promise> { +>next : Symbol(ConstantIterator.next, Decl(customAsyncIterator.ts, 3, 5)) +>value : Symbol(value, Decl(customAsyncIterator.ts, 4, 15)) +>T : Symbol(T, Decl(customAsyncIterator.ts, 1, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>IteratorResult : Symbol(IteratorResult, Decl(lib.es2015.iterable.d.ts, --, --)) +>T : Symbol(T, Decl(customAsyncIterator.ts, 1, 23)) + + if (value != null) { +>value : Symbol(value, Decl(customAsyncIterator.ts, 4, 15)) + + throw new Error("ConstantIterator.prototype.next may not take any values"); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } + return { value: this.constant, done: false }; +>value : Symbol(value, Decl(customAsyncIterator.ts, 8, 16)) +>this.constant : Symbol(ConstantIterator.constant, Decl(customAsyncIterator.ts, 2, 16)) +>this : Symbol(ConstantIterator, Decl(customAsyncIterator.ts, 0, 0)) +>constant : Symbol(ConstantIterator.constant, Decl(customAsyncIterator.ts, 2, 16)) +>done : Symbol(done, Decl(customAsyncIterator.ts, 8, 38)) + } +} diff --git a/tests/baselines/reference/customAsyncIterator.types b/tests/baselines/reference/customAsyncIterator.types new file mode 100644 index 00000000000..63c67cfddd3 --- /dev/null +++ b/tests/baselines/reference/customAsyncIterator.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/customAsyncIterator.ts === +// GH: https://github.com/microsoft/TypeScript/issues/33239 +class ConstantIterator implements AsyncIterator { +>ConstantIterator : ConstantIterator + + constructor(private constant: T) { +>constant : T + } + async next(value?: T): Promise> { +>next : (value?: T) => Promise> +>value : T + + if (value != null) { +>value != null : boolean +>value : T +>null : null + + throw new Error("ConstantIterator.prototype.next may not take any values"); +>new Error("ConstantIterator.prototype.next may not take any values") : Error +>Error : ErrorConstructor +>"ConstantIterator.prototype.next may not take any values" : "ConstantIterator.prototype.next may not take any values" + } + return { value: this.constant, done: false }; +>{ value: this.constant, done: false } : { value: T; done: false; } +>value : T +>this.constant : T +>this : this +>constant : T +>done : false +>false : false + } +} diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.1.symbols b/tests/baselines/reference/types.asyncGenerators.es2018.1.symbols index 3a0e33ce1b1..5cf681477e5 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.1.symbols +++ b/tests/baselines/reference/types.asyncGenerators.es2018.1.symbols @@ -289,4 +289,13 @@ async function * awaitedType2() { >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) } +async function * nextType1(): { next(...args: [] | [number | PromiseLike]): any } { +>nextType1 : Symbol(nextType1, Decl(types.asyncGenerators.es2018.1.ts, 122, 1)) +>next : Symbol(next, Decl(types.asyncGenerators.es2018.1.ts, 123, 31)) +>args : Symbol(args, Decl(types.asyncGenerators.es2018.1.ts, 123, 37)) +>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --)) + + const x = yield; // `number | PromiseLike` (should not await TNext) +>x : Symbol(x, Decl(types.asyncGenerators.es2018.1.ts, 124, 9)) +} diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.1.types b/tests/baselines/reference/types.asyncGenerators.es2018.1.types index 54db9b890ec..3c6e51c56d2 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.1.types +++ b/tests/baselines/reference/types.asyncGenerators.es2018.1.types @@ -430,4 +430,13 @@ async function * awaitedType2() { >resolve : { (value: T | PromiseLike): Promise; (): Promise; } >1 : 1 } +async function * nextType1(): { next(...args: [] | [number | PromiseLike]): any } { +>nextType1 : () => { next(...args: [] | [number | PromiseLike]): any; } +>next : (...args: [] | [number | PromiseLike]) => any +>args : [] | [number | PromiseLike] + + const x = yield; // `number | PromiseLike` (should not await TNext) +>x : number | PromiseLike +>yield : number | PromiseLike +} diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt index d7ec011bced..9f22060b9e9 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt +++ b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt @@ -3,7 +3,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(10,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. Types of property 'next' are incompatible. - Type '(...args: [] | [PromiseLike]) => Promise>' is not assignable to type '(...args: [] | [PromiseLike]) => Promise>'. + Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. Type 'Promise>' is not assignable to type 'Promise>'. Type 'IteratorResult' is not assignable to type 'IteratorResult'. Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. @@ -14,7 +14,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(16,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. Types of property 'next' are incompatible. - Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [PromiseLike]) => Promise>'. + Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. Type 'Promise>' is not assignable to type 'Promise>'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(19,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterable'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterable'. @@ -22,7 +22,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. Types of property 'next' are incompatible. - Type '(...args: [] | [PromiseLike]) => Promise>' is not assignable to type '(...args: [] | [PromiseLike]) => Promise>'. + Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. Type 'Promise>' is not assignable to type 'Promise>'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(22,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterable'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterable'. @@ -32,7 +32,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. Types of property 'next' are incompatible. - Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [PromiseLike]) => Promise>'. + Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. Type 'Promise>' is not assignable to type 'Promise>'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(28,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. @@ -53,7 +53,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(67,42): error TS2741: Property '[Symbol.iterator]' is missing in type 'AsyncGenerator' but required in type 'Iterable'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(70,42): error TS2322: Type 'AsyncGenerator' is not assignable to type 'Iterator'. Types of property 'next' are incompatible. - Type '(...args: [] | [PromiseLike]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. + Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. Type 'Promise>' is not assignable to type 'IteratorResult'. Property 'value' is missing in type 'Promise>' but required in type 'IteratorYieldResult'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(74,12): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. @@ -79,7 +79,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( !!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. !!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. !!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [PromiseLike]) => Promise>' is not assignable to type '(...args: [] | [PromiseLike]) => Promise>'. +!!! error TS2322: Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. !!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. !!! error TS2322: Type 'IteratorResult' is not assignable to type 'IteratorResult'. !!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. @@ -98,7 +98,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( !!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. !!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. !!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [PromiseLike]) => Promise>'. +!!! error TS2322: Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. !!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. yield* (async function * () { yield "a"; })(); }; @@ -110,7 +110,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( !!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. !!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. !!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [PromiseLike]) => Promise>' is not assignable to type '(...args: [] | [PromiseLike]) => Promise>'. +!!! error TS2322: Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. !!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. yield "a"; }; @@ -128,7 +128,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( !!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. !!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. !!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [PromiseLike]) => Promise>'. +!!! error TS2322: Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. !!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. yield* (async function * () { yield "a"; })(); }; @@ -211,7 +211,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( ~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'Iterator'. !!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [PromiseLike]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. +!!! error TS2322: Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. !!! error TS2322: Type 'Promise>' is not assignable to type 'IteratorResult'. !!! error TS2322: Property 'value' is missing in type 'Promise>' but required in type 'IteratorYieldResult'. !!! related TS2728 /.ts/lib.es2015.iterable.d.ts:33:5: 'value' is declared here. diff --git a/tests/cases/compiler/customAsyncIterator.ts b/tests/cases/compiler/customAsyncIterator.ts new file mode 100644 index 00000000000..dcd1140f6b5 --- /dev/null +++ b/tests/cases/compiler/customAsyncIterator.ts @@ -0,0 +1,13 @@ +// @target: esnext + +// GH: https://github.com/microsoft/TypeScript/issues/33239 +class ConstantIterator implements AsyncIterator { + constructor(private constant: T) { + } + async next(value?: T): Promise> { + if (value != null) { + throw new Error("ConstantIterator.prototype.next may not take any values"); + } + return { value: this.constant, done: false }; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.1.ts b/tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.1.ts index f31f453ba5f..6d39be9cef7 100644 --- a/tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.1.ts +++ b/tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.1.ts @@ -124,3 +124,6 @@ async function * awaitedType1() { async function * awaitedType2() { const x = await Promise.resolve(1); } +async function * nextType1(): { next(...args: [] | [number | PromiseLike]): any } { + const x = yield; // `number | PromiseLike` (should not await TNext) +} From ba30fdc4ae961298d1ac6a3e0b6fc3d1ac1c0e74 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 18 Sep 2019 06:36:51 -0700 Subject: [PATCH 068/100] Attach flow nodes only when allowUnreachableCode !== true --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index cf93ee17ebd..c9d3d15b9af 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -672,7 +672,7 @@ namespace ts { bindJSDoc(node); return; } - if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement) { + if (node.kind >= SyntaxKind.FirstStatement && node.kind <= SyntaxKind.LastStatement && !options.allowUnreachableCode) { node.flowNode = currentFlow; } switch (node.kind) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9e331dd0854..7e9e8bd4b0e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -30539,8 +30539,7 @@ namespace ts { cancellationToken.throwIfCancellationRequested(); } } - if (kind >= SyntaxKind.FirstStatement && kind <= SyntaxKind.LastStatement && - !compilerOptions.allowUnreachableCode && node.flowNode && !isReachableFlowNode(node.flowNode)) { + if (kind >= SyntaxKind.FirstStatement && kind <= SyntaxKind.LastStatement && node.flowNode && !isReachableFlowNode(node.flowNode)) { errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, Diagnostics.Unreachable_code_detected); } From 1c20aa0b1abdfe60efa6cb08ad667f328daf74a8 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Wed, 18 Sep 2019 18:54:42 +0100 Subject: [PATCH 069/100] Narrow unknown under inequality when assumed false (#33488) --- src/compiler/checker.ts | 2 +- .../reference/unknownType2.errors.txt | 37 ++++++ tests/baselines/reference/unknownType2.js | 63 ++++++++++ .../baselines/reference/unknownType2.symbols | 105 ++++++++++++++++ tests/baselines/reference/unknownType2.types | 118 ++++++++++++++++++ .../conformance/types/unknown/unknownType2.ts | 37 ++++++ 6 files changed, 361 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9a8cf2f8038..c5787c3b29d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17453,7 +17453,7 @@ namespace ts { assumeTrue = !assumeTrue; } const valueType = getTypeOfExpression(value); - if ((type.flags & TypeFlags.Unknown) && (operator === SyntaxKind.EqualsEqualsEqualsToken) && assumeTrue) { + if ((type.flags & TypeFlags.Unknown) && assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken)) { if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) { return valueType; } diff --git a/tests/baselines/reference/unknownType2.errors.txt b/tests/baselines/reference/unknownType2.errors.txt index 5f08804b9e0..1469526182b 100644 --- a/tests/baselines/reference/unknownType2.errors.txt +++ b/tests/baselines/reference/unknownType2.errors.txt @@ -228,4 +228,41 @@ tests/cases/conformance/types/unknown/unknownType2.ts(216,13): error TS2322: Typ // Arguably this should be never. type End = isTrue> } + + // Repro from #33483 + + function f2(x: unknown): string | undefined { + if (x !== undefined && typeof x !== 'string') { + throw new Error(); + } + return x; + } + + function notNotEquals(u: unknown) { + if (u !== NumberEnum) { } + else { + const o: object = u; + } + + if (u !== NumberEnum.A) { } + else { + const a: NumberEnum.A = u; + } + + + if (u !== NumberEnum.A && u !== NumberEnum.B && u !== StringEnum.A) { } + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; + } + + // equivalent to + if (!(u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A)) { } + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; + } + } + + + + \ No newline at end of file diff --git a/tests/baselines/reference/unknownType2.js b/tests/baselines/reference/unknownType2.js index 2ec5b3ed205..cb1b0a58029 100644 --- a/tests/baselines/reference/unknownType2.js +++ b/tests/baselines/reference/unknownType2.js @@ -221,6 +221,43 @@ function switchResponseWrong(x: unknown): SomeResponse { // Arguably this should be never. type End = isTrue> } + +// Repro from #33483 + +function f2(x: unknown): string | undefined { + if (x !== undefined && typeof x !== 'string') { + throw new Error(); + } + return x; +} + +function notNotEquals(u: unknown) { + if (u !== NumberEnum) { } + else { + const o: object = u; + } + + if (u !== NumberEnum.A) { } + else { + const a: NumberEnum.A = u; + } + + + if (u !== NumberEnum.A && u !== NumberEnum.B && u !== StringEnum.A) { } + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; + } + + // equivalent to + if (!(u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A)) { } + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; + } +} + + + + //// [unknownType2.js] @@ -388,3 +425,29 @@ function switchResponseWrong(x) { throw new Error('Can you repeat the question?'); } } +// Repro from #33483 +function f2(x) { + if (x !== undefined && typeof x !== 'string') { + throw new Error(); + } + return x; +} +function notNotEquals(u) { + if (u !== NumberEnum) { } + else { + var o = u; + } + if (u !== NumberEnum.A) { } + else { + var a = u; + } + if (u !== NumberEnum.A && u !== NumberEnum.B && u !== StringEnum.A) { } + else { + var aOrB = u; + } + // equivalent to + if (!(u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A)) { } + else { + var aOrB = u; + } +} diff --git a/tests/baselines/reference/unknownType2.symbols b/tests/baselines/reference/unknownType2.symbols index 6e871bd4de4..19a1c7fca6e 100644 --- a/tests/baselines/reference/unknownType2.symbols +++ b/tests/baselines/reference/unknownType2.symbols @@ -582,3 +582,108 @@ function switchResponseWrong(x: unknown): SomeResponse { >x : Symbol(x, Decl(unknownType2.ts, 210, 29)) } +// Repro from #33483 + +function f2(x: unknown): string | undefined { +>f2 : Symbol(f2, Decl(unknownType2.ts, 221, 1)) +>x : Symbol(x, Decl(unknownType2.ts, 225, 12)) + + if (x !== undefined && typeof x !== 'string') { +>x : Symbol(x, Decl(unknownType2.ts, 225, 12)) +>undefined : Symbol(undefined) +>x : Symbol(x, Decl(unknownType2.ts, 225, 12)) + + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } + return x; +>x : Symbol(x, Decl(unknownType2.ts, 225, 12)) +} + +function notNotEquals(u: unknown) { +>notNotEquals : Symbol(notNotEquals, Decl(unknownType2.ts, 230, 1)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) + + if (u !== NumberEnum) { } +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) + + else { + const o: object = u; +>o : Symbol(o, Decl(unknownType2.ts, 235, 13)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) + } + + if (u !== NumberEnum.A) { } +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) +>NumberEnum.A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) + + else { + const a: NumberEnum.A = u; +>a : Symbol(a, Decl(unknownType2.ts, 240, 13)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) + } + + + if (u !== NumberEnum.A && u !== NumberEnum.B && u !== StringEnum.A) { } +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) +>NumberEnum.A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) +>NumberEnum.B : Symbol(NumberEnum.B, Decl(unknownType2.ts, 93, 6)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>B : Symbol(NumberEnum.B, Decl(unknownType2.ts, 93, 6)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) +>StringEnum.A : Symbol(StringEnum.A, Decl(unknownType2.ts, 98, 17)) +>StringEnum : Symbol(StringEnum, Decl(unknownType2.ts, 96, 1)) +>A : Symbol(StringEnum.A, Decl(unknownType2.ts, 98, 17)) + + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; +>aOrB : Symbol(aOrB, Decl(unknownType2.ts, 246, 13)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>B : Symbol(NumberEnum.B, Decl(unknownType2.ts, 93, 6)) +>StringEnum : Symbol(StringEnum, Decl(unknownType2.ts, 96, 1)) +>A : Symbol(StringEnum.A, Decl(unknownType2.ts, 98, 17)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) + } + + // equivalent to + if (!(u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A)) { } +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) +>NumberEnum.A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) +>NumberEnum.B : Symbol(NumberEnum.B, Decl(unknownType2.ts, 93, 6)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>B : Symbol(NumberEnum.B, Decl(unknownType2.ts, 93, 6)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) +>StringEnum.A : Symbol(StringEnum.A, Decl(unknownType2.ts, 98, 17)) +>StringEnum : Symbol(StringEnum, Decl(unknownType2.ts, 96, 1)) +>A : Symbol(StringEnum.A, Decl(unknownType2.ts, 98, 17)) + + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; +>aOrB : Symbol(aOrB, Decl(unknownType2.ts, 252, 13)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>A : Symbol(NumberEnum.A, Decl(unknownType2.ts, 92, 17)) +>NumberEnum : Symbol(NumberEnum, Decl(unknownType2.ts, 90, 1)) +>B : Symbol(NumberEnum.B, Decl(unknownType2.ts, 93, 6)) +>StringEnum : Symbol(StringEnum, Decl(unknownType2.ts, 96, 1)) +>A : Symbol(StringEnum.A, Decl(unknownType2.ts, 98, 17)) +>u : Symbol(u, Decl(unknownType2.ts, 232, 22)) + } +} + + + + + diff --git a/tests/baselines/reference/unknownType2.types b/tests/baselines/reference/unknownType2.types index 7fc3c3d1038..ce3332138d5 100644 --- a/tests/baselines/reference/unknownType2.types +++ b/tests/baselines/reference/unknownType2.types @@ -627,3 +627,121 @@ function switchResponseWrong(x: unknown): SomeResponse { >x : unknown } +// Repro from #33483 + +function f2(x: unknown): string | undefined { +>f2 : (x: unknown) => string | undefined +>x : unknown + + if (x !== undefined && typeof x !== 'string') { +>x !== undefined && typeof x !== 'string' : boolean +>x !== undefined : boolean +>x : unknown +>undefined : undefined +>typeof x !== 'string' : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>'string' : "string" + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor + } + return x; +>x : string | undefined +} + +function notNotEquals(u: unknown) { +>notNotEquals : (u: unknown) => void +>u : unknown + + if (u !== NumberEnum) { } +>u !== NumberEnum : boolean +>u : unknown +>NumberEnum : typeof NumberEnum + + else { + const o: object = u; +>o : object +>u : object + } + + if (u !== NumberEnum.A) { } +>u !== NumberEnum.A : boolean +>u : unknown +>NumberEnum.A : NumberEnum.A +>NumberEnum : typeof NumberEnum +>A : NumberEnum.A + + else { + const a: NumberEnum.A = u; +>a : NumberEnum.A +>NumberEnum : any +>u : NumberEnum.A + } + + + if (u !== NumberEnum.A && u !== NumberEnum.B && u !== StringEnum.A) { } +>u !== NumberEnum.A && u !== NumberEnum.B && u !== StringEnum.A : boolean +>u !== NumberEnum.A && u !== NumberEnum.B : boolean +>u !== NumberEnum.A : boolean +>u : unknown +>NumberEnum.A : NumberEnum.A +>NumberEnum : typeof NumberEnum +>A : NumberEnum.A +>u !== NumberEnum.B : boolean +>u : unknown +>NumberEnum.B : NumberEnum.B +>NumberEnum : typeof NumberEnum +>B : NumberEnum.B +>u !== StringEnum.A : boolean +>u : unknown +>StringEnum.A : StringEnum.A +>StringEnum : typeof StringEnum +>A : StringEnum.A + + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; +>aOrB : NumberEnum.A | NumberEnum.B | StringEnum.A +>NumberEnum : any +>NumberEnum : any +>StringEnum : any +>u : NumberEnum.A | NumberEnum.B | StringEnum.A + } + + // equivalent to + if (!(u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A)) { } +>!(u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A) : boolean +>(u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A) : boolean +>u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A : boolean +>u === NumberEnum.A || u === NumberEnum.B : boolean +>u === NumberEnum.A : boolean +>u : unknown +>NumberEnum.A : NumberEnum.A +>NumberEnum : typeof NumberEnum +>A : NumberEnum.A +>u === NumberEnum.B : boolean +>u : unknown +>NumberEnum.B : NumberEnum.B +>NumberEnum : typeof NumberEnum +>B : NumberEnum.B +>u === StringEnum.A : boolean +>u : unknown +>StringEnum.A : StringEnum.A +>StringEnum : typeof StringEnum +>A : StringEnum.A + + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; +>aOrB : NumberEnum.A | NumberEnum.B | StringEnum.A +>NumberEnum : any +>NumberEnum : any +>StringEnum : any +>u : NumberEnum.A | NumberEnum.B | StringEnum.A + } +} + + + + + diff --git a/tests/cases/conformance/types/unknown/unknownType2.ts b/tests/cases/conformance/types/unknown/unknownType2.ts index b3d16654b80..7da3093634e 100644 --- a/tests/cases/conformance/types/unknown/unknownType2.ts +++ b/tests/cases/conformance/types/unknown/unknownType2.ts @@ -222,3 +222,40 @@ function switchResponseWrong(x: unknown): SomeResponse { // Arguably this should be never. type End = isTrue> } + +// Repro from #33483 + +function f2(x: unknown): string | undefined { + if (x !== undefined && typeof x !== 'string') { + throw new Error(); + } + return x; +} + +function notNotEquals(u: unknown) { + if (u !== NumberEnum) { } + else { + const o: object = u; + } + + if (u !== NumberEnum.A) { } + else { + const a: NumberEnum.A = u; + } + + + if (u !== NumberEnum.A && u !== NumberEnum.B && u !== StringEnum.A) { } + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; + } + + // equivalent to + if (!(u === NumberEnum.A || u === NumberEnum.B || u === StringEnum.A)) { } + else { + const aOrB: NumberEnum.A | NumberEnum.B | StringEnum.A = u; + } +} + + + + From 683e2810403079c1b99ac39c09698e61a84c70ce Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 18 Sep 2019 13:14:39 -0700 Subject: [PATCH 070/100] Reintroduce cloneInferredPartOfContext to fix overloaded inferences with returnMappers (#33478) --- src/compiler/checker.ts | 9 +- .../twiceNestedKeyofIndexInference.js | 43 ++++++ .../twiceNestedKeyofIndexInference.symbols | 139 ++++++++++++++++++ .../twiceNestedKeyofIndexInference.types | 76 ++++++++++ .../twiceNestedKeyofIndexInference.ts | 32 ++++ 5 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/twiceNestedKeyofIndexInference.js create mode 100644 tests/baselines/reference/twiceNestedKeyofIndexInference.symbols create mode 100644 tests/baselines/reference/twiceNestedKeyofIndexInference.types create mode 100644 tests/cases/compiler/twiceNestedKeyofIndexInference.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c5787c3b29d..3273b7cb185 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15408,6 +15408,13 @@ namespace ts { }; } + function cloneInferredPartOfContext(context: InferenceContext): InferenceContext | undefined { + const inferences = filter(context.inferences, hasInferenceCandidates); + return inferences.length ? + createInferenceContextWorker(map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) : + undefined; + } + function getMapperFromContext(context: T): TypeMapper | T & undefined { return context && context.mapper; } @@ -21465,7 +21472,7 @@ namespace ts { const returnContext = createInferenceContext(signature.typeParameters!, signature, context.flags); const returnSourceType = instantiateType(contextualType, outerContext && outerContext.returnMapper); inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType); - context.returnMapper = some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(returnContext) : undefined; + context.returnMapper = some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(cloneInferredPartOfContext(returnContext)) : undefined; } } diff --git a/tests/baselines/reference/twiceNestedKeyofIndexInference.js b/tests/baselines/reference/twiceNestedKeyofIndexInference.js new file mode 100644 index 00000000000..ed4f0c6bfb5 --- /dev/null +++ b/tests/baselines/reference/twiceNestedKeyofIndexInference.js @@ -0,0 +1,43 @@ +//// [twiceNestedKeyofIndexInference.ts] +type Set1 = T extends any[] ? T : Pick> & { + [SK1 in K1]-?: Required>; +}[K1]; + +type Set2 = T extends any[] ? T : Pick> & { + [SK1 in K1]-?: Required<{ + [key in K1]: Set1; + }>; +}[K1]; + +declare function set(source: T, path: [K1], value: T[K1]): Set1; + +declare function set(source: T, path: [K1, K2], value: T[K1][K2]): Set2; + + +interface State { + a: { + b: string; + c: number; + }; + d: boolean; +} + +const state: State = { + a: { + b: "", + c: 0, + }, + d: false, +}; + +const newState: State = set(state, ["a", 'b'], 'why'); // shouldn't be an error + +//// [twiceNestedKeyofIndexInference.js] +var state = { + a: { + b: "", + c: 0 + }, + d: false +}; +var newState = set(state, ["a", 'b'], 'why'); // shouldn't be an error diff --git a/tests/baselines/reference/twiceNestedKeyofIndexInference.symbols b/tests/baselines/reference/twiceNestedKeyofIndexInference.symbols new file mode 100644 index 00000000000..57fa8e738b2 --- /dev/null +++ b/tests/baselines/reference/twiceNestedKeyofIndexInference.symbols @@ -0,0 +1,139 @@ +=== tests/cases/compiler/twiceNestedKeyofIndexInference.ts === +type Set1 = T extends any[] ? T : Pick> & { +>Set1 : Symbol(Set1, Decl(twiceNestedKeyofIndexInference.ts, 0, 0)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 0, 10)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 0, 12)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 0, 10)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 0, 10)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 0, 10)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 0, 10)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 0, 10)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 0, 12)) + + [SK1 in K1]-?: Required>; +>SK1 : Symbol(SK1, Decl(twiceNestedKeyofIndexInference.ts, 1, 5)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 0, 12)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 0, 10)) +>SK1 : Symbol(SK1, Decl(twiceNestedKeyofIndexInference.ts, 1, 5)) + +}[K1]; +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 0, 12)) + +type Set2 = T extends any[] ? T : Pick> & { +>Set2 : Symbol(Set2, Decl(twiceNestedKeyofIndexInference.ts, 2, 6)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 4, 10)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 4, 12)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 4, 10)) +>K2 : Symbol(K2, Decl(twiceNestedKeyofIndexInference.ts, 4, 32)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 4, 10)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 4, 12)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 4, 10)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 4, 10)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 4, 10)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 4, 10)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 4, 12)) + + [SK1 in K1]-?: Required<{ +>SK1 : Symbol(SK1, Decl(twiceNestedKeyofIndexInference.ts, 5, 5)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 4, 12)) +>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --)) + + [key in K1]: Set1; +>key : Symbol(key, Decl(twiceNestedKeyofIndexInference.ts, 6, 9)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 4, 12)) +>Set1 : Symbol(Set1, Decl(twiceNestedKeyofIndexInference.ts, 0, 0)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 4, 10)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 4, 12)) +>K2 : Symbol(K2, Decl(twiceNestedKeyofIndexInference.ts, 4, 32)) + + }>; +}[K1]; +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 4, 12)) + +declare function set(source: T, path: [K1], value: T[K1]): Set1; +>set : Symbol(set, Decl(twiceNestedKeyofIndexInference.ts, 8, 6), Decl(twiceNestedKeyofIndexInference.ts, 10, 94)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 10, 21)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 10, 23)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 10, 21)) +>source : Symbol(source, Decl(twiceNestedKeyofIndexInference.ts, 10, 44)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 10, 21)) +>path : Symbol(path, Decl(twiceNestedKeyofIndexInference.ts, 10, 54)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 10, 23)) +>value : Symbol(value, Decl(twiceNestedKeyofIndexInference.ts, 10, 66)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 10, 21)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 10, 23)) +>Set1 : Symbol(Set1, Decl(twiceNestedKeyofIndexInference.ts, 0, 0)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 10, 21)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 10, 23)) + +declare function set(source: T, path: [K1, K2], value: T[K1][K2]): Set2; +>set : Symbol(set, Decl(twiceNestedKeyofIndexInference.ts, 8, 6), Decl(twiceNestedKeyofIndexInference.ts, 10, 94)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 12, 21)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 12, 23)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 12, 21)) +>K2 : Symbol(K2, Decl(twiceNestedKeyofIndexInference.ts, 12, 43)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 12, 21)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 12, 23)) +>source : Symbol(source, Decl(twiceNestedKeyofIndexInference.ts, 12, 68)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 12, 21)) +>path : Symbol(path, Decl(twiceNestedKeyofIndexInference.ts, 12, 78)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 12, 23)) +>K2 : Symbol(K2, Decl(twiceNestedKeyofIndexInference.ts, 12, 43)) +>value : Symbol(value, Decl(twiceNestedKeyofIndexInference.ts, 12, 94)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 12, 21)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 12, 23)) +>K2 : Symbol(K2, Decl(twiceNestedKeyofIndexInference.ts, 12, 43)) +>Set2 : Symbol(Set2, Decl(twiceNestedKeyofIndexInference.ts, 2, 6)) +>T : Symbol(T, Decl(twiceNestedKeyofIndexInference.ts, 12, 21)) +>K1 : Symbol(K1, Decl(twiceNestedKeyofIndexInference.ts, 12, 23)) +>K2 : Symbol(K2, Decl(twiceNestedKeyofIndexInference.ts, 12, 43)) + + +interface State { +>State : Symbol(State, Decl(twiceNestedKeyofIndexInference.ts, 12, 130)) + + a: { +>a : Symbol(State.a, Decl(twiceNestedKeyofIndexInference.ts, 15, 17)) + + b: string; +>b : Symbol(b, Decl(twiceNestedKeyofIndexInference.ts, 16, 8)) + + c: number; +>c : Symbol(c, Decl(twiceNestedKeyofIndexInference.ts, 17, 18)) + + }; + d: boolean; +>d : Symbol(State.d, Decl(twiceNestedKeyofIndexInference.ts, 19, 6)) +} + +const state: State = { +>state : Symbol(state, Decl(twiceNestedKeyofIndexInference.ts, 23, 5)) +>State : Symbol(State, Decl(twiceNestedKeyofIndexInference.ts, 12, 130)) + + a: { +>a : Symbol(a, Decl(twiceNestedKeyofIndexInference.ts, 23, 22)) + + b: "", +>b : Symbol(b, Decl(twiceNestedKeyofIndexInference.ts, 24, 8)) + + c: 0, +>c : Symbol(c, Decl(twiceNestedKeyofIndexInference.ts, 25, 14)) + + }, + d: false, +>d : Symbol(d, Decl(twiceNestedKeyofIndexInference.ts, 27, 6)) + +}; + +const newState: State = set(state, ["a", 'b'], 'why'); // shouldn't be an error +>newState : Symbol(newState, Decl(twiceNestedKeyofIndexInference.ts, 31, 5)) +>State : Symbol(State, Decl(twiceNestedKeyofIndexInference.ts, 12, 130)) +>set : Symbol(set, Decl(twiceNestedKeyofIndexInference.ts, 8, 6), Decl(twiceNestedKeyofIndexInference.ts, 10, 94)) +>state : Symbol(state, Decl(twiceNestedKeyofIndexInference.ts, 23, 5)) + diff --git a/tests/baselines/reference/twiceNestedKeyofIndexInference.types b/tests/baselines/reference/twiceNestedKeyofIndexInference.types new file mode 100644 index 00000000000..68622038e72 --- /dev/null +++ b/tests/baselines/reference/twiceNestedKeyofIndexInference.types @@ -0,0 +1,76 @@ +=== tests/cases/compiler/twiceNestedKeyofIndexInference.ts === +type Set1 = T extends any[] ? T : Pick> & { +>Set1 : Set1 + + [SK1 in K1]-?: Required>; +}[K1]; + +type Set2 = T extends any[] ? T : Pick> & { +>Set2 : Set2 + + [SK1 in K1]-?: Required<{ + [key in K1]: Set1; + }>; +}[K1]; + +declare function set(source: T, path: [K1], value: T[K1]): Set1; +>set : { (source: T, path: [K1], value: T[K1]): Set1; (source: T, path: [K1, K2], value: T[K1][K2]): Set2; } +>source : T +>path : [K1] +>value : T[K1] + +declare function set(source: T, path: [K1, K2], value: T[K1][K2]): Set2; +>set : { (source: T, path: [K1], value: T[K1]): Set1; (source: T, path: [K1, K2], value: T[K1][K2]): Set2; } +>source : T +>path : [K1, K2] +>value : T[K1][K2] + + +interface State { + a: { +>a : { b: string; c: number; } + + b: string; +>b : string + + c: number; +>c : number + + }; + d: boolean; +>d : boolean +} + +const state: State = { +>state : State +>{ a: { b: "", c: 0, }, d: false,} : { a: { b: string; c: number; }; d: false; } + + a: { +>a : { b: string; c: number; } +>{ b: "", c: 0, } : { b: string; c: number; } + + b: "", +>b : string +>"" : "" + + c: 0, +>c : number +>0 : 0 + + }, + d: false, +>d : false +>false : false + +}; + +const newState: State = set(state, ["a", 'b'], 'why'); // shouldn't be an error +>newState : State +>set(state, ["a", 'b'], 'why') : Pick & Required<{ a: Pick<{ b: string; c: number; }, "c"> & Required>; }> +>set : { (source: T, path: [K1], value: T[K1]): Set1; (source: T, path: [K1, K2], value: T[K1][K2]): Set2; } +>state : State +>["a", 'b'] : ["a", "b"] +>"a" : "a" +>'b' : "b" +>'why' : "why" + diff --git a/tests/cases/compiler/twiceNestedKeyofIndexInference.ts b/tests/cases/compiler/twiceNestedKeyofIndexInference.ts new file mode 100644 index 00000000000..35fb39b009e --- /dev/null +++ b/tests/cases/compiler/twiceNestedKeyofIndexInference.ts @@ -0,0 +1,32 @@ +type Set1 = T extends any[] ? T : Pick> & { + [SK1 in K1]-?: Required>; +}[K1]; + +type Set2 = T extends any[] ? T : Pick> & { + [SK1 in K1]-?: Required<{ + [key in K1]: Set1; + }>; +}[K1]; + +declare function set(source: T, path: [K1], value: T[K1]): Set1; + +declare function set(source: T, path: [K1, K2], value: T[K1][K2]): Set2; + + +interface State { + a: { + b: string; + c: number; + }; + d: boolean; +} + +const state: State = { + a: { + b: "", + c: 0, + }, + d: false, +}; + +const newState: State = set(state, ["a", 'b'], 'why'); // shouldn't be an error \ No newline at end of file From 5e06bea48155d3ffea13917a3bda72b09bf18488 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 18 Sep 2019 13:56:24 -0700 Subject: [PATCH 071/100] =?UTF-8?q?getConstraintDeclaration=20gets=20the?= =?UTF-8?q?=20first=20declaration=20with=20a=20constraint=E2=80=A6=20(#334?= =?UTF-8?q?26)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * getConstraintDeclaration gets the first declaration with a constraint, rather than just the first declaration * Add type annotation * Update comment --- src/compiler/checker.ts | 14 +++-- ...UnconstrainedNoErrorIrrespectiveOfOrder.js | 28 ++++++++++ ...strainedNoErrorIrrespectiveOfOrder.symbols | 51 +++++++++++++++++++ ...onstrainedNoErrorIrrespectiveOfOrder.types | 27 ++++++++++ ...erfacesWithDifferentConstraints.errors.txt | 10 +--- ...nericInterfacesWithDifferentConstraints.js | 2 +- ...InterfacesWithDifferentConstraints.symbols | 2 +- ...icInterfacesWithDifferentConstraints.types | 2 +- ...UnconstrainedNoErrorIrrespectiveOfOrder.ts | 19 +++++++ ...nericInterfacesWithDifferentConstraints.ts | 2 +- 10 files changed, 137 insertions(+), 20 deletions(-) create mode 100644 tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.js create mode 100644 tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.symbols create mode 100644 tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.types create mode 100644 tests/cases/compiler/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3273b7cb185..463d00c13e2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8971,9 +8971,8 @@ namespace ts { return undefined; } - function getConstraintDeclaration(type: TypeParameter) { - const decl = type.symbol && getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter); - return decl && getEffectiveConstraintOfTypeParameter(decl); + function getConstraintDeclaration(type: TypeParameter): TypeNode | undefined { + return mapDefined(filter(type.symbol && type.symbol.declarations, isTypeParameterDeclaration), getEffectiveConstraintOfTypeParameter)[0]; } function getInferredTypeParameterConstraint(typeParameter: TypeParameter) { @@ -29242,11 +29241,10 @@ namespace ts { const constraint = getEffectiveConstraintOfTypeParameter(source); const sourceConstraint = constraint && getTypeFromTypeNode(constraint); const targetConstraint = getConstraintOfTypeParameter(target); - if (sourceConstraint) { - // relax check if later interface augmentation has no constraint - if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) { - return false; - } + // relax check if later interface augmentation has no constraint, it's more broad and is OK to merge with + // a more constrained interface (this could be generalized to a full heirarchy check, but that's maybe overkill) + if (sourceConstraint && targetConstraint && !isTypeIdenticalTo(sourceConstraint, targetConstraint)) { + return false; } // If the type parameter node has a default and it is not identical to the default diff --git a/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.js b/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.js new file mode 100644 index 00000000000..a4241186639 --- /dev/null +++ b/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.js @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.ts] //// + +//// [working.ts] +// minmal samples from #33395 +export namespace ns { + interface Function any> { + throttle(): Function; + } + interface Function { + unary(): Function<() => ReturnType>; + } +} +//// [regression.ts] +export namespace ns { + interface Function { + unary(): Function<() => ReturnType>; + } + interface Function any> { + throttle(): Function; + } +} + +//// [working.js] +"use strict"; +exports.__esModule = true; +//// [regression.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.symbols b/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.symbols new file mode 100644 index 00000000000..5dc01da7c48 --- /dev/null +++ b/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.symbols @@ -0,0 +1,51 @@ +=== tests/cases/compiler/working.ts === +// minmal samples from #33395 +export namespace ns { +>ns : Symbol(ns, Decl(working.ts, 0, 0)) + + interface Function any> { +>Function : Symbol(Function, Decl(working.ts, 1, 21), Decl(working.ts, 4, 5)) +>T : Symbol(T, Decl(working.ts, 2, 23), Decl(working.ts, 5, 23)) +>args : Symbol(args, Decl(working.ts, 2, 34)) + + throttle(): Function; +>throttle : Symbol(Function.throttle, Decl(working.ts, 2, 57)) +>Function : Symbol(Function, Decl(working.ts, 1, 21), Decl(working.ts, 4, 5)) +>T : Symbol(T, Decl(working.ts, 2, 23), Decl(working.ts, 5, 23)) + } + interface Function { +>Function : Symbol(Function, Decl(working.ts, 1, 21), Decl(working.ts, 4, 5)) +>T : Symbol(T, Decl(working.ts, 2, 23), Decl(working.ts, 5, 23)) + + unary(): Function<() => ReturnType>; +>unary : Symbol(Function.unary, Decl(working.ts, 5, 27)) +>Function : Symbol(Function, Decl(working.ts, 1, 21), Decl(working.ts, 4, 5)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(working.ts, 2, 23), Decl(working.ts, 5, 23)) + } +} +=== tests/cases/compiler/regression.ts === +export namespace ns { +>ns : Symbol(ns, Decl(regression.ts, 0, 0)) + + interface Function { +>Function : Symbol(Function, Decl(regression.ts, 0, 21), Decl(regression.ts, 3, 5)) +>T : Symbol(T, Decl(regression.ts, 1, 23), Decl(regression.ts, 4, 23)) + + unary(): Function<() => ReturnType>; +>unary : Symbol(Function.unary, Decl(regression.ts, 1, 27)) +>Function : Symbol(Function, Decl(regression.ts, 0, 21), Decl(regression.ts, 3, 5)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(regression.ts, 1, 23), Decl(regression.ts, 4, 23)) + } + interface Function any> { +>Function : Symbol(Function, Decl(regression.ts, 0, 21), Decl(regression.ts, 3, 5)) +>T : Symbol(T, Decl(regression.ts, 1, 23), Decl(regression.ts, 4, 23)) +>args : Symbol(args, Decl(regression.ts, 4, 34)) + + throttle(): Function; +>throttle : Symbol(Function.throttle, Decl(regression.ts, 4, 57)) +>Function : Symbol(Function, Decl(regression.ts, 0, 21), Decl(regression.ts, 3, 5)) +>T : Symbol(T, Decl(regression.ts, 1, 23), Decl(regression.ts, 4, 23)) + } +} diff --git a/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.types b/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.types new file mode 100644 index 00000000000..e42e438c983 --- /dev/null +++ b/tests/baselines/reference/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/working.ts === +// minmal samples from #33395 +export namespace ns { + interface Function any> { +>args : any + + throttle(): Function; +>throttle : () => Function + } + interface Function { + unary(): Function<() => ReturnType>; +>unary : () => Function<() => ReturnType> + } +} +=== tests/cases/compiler/regression.ts === +export namespace ns { + interface Function { + unary(): Function<() => ReturnType>; +>unary : () => Function<() => ReturnType> + } + interface Function any> { +>args : any + + throttle(): Function; +>throttle : () => Function + } +} diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt index 21a35e0553b..edc33d6b1ba 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt @@ -4,11 +4,9 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(14,15): error TS2428: All declarations of 'B' must have identical type parameters. tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(32,22): error TS2428: All declarations of 'A' must have identical type parameters. tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(38,22): error TS2428: All declarations of 'A' must have identical type parameters. -tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(53,11): error TS2428: All declarations of 'C' must have identical type parameters. -tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(57,11): error TS2428: All declarations of 'C' must have identical type parameters. -==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (8 errors) ==== +==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (6 errors) ==== interface A { ~ !!! error TS2428: All declarations of 'A' must have identical type parameters. @@ -74,14 +72,10 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi } interface C { - ~ -!!! error TS2428: All declarations of 'C' must have identical type parameters. x: T; } - interface C { // error - ~ -!!! error TS2428: All declarations of 'C' must have identical type parameters. + interface C { // ok y: T; } diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js index 5b1964b2891..7e62915cb54 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.js @@ -55,7 +55,7 @@ interface C { x: T; } -interface C { // error +interface C { // ok y: T; } diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols index a1ad41441bd..6dd5de33354 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.symbols @@ -137,7 +137,7 @@ interface C { >T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) } -interface C { // error +interface C { // ok >C : Symbol(C, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 50, 1), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 54, 1)) >T : Symbol(T, Decl(twoGenericInterfacesWithDifferentConstraints.ts, 52, 12), Decl(twoGenericInterfacesWithDifferentConstraints.ts, 56, 12)) diff --git a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types index 70a8be8cb3a..87877311b53 100644 --- a/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types +++ b/tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.types @@ -70,7 +70,7 @@ interface C { >x : T } -interface C { // error +interface C { // ok y: T; >y : T } diff --git a/tests/cases/compiler/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.ts b/tests/cases/compiler/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.ts new file mode 100644 index 00000000000..7bbce8e8b03 --- /dev/null +++ b/tests/cases/compiler/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.ts @@ -0,0 +1,19 @@ +// @filename: working.ts +// minmal samples from #33395 +export namespace ns { + interface Function any> { + throttle(): Function; + } + interface Function { + unary(): Function<() => ReturnType>; + } +} +// @filename: regression.ts +export namespace ns { + interface Function { + unary(): Function<() => ReturnType>; + } + interface Function any> { + throttle(): Function; + } +} \ No newline at end of file diff --git a/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts b/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts index 4c698626eb0..6963277915a 100644 --- a/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts +++ b/tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts @@ -54,7 +54,7 @@ interface C { x: T; } -interface C { // error +interface C { // ok y: T; } From e430f2a81cafb3fe31a32c42321c769a3d084056 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 18 Sep 2019 14:02:41 -0700 Subject: [PATCH 072/100] Add output file names api for supporting ts-loader --- src/compiler/builder.ts | 4 +- src/compiler/emitter.ts | 90 +++++++++++++------ src/compiler/program.ts | 4 +- src/compiler/tsbuild.ts | 2 +- src/compiler/watch.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 2 + tests/baselines/reference/api/typescript.d.ts | 2 + 7 files changed, 71 insertions(+), 35 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 653832c8dbd..a67a6a246cc 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -257,7 +257,7 @@ namespace ts { function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newProgram: Program, getCanonicalFileName: GetCanonicalFileName): readonly Diagnostic[] { if (!diagnostics.length) return emptyArray; - const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getOutputPathForBuildInfo(newProgram.getCompilerOptions())!, newProgram.getCurrentDirectory())); + const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions())!, newProgram.getCurrentDirectory())); return diagnostics.map(diagnostic => { const result: Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath); result.reportsUnnecessary = diagnostic.reportsUnnecessary; @@ -656,7 +656,7 @@ namespace ts { function getProgramBuildInfo(state: Readonly, getCanonicalFileName: GetCanonicalFileName): ProgramBuildInfo | undefined { if (state.compilerOptions.outFile || state.compilerOptions.out) return undefined; const currentDirectory = Debug.assertDefined(state.program).getCurrentDirectory(); - const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getOutputPathForBuildInfo(state.compilerOptions)!, currentDirectory)); + const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory)); const fileInfos: MapLike = {}; state.fileInfos.forEach((value, key) => { const signature = state.currentAffectedFilesSignatures && state.currentAffectedFilesSignatures.get(key); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 91df5402be3..7bad8359b26 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -45,14 +45,13 @@ namespace ts { } } if (includeBuildInfo) { - const buildInfoPath = getOutputPathForBuildInfo(host.getCompilerOptions()); + const buildInfoPath = getTsBuildInfoEmitOutputFilePath(host.getCompilerOptions()); if (buildInfoPath) return action({ buildInfoPath }, /*sourceFileOrBundle*/ undefined); } } } - /*@internal*/ - export function getOutputPathForBuildInfo(options: CompilerOptions) { + export function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions) { const configFile = options.configFilePath; if (!isIncrementalCompilation(options)) return undefined; if (options.tsBuildInfoFile) return options.tsBuildInfoFile; @@ -80,7 +79,7 @@ namespace ts { const sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options); const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(outPath) + Extension.Dts : undefined; const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined; - const buildInfoPath = getOutputPathForBuildInfo(options); + const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options); return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath }; } @@ -170,38 +169,71 @@ namespace ts { undefined; } + function createAddOutput() { + let outputs: string[] | undefined; + return { addOutput, getOutputs }; + function addOutput(path: string | undefined) { + if (path) { + (outputs || (outputs = [])).push(path); + } + } + function getOutputs(): readonly string[] { + return outputs || emptyArray; + } + } + + function getSingleOutputFileNames(configFile: ParsedCommandLine, addOutput: ReturnType["addOutput"]) { + const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false); + addOutput(jsFilePath); + addOutput(sourceMapFilePath); + addOutput(declarationFilePath); + addOutput(declarationMapPath); + addOutput(buildInfoPath); + } + + function getOwnOutputFileNames(configFile: ParsedCommandLine, inputFileName: string, ignoreCase: boolean, addOutput: ReturnType["addOutput"]) { + if (fileExtensionIs(inputFileName, Extension.Dts)) return; + const js = getOutputJSFileName(inputFileName, configFile, ignoreCase); + addOutput(js); + if (fileExtensionIs(inputFileName, Extension.Json)) return; + if (js && configFile.options.sourceMap) { + addOutput(`${js}.map`); + } + if (getEmitDeclarations(configFile.options) && hasTSFileExtension(inputFileName)) { + const dts = getOutputDeclarationFileName(inputFileName, configFile, ignoreCase); + addOutput(dts); + if (configFile.options.declarationMap) { + addOutput(`${dts}.map`); + } + } + } + /*@internal*/ export function getAllProjectOutputs(configFile: ParsedCommandLine, ignoreCase: boolean): readonly string[] { - let outputs: string[] | undefined; - const addOutput = (path: string | undefined) => path && (outputs || (outputs = [])).push(path); + const { addOutput, getOutputs } = createAddOutput(); if (configFile.options.outFile || configFile.options.out) { - const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false); - addOutput(jsFilePath); - addOutput(sourceMapFilePath); - addOutput(declarationFilePath); - addOutput(declarationMapPath); - addOutput(buildInfoPath); + getSingleOutputFileNames(configFile, addOutput); } else { for (const inputFileName of configFile.fileNames) { - if (fileExtensionIs(inputFileName, Extension.Dts)) continue; - const js = getOutputJSFileName(inputFileName, configFile, ignoreCase); - addOutput(js); - if (fileExtensionIs(inputFileName, Extension.Json)) continue; - if (js && configFile.options.sourceMap) { - addOutput(`${js}.map`); - } - if (getEmitDeclarations(configFile.options) && hasTSFileExtension(inputFileName)) { - const dts = getOutputDeclarationFileName(inputFileName, configFile, ignoreCase); - addOutput(dts); - if (configFile.options.declarationMap) { - addOutput(`${dts}.map`); - } - } + getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput); } - addOutput(getOutputPathForBuildInfo(configFile.options)); + addOutput(getTsBuildInfoEmitOutputFilePath(configFile.options)); } - return outputs || emptyArray; + return getOutputs(); + } + + export function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[] { + inputFileName = normalizePath(inputFileName); + Debug.assert(contains(commandLine.fileNames, inputFileName), `Expected fileName to be present in command line`); + const { addOutput, getOutputs } = createAddOutput(); + if (commandLine.options.outFile || commandLine.options.out) { + getSingleOutputFileNames(commandLine, addOutput); + } + else { + getOwnOutputFileNames(commandLine, inputFileName, ignoreCase, addOutput); + } + return getOutputs(); } /*@internal*/ @@ -220,7 +252,7 @@ namespace ts { return getOutputDeclarationFileName(inputFileName, configFile, ignoreCase); } } - const buildInfoPath = getOutputPathForBuildInfo(configFile.options); + const buildInfoPath = getTsBuildInfoEmitOutputFilePath(configFile.options); if (buildInfoPath) return buildInfoPath; return Debug.fail(`project ${configFile.options.configFilePath} expected to have at least one output`); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 68eccdff307..427ab577bf3 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3108,7 +3108,7 @@ namespace ts { } function verifyProjectReferences() { - const buildInfoPath = !options.noEmit && !options.suppressOutputPathCheck ? getOutputPathForBuildInfo(options) : undefined; + const buildInfoPath = !options.noEmit && !options.suppressOutputPathCheck ? getTsBuildInfoEmitOutputFilePath(options) : undefined; forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => { const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index]; const parentFile = parent && parent.sourceFile as JsonSourceFile; @@ -3135,7 +3135,7 @@ namespace ts { createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path); } } - if (!parent && buildInfoPath && buildInfoPath === getOutputPathForBuildInfo(options)) { + if (!parent && buildInfoPath && buildInfoPath === getTsBuildInfoEmitOutputFilePath(options)) { createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path); hasEmitBlockingDiagnostics.set(toPath(buildInfoPath), true); } diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index d572fc9dad8..69b90135fd0 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -1621,7 +1621,7 @@ namespace ts { if (!state.buildInfoChecked.has(resolvedPath)) { state.buildInfoChecked.set(resolvedPath, true); - const buildInfoPath = getOutputPathForBuildInfo(project.options); + const buildInfoPath = getTsBuildInfoEmitOutputFilePath(project.options); if (buildInfoPath) { const value = state.readFileWithCache(buildInfoPath); const buildInfo = value && getBuildInfo(value); diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index b3b4739a2c6..652b85d000d 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -447,7 +447,7 @@ namespace ts { } export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost) { if (compilerOptions.out || compilerOptions.outFile) return undefined; - const buildInfoPath = getOutputPathForBuildInfo(compilerOptions); + const buildInfoPath = getTsBuildInfoEmitOutputFilePath(compilerOptions); if (!buildInfoPath) return undefined; const content = host.readFile(buildInfoPath); if (!content) return undefined; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 58d513b2e0a..79450ca83c9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4289,6 +4289,8 @@ declare namespace ts { function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; } declare namespace ts { + function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; + function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[]; function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers): Printer; } declare namespace ts { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index bc71eaffa37..f0ae718d570 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4289,6 +4289,8 @@ declare namespace ts { function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; } declare namespace ts { + function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; + function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[]; function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers): Printer; } declare namespace ts { From cafec556f338b1ef9bc06f88eb324a28df5b1d9b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 18 Sep 2019 15:20:20 -0700 Subject: [PATCH 073/100] Properly handle try-finally statements in isReachableFlowNode --- src/compiler/checker.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7e9e8bd4b0e..77814ccc544 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17003,6 +17003,10 @@ namespace ts { return result; } + function isUnlockedReachableFlowNode(flow: FlowNode) { + return !(flow.flags & FlowFlags.PreFinally && (flow).lock.locked) && isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false); + } + function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean { while (true) { if (flow === lastFlowNode) { @@ -17017,8 +17021,8 @@ namespace ts { } noCacheCheck = false; } - if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation | FlowFlags.PreFinally | FlowFlags.AfterFinally)) { - flow = (flow).antecedent; + if (flags & (FlowFlags.Assignment | FlowFlags.Condition | FlowFlags.ArrayMutation | FlowFlags.PreFinally)) { + flow = (flow).antecedent; } else if (flags & FlowFlags.Call) { const signature = getEffectsSignature((flow).node); @@ -17029,7 +17033,7 @@ namespace ts { } else if (flags & FlowFlags.BranchLabel) { // A branching point is reachable if any branch is reachable. - return some((flow).antecedents, isReachableFlowNode); + return some((flow).antecedents, isUnlockedReachableFlowNode); } else if (flags & FlowFlags.LoopLabel) { // A loop is reachable if the control flow path that leads to the top is reachable. @@ -17043,6 +17047,14 @@ namespace ts { } flow = (flow).antecedent; } + else if (flags & FlowFlags.AfterFinally) { + // Cache is unreliable once we start locking nodes + lastFlowNode = undefined; + (flow).locked = true; + const result = isReachableFlowNodeWorker((flow).antecedent, /*skipCacheCheck*/ false); + (flow).locked = false; + return result; + } else { return !(flags & FlowFlags.Unreachable); } From 940231785e8b99df9af1ba39433ba10b120e51ca Mon Sep 17 00:00:00 2001 From: Nathan Fenner Date: Tue, 17 Sep 2019 15:00:37 -0700 Subject: [PATCH 074/100] report error on extra jsx prop instead of component name --- src/compiler/checker.ts | 10 ++++++++ .../checkJsxChildrenProperty15.errors.txt | 4 ++-- ...StringLiteralsInJsxAttributes02.errors.txt | 24 +++++++++---------- .../tsxAttributeResolution1.errors.txt | 12 +++++----- .../tsxAttributeResolution11.errors.txt | 4 ++-- .../tsxAttributeResolution15.errors.txt | 4 ++-- .../tsxElementResolution11.errors.txt | 4 ++-- .../tsxElementResolution3.errors.txt | 4 ++-- .../tsxElementResolution4.errors.txt | 4 ++-- .../tsxLibraryManagedAttributes.errors.txt | 16 ++++++------- ...tsxSpreadAttributesResolution14.errors.txt | 4 ++-- .../tsxSpreadAttributesResolution2.errors.txt | 4 ++-- ...elessFunctionComponentOverload4.errors.txt | 16 ++++++------- ...elessFunctionComponentOverload5.errors.txt | 4 ++-- ...tsxStatelessFunctionComponents1.errors.txt | 16 ++++++------- ...tsxStatelessFunctionComponents2.errors.txt | 4 ++-- .../reference/tsxUnionElementType4.errors.txt | 8 +++---- .../reference/tsxUnionElementType6.errors.txt | 4 ++-- 18 files changed, 78 insertions(+), 68 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 463d00c13e2..f361657e2f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13040,6 +13040,16 @@ namespace ts { // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal. // However, using an object-literal error message will be very confusing to the users so we give different a message. // TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages) + + if (errorNode && isJsxOpeningLikeElement(errorNode.parent)) { + const attributes = errorNode.parent.attributes; + for (const jsxProperty of attributes.properties) { + if (jsxProperty.kind === SyntaxKind.JsxAttribute && jsxProperty.name.escapedText === prop.escapedName) { + // Move the error node to the actual JSX property, instead of pointing to the identifier in the JSX element. + errorNode = jsxProperty; + } + } + } reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget)); } else { diff --git a/tests/baselines/reference/checkJsxChildrenProperty15.errors.txt b/tests/baselines/reference/checkJsxChildrenProperty15.errors.txt index 605a293ffaa..fa034be0f18 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty15.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenProperty15.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(10,13): error TS2322: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes'. +tests/cases/conformance/jsx/file.tsx(10,17): error TS2322: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes'. Property 'children' does not exist on type 'IntrinsicAttributes'. tests/cases/conformance/jsx/file.tsx(11,13): error TS2322: Type '{ children: Element; key: string; }' is not assignable to type 'IntrinsicAttributes'. Property 'children' does not exist on type 'IntrinsicAttributes'. @@ -17,7 +17,7 @@ tests/cases/conformance/jsx/file.tsx(12,13): error TS2322: Type '{ children: Ele // Not OK (excess children) const k3 = } />; - ~~~ + ~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes'. !!! error TS2322: Property 'children' does not exist on type 'IntrinsicAttributes'. const k4 =
; diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt index ff2ec7e5106..b66975fdb73 100644 --- a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt +++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt @@ -1,34 +1,34 @@ -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(27,13): error TS2769: No overload matches this call. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(27,64): error TS2769: No overload matches this call. Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,13): error TS2769: No overload matches this call. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(28,12): error TS2769: No overload matches this call. Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(29,13): error TS2769: No overload matches this call. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(29,43): error TS2769: No overload matches this call. Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. Type '{ extra: true; goTo: string; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(30,13): error TS2769: No overload matches this call. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(30,12): error TS2769: No overload matches this call. Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. Type '{ goTo: string; extra: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'goTo' does not exist on type 'IntrinsicAttributes & ButtonProps'. Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. Type '{ goTo: "home"; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(33,13): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(33,65): error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. -tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,13): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. +tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,44): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. @@ -60,7 +60,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,13): err } const b0 = {console.log(k)}}} extra />; // k has type "left" | "right" - ~~~~~~~~~~ + ~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. !!! error TS2769: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. @@ -69,7 +69,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,13): err !!! error TS2769: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. const b2 = {console.log(k)}} extra />; // k has type "left" | "right" - ~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. !!! error TS2769: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. @@ -78,7 +78,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,13): err !!! error TS2769: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. const b3 = ; // goTo has type"home" | "contact" - ~~~~~~~~~~ + ~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. !!! error TS2769: Type '{ extra: true; goTo: string; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. @@ -87,7 +87,7 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,13): err !!! error TS2769: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. const b4 = ; // goTo has type "home" | "contact" - ~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. !!! error TS2769: Type '{ goTo: string; extra: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. @@ -98,13 +98,13 @@ tests/cases/conformance/types/contextualTypes/jsxAttributes/file.tsx(36,13): err export function NoOverload(buttonProps: ButtonProps): JSX.Element { return undefined } const c1 = {console.log(k)}}} extra />; // k has type any - ~~~~~~~~~~ + ~~~~~ !!! error TS2322: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. !!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. export function NoOverload1(linkProps: LinkProps): JSX.Element { return undefined } const d1 = ; // goTo has type "home" | "contact" - ~~~~~~~~~~~ + ~~~~~ !!! error TS2322: Type '{ extra: true; goTo: "home"; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2322: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxAttributeResolution1.errors.txt b/tests/baselines/reference/tsxAttributeResolution1.errors.txt index 9fc3e8f94da..00e35caf3a2 100644 --- a/tests/baselines/reference/tsxAttributeResolution1.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution1.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/jsx/file.tsx(23,8): error TS2322: Type 'string' is not assignable to type 'number'. -tests/cases/conformance/jsx/file.tsx(24,2): error TS2322: Type '{ y: number; }' is not assignable to type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(24,8): error TS2322: Type '{ y: number; }' is not assignable to type 'Attribs1'. Property 'y' does not exist on type 'Attribs1'. -tests/cases/conformance/jsx/file.tsx(25,2): error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(25,8): error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'. Property 'y' does not exist on type 'Attribs1'. tests/cases/conformance/jsx/file.tsx(26,8): error TS2322: Type 'string' is not assignable to type 'number'. -tests/cases/conformance/jsx/file.tsx(27,2): error TS2322: Type '{ var: string; }' is not assignable to type 'Attribs1'. +tests/cases/conformance/jsx/file.tsx(27,8): error TS2322: Type '{ var: string; }' is not assignable to type 'Attribs1'. Property 'var' does not exist on type 'Attribs1'. tests/cases/conformance/jsx/file.tsx(29,2): error TS2741: Property 'reqd' is missing in type '{}' but required in type '{ reqd: string; }'. tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type 'number' is not assignable to type 'string'. @@ -38,11 +38,11 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type 'number' is not a !!! error TS2322: Type 'string' is not assignable to type 'number'. !!! related TS6500 tests/cases/conformance/jsx/file.tsx:10:2: The expected type comes from property 'x' which is declared here on type 'Attribs1' ; // Error, no property "y" - ~~~~~ + ~~~~~ !!! error TS2322: Type '{ y: number; }' is not assignable to type 'Attribs1'. !!! error TS2322: Property 'y' does not exist on type 'Attribs1'. ; // Error, no property "y" - ~~~~~ + ~~~~~~~ !!! error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'. !!! error TS2322: Property 'y' does not exist on type 'Attribs1'. ; // Error, "32" is not number @@ -50,7 +50,7 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type 'number' is not a !!! error TS2322: Type 'string' is not assignable to type 'number'. !!! related TS6500 tests/cases/conformance/jsx/file.tsx:10:2: The expected type comes from property 'x' which is declared here on type 'Attribs1' ; // Error, no 'var' property - ~~~~~ + ~~~~~~~~ !!! error TS2322: Type '{ var: string; }' is not assignable to type 'Attribs1'. !!! error TS2322: Property 'var' does not exist on type 'Attribs1'. diff --git a/tests/baselines/reference/tsxAttributeResolution11.errors.txt b/tests/baselines/reference/tsxAttributeResolution11.errors.txt index 6c6a23a9b70..163932ce2e0 100644 --- a/tests/baselines/reference/tsxAttributeResolution11.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution11.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(11,10): error TS2322: Type '{ bar: string; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'. +tests/cases/conformance/jsx/file.tsx(11,22): error TS2322: Type '{ bar: string; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'. Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. @@ -27,7 +27,7 @@ tests/cases/conformance/jsx/file.tsx(11,10): error TS2322: Type '{ bar: string; // Should be an OK var x = ; - ~~~~~~~~~~~ + ~~~~~~~~~~~ !!! error TS2322: Type '{ bar: string; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'. !!! error TS2322: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. diff --git a/tests/baselines/reference/tsxAttributeResolution15.errors.txt b/tests/baselines/reference/tsxAttributeResolution15.errors.txt index ca86178b578..b147464b840 100644 --- a/tests/baselines/reference/tsxAttributeResolution15.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution15.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(11,10): error TS2322: Type '{ prop1: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(11,21): error TS2322: Type '{ prop1: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. tests/cases/conformance/jsx/file.tsx(14,44): error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature. @@ -15,7 +15,7 @@ tests/cases/conformance/jsx/file.tsx(14,44): error TS7017: Element implicitly ha // Error let a = - ~~~~~~~~~~ + ~~~~~~~~~~~~~ !!! error TS2322: Type '{ prop1: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. !!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. diff --git a/tests/baselines/reference/tsxElementResolution11.errors.txt b/tests/baselines/reference/tsxElementResolution11.errors.txt index d08a6ed2721..59ce93a4ccf 100644 --- a/tests/baselines/reference/tsxElementResolution11.errors.txt +++ b/tests/baselines/reference/tsxElementResolution11.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(17,2): error TS2322: Type '{ x: number; }' is not assignable to type '{ q?: number; }'. +tests/cases/conformance/jsx/file.tsx(17,7): error TS2322: Type '{ x: number; }' is not assignable to type '{ q?: number; }'. Property 'x' does not exist on type '{ q?: number; }'. @@ -20,7 +20,7 @@ tests/cases/conformance/jsx/file.tsx(17,2): error TS2322: Type '{ x: number; }' } var Obj2: Obj2type; ; // Error - ~~~~ + ~~~~~~ !!! error TS2322: Type '{ x: number; }' is not assignable to type '{ q?: number; }'. !!! error TS2322: Property 'x' does not exist on type '{ q?: number; }'. diff --git a/tests/baselines/reference/tsxElementResolution3.errors.txt b/tests/baselines/reference/tsxElementResolution3.errors.txt index f220dbd8a5b..c5a11b9cbc1 100644 --- a/tests/baselines/reference/tsxElementResolution3.errors.txt +++ b/tests/baselines/reference/tsxElementResolution3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(12,2): error TS2322: Type '{ w: string; }' is not assignable to type '{ n: string; }'. +tests/cases/conformance/jsx/file.tsx(12,7): error TS2322: Type '{ w: string; }' is not assignable to type '{ n: string; }'. Property 'w' does not exist on type '{ n: string; }'. @@ -15,6 +15,6 @@ tests/cases/conformance/jsx/file.tsx(12,2): error TS2322: Type '{ w: string; }' // Error ; - ~~~~ + ~~~~~~~ !!! error TS2322: Type '{ w: string; }' is not assignable to type '{ n: string; }'. !!! error TS2322: Property 'w' does not exist on type '{ n: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution4.errors.txt b/tests/baselines/reference/tsxElementResolution4.errors.txt index f76925030f2..ea2ae7b0073 100644 --- a/tests/baselines/reference/tsxElementResolution4.errors.txt +++ b/tests/baselines/reference/tsxElementResolution4.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(16,2): error TS2322: Type '{ q: string; }' is not assignable to type '{ m: string; }'. +tests/cases/conformance/jsx/file.tsx(16,7): error TS2322: Type '{ q: string; }' is not assignable to type '{ m: string; }'. Property 'q' does not exist on type '{ m: string; }'. @@ -19,7 +19,7 @@ tests/cases/conformance/jsx/file.tsx(16,2): error TS2322: Type '{ q: string; }' // Error ; - ~~~~ + ~~~~ !!! error TS2322: Type '{ q: string; }' is not assignable to type '{ m: string; }'. !!! error TS2322: Property 'q' does not exist on type '{ m: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt b/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt index b34ee77d1fb..6bf817f0c7d 100644 --- a/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt +++ b/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt @@ -1,22 +1,22 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(55,12): error TS2322: Type '{ foo: number; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: number; }>'. Type '{ foo: number; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: string; }': bar, baz -tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(57,12): error TS2322: Type '{ bar: string; baz: string; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: number; }>'. +tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(57,41): error TS2322: Type '{ bar: string; baz: string; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: number; }>'. Property 'bat' does not exist on type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: number; }>'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(59,42): error TS2322: Type 'null' is not assignable to type 'string'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(69,26): error TS2322: Type 'string' is not assignable to type 'number | null | undefined'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(71,35): error TS2322: Type 'null' is not assignable to type 'ReactNode'. -tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(80,12): error TS2322: Type '{ foo: number; bar: string; }' is not assignable to type 'Defaultize<{}, { foo: number; }>'. +tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(80,38): error TS2322: Type '{ foo: number; bar: string; }' is not assignable to type 'Defaultize<{}, { foo: number; }>'. Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(81,29): error TS2322: Type 'string' is not assignable to type 'number | undefined'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(98,12): error TS2322: Type '{ foo: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. Type '{ foo: string; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: number; }': bar, baz -tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(100,12): error TS2322: Type '{ bar: string; baz: number; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. +tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(100,56): error TS2322: Type '{ bar: string; baz: number; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. Property 'bat' does not exist on type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(102,57): error TS2322: Type 'null' is not assignable to type 'number'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(111,46): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(112,46): error TS2322: Type 'null' is not assignable to type 'string'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(113,57): error TS2322: Type 'null' is not assignable to type 'ReactNode'. -tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(122,12): error TS2322: Type '{ foo: string; bar: string; }' is not assignable to type 'Defaultize'. +tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(122,58): error TS2322: Type '{ foo: string; bar: string; }' is not assignable to type 'Defaultize'. Property 'bar' does not exist on type 'Defaultize'. tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS2322: Type 'number' is not assignable to type 'string | undefined'. @@ -82,7 +82,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 !!! error TS2322: Type '{ foo: number; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: string; }': bar, baz const c = ; const d = ; // Error, baz not a valid prop - ~~~~~~~~~ + ~~~~~~~~~~ !!! error TS2322: Type '{ bar: string; baz: string; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: number; }>'. !!! error TS2322: Property 'bat' does not exist on type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: number; }>'. const e = ; // bar is nullable/undefinable since it's not marked `isRequired` @@ -116,7 +116,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 const k = ; const l = ; // error, no prop named bar - ~~~~~~~~~~~~~~~~ + ~~~~~~~~ !!! error TS2322: Type '{ foo: number; bar: string; }' is not assignable to type 'Defaultize<{}, { foo: number; }>'. !!! error TS2322: Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'. const m = ; // error, wrong type @@ -145,7 +145,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 !!! error TS2322: Type '{ foo: string; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: number; }': bar, baz const p = ; const q = ; // Error, baz not a valid prop - ~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~ !!! error TS2322: Type '{ bar: string; baz: number; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. !!! error TS2322: Property 'bat' does not exist on type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. const r = ; // bar is nullable/undefinable since it's not marked `isRequired` @@ -181,7 +181,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 const x = ; const y = ; // error, no prop named bar - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~ !!! error TS2322: Type '{ foo: string; bar: string; }' is not assignable to type 'Defaultize'. !!! error TS2322: Property 'bar' does not exist on type 'Defaultize'. const z = ; // error, wrong type diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution14.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution14.errors.txt index 67beb30ccb0..f000257b9d5 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution14.errors.txt +++ b/tests/baselines/reference/tsxSpreadAttributesResolution14.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(11,10): error TS2322: Type '{ Property1: true; property1: string; property2: number; }' is not assignable to type 'IntrinsicAttributes & AnotherComponentProps'. +tests/cases/conformance/jsx/file.tsx(11,38): error TS2322: Type '{ Property1: true; property1: string; property2: number; }' is not assignable to type 'IntrinsicAttributes & AnotherComponentProps'. Property 'Property1' does not exist on type 'IntrinsicAttributes & AnotherComponentProps'. @@ -14,7 +14,7 @@ tests/cases/conformance/jsx/file.tsx(11,10): error TS2322: Type '{ Property1: tr return ( // Error extra property - ~~~~~~~~~~~~~~~~ + ~~~~~~~~~ !!! error TS2322: Type '{ Property1: true; property1: string; property2: number; }' is not assignable to type 'IntrinsicAttributes & AnotherComponentProps'. !!! error TS2322: Property 'Property1' does not exist on type 'IntrinsicAttributes & AnotherComponentProps'. ); diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt index d9748382f25..e46732e0cde 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt +++ b/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt @@ -5,7 +5,7 @@ tests/cases/conformance/jsx/file.tsx(22,21): error TS2322: Type 'true' is not as tests/cases/conformance/jsx/file.tsx(23,10): error TS2322: Type '{ x: number; y: "2"; }' is not assignable to type 'PoisonedProp'. Types of property 'x' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(24,11): error TS2322: Type '{ X: string; x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(24,40): error TS2322: Type '{ X: string; x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. Property 'X' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. @@ -48,6 +48,6 @@ tests/cases/conformance/jsx/file.tsx(24,11): error TS2322: Type '{ X: string; x: !!! error TS2322: Types of property 'x' are incompatible. !!! error TS2322: Type 'number' is not assignable to type 'string'. let w1 = ; - ~~~~~~~~ + ~~~~~~ !!! error TS2322: Type '{ X: string; x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. !!! error TS2322: Property 'X' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt index 5318c77efae..43935105d84 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt @@ -1,23 +1,23 @@ -tests/cases/conformance/jsx/file.tsx(12,13): error TS2769: No overload matches this call. +tests/cases/conformance/jsx/file.tsx(12,22): error TS2769: No overload matches this call. Overload 1 of 2, '(): Element', gave the following error. Type '{ extraProp: true; }' is not assignable to type 'IntrinsicAttributes'. Property 'extraProp' does not exist on type 'IntrinsicAttributes'. Overload 2 of 2, '(l: { yy: number; yy1: string; }): Element', gave the following error. Type '{ extraProp: true; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. Property 'extraProp' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. -tests/cases/conformance/jsx/file.tsx(13,13): error TS2769: No overload matches this call. +tests/cases/conformance/jsx/file.tsx(13,12): error TS2769: No overload matches this call. Overload 1 of 2, '(): Element', gave the following error. Type '{ yy: number; }' is not assignable to type 'IntrinsicAttributes'. Property 'yy' does not exist on type 'IntrinsicAttributes'. Overload 2 of 2, '(l: { yy: number; yy1: string; }): Element', gave the following error. Property 'yy1' is missing in type '{ yy: number; }' but required in type '{ yy: number; yy1: string; }'. -tests/cases/conformance/jsx/file.tsx(14,12): error TS2769: No overload matches this call. +tests/cases/conformance/jsx/file.tsx(14,31): error TS2769: No overload matches this call. Overload 1 of 2, '(): Element', gave the following error. Type '{ yy1: true; yy: number; }' is not assignable to type 'IntrinsicAttributes'. Property 'yy1' does not exist on type 'IntrinsicAttributes'. Overload 2 of 2, '(l: { yy: number; yy1: string; }): Element', gave the following error. Type 'true' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(16,13): error TS2769: No overload matches this call. +tests/cases/conformance/jsx/file.tsx(16,31): error TS2769: No overload matches this call. Overload 1 of 2, '(): Element', gave the following error. Type '{ y1: number; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes'. Property 'y1' does not exist on type 'IntrinsicAttributes'. @@ -89,7 +89,7 @@ tests/cases/conformance/jsx/file.tsx(36,12): error TS2769: No overload matches t // Error const c0 = ; // extra property; - ~~~~~~~~ + ~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(): Element', gave the following error. !!! error TS2769: Type '{ extraProp: true; }' is not assignable to type 'IntrinsicAttributes'. @@ -98,7 +98,7 @@ tests/cases/conformance/jsx/file.tsx(36,12): error TS2769: No overload matches t !!! error TS2769: Type '{ extraProp: true; }' is not assignable to type 'IntrinsicAttributes & { yy: number; yy1: string; }'. !!! error TS2769: Property 'extraProp' does not exist on type 'IntrinsicAttributes & { yy: number; yy1: string; }'. const c1 = ; // missing property; - ~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(): Element', gave the following error. !!! error TS2769: Type '{ yy: number; }' is not assignable to type 'IntrinsicAttributes'. @@ -107,7 +107,7 @@ tests/cases/conformance/jsx/file.tsx(36,12): error TS2769: No overload matches t !!! error TS2769: Property 'yy1' is missing in type '{ yy: number; }' but required in type '{ yy: number; yy1: string; }'. !!! related TS2728 tests/cases/conformance/jsx/file.tsx:3:43: 'yy1' is declared here. const c2 = ; // type incompatible; - ~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(): Element', gave the following error. !!! error TS2769: Type '{ yy1: true; yy: number; }' is not assignable to type 'IntrinsicAttributes'. @@ -117,7 +117,7 @@ tests/cases/conformance/jsx/file.tsx(36,12): error TS2769: No overload matches t !!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:43: The expected type comes from property 'yy1' which is declared here on type 'IntrinsicAttributes & { yy: number; yy1: string; }' const c3 = ; // This is OK becuase all attribute are spread const c4 = ; // extra property; - ~~~~~~~~ + ~~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(): Element', gave the following error. !!! error TS2769: Type '{ y1: number; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes'. diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt index faf129dda4b..aa2e4fe19c6 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(48,13): error TS2769: No overload matches this call. +tests/cases/conformance/jsx/file.tsx(48,12): error TS2769: No overload matches this call. Overload 1 of 3, '(buttonProps: ButtonProps): Element', gave the following error. Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'to' does not exist on type 'IntrinsicAttributes & ButtonProps'. @@ -80,7 +80,7 @@ tests/cases/conformance/jsx/file.tsx(56,12): error TS2769: No overload matches t // Error const b0 = {}}>GO; // extra property; - ~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 3, '(buttonProps: ButtonProps): Element', gave the following error. !!! error TS2769: Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt index 2ca7adfbc3e..a8ba635f7a7 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt @@ -1,12 +1,12 @@ -tests/cases/conformance/jsx/file.tsx(19,10): error TS2322: Type '{ naaame: string; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'. +tests/cases/conformance/jsx/file.tsx(19,16): error TS2322: Type '{ naaame: string; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'. Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. tests/cases/conformance/jsx/file.tsx(27,15): error TS2322: Type 'number' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(29,10): error TS2322: Type '{ naaaaaaame: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. +tests/cases/conformance/jsx/file.tsx(29,15): error TS2322: Type '{ naaaaaaame: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. tests/cases/conformance/jsx/file.tsx(34,10): error TS2741: Property '"prop-name"' is missing in type '{ extra-prop-name: string; }' but required in type '{ "prop-name": string; }'. -tests/cases/conformance/jsx/file.tsx(37,10): error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'. +tests/cases/conformance/jsx/file.tsx(37,23): error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'. Property 'prop1' does not exist on type 'IntrinsicAttributes'. -tests/cases/conformance/jsx/file.tsx(38,11): error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'. +tests/cases/conformance/jsx/file.tsx(38,24): error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'. Property 'ref' does not exist on type 'IntrinsicAttributes'. tests/cases/conformance/jsx/file.tsx(41,16): error TS1005: ',' expected. tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolean; }' has no properties in common with type 'IntrinsicAttributes'. @@ -32,7 +32,7 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea let a1 = ; // Error let b = ; - ~~~~~ + ~~~~~~~~~~~~~~ !!! error TS2322: Type '{ naaame: string; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'. !!! error TS2322: Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. @@ -47,7 +47,7 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea !!! error TS2322: Type 'number' is not assignable to type 'string'. // Error let f = ; - ~~~~ + ~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ naaaaaaame: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. !!! error TS2322: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. @@ -61,11 +61,11 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea // Error let i = - ~~~~~~~~~~~~ + ~~~~~ !!! error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'. !!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes'. let i1 = x.greeting.substr(10)} /> - ~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'. !!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes'. diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt index 551d0e72523..57ef8c2efbf 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(19,10): error TS2322: Type '{ ref: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. +tests/cases/conformance/jsx/file.tsx(19,16): error TS2322: Type '{ ref: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. tests/cases/conformance/jsx/file.tsx(25,42): error TS2551: Property 'subtr' does not exist on type 'string'. Did you mean 'substr'? tests/cases/conformance/jsx/file.tsx(27,33): error TS2339: Property 'notARealProperty' does not exist on type 'BigGreeter'. @@ -25,7 +25,7 @@ tests/cases/conformance/jsx/file.tsx(35,26): error TS2339: Property 'propertyNot let b = ; // Error - not allowed to specify 'ref' on SFCs let c = ; - ~~~~~ + ~~~~~~~~~~~ !!! error TS2322: Type '{ ref: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. !!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. diff --git a/tests/baselines/reference/tsxUnionElementType4.errors.txt b/tests/baselines/reference/tsxUnionElementType4.errors.txt index bca0229de54..2048b100c11 100644 --- a/tests/baselines/reference/tsxUnionElementType4.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType4.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'true' is not assignable to type 'never'. -tests/cases/conformance/jsx/file.tsx(33,10): error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(33,21): error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. -tests/cases/conformance/jsx/file.tsx(34,10): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. +tests/cases/conformance/jsx/file.tsx(34,22): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. @@ -42,11 +42,11 @@ tests/cases/conformance/jsx/file.tsx(34,10): error TS2322: Type '{ prop: true; } !!! error TS2322: Type 'true' is not assignable to type 'never'. !!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }' let b = - ~~~~~~~~~~ + ~~~~~~ !!! error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. !!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. let c = ; - ~~~~~~~~~~~ + ~~~~ !!! error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. !!! error TS2322: Property 'prop' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxUnionElementType6.errors.txt b/tests/baselines/reference/tsxUnionElementType6.errors.txt index 790285f2978..cad93a38ae9 100644 --- a/tests/baselines/reference/tsxUnionElementType6.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/jsx/file.tsx(18,10): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes'. +tests/cases/conformance/jsx/file.tsx(18,23): error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes'. Property 'x' does not exist on type 'IntrinsicAttributes'. tests/cases/conformance/jsx/file.tsx(19,27): error TS2322: Type 'string' is not assignable to type 'boolean'. tests/cases/conformance/jsx/file.tsx(20,10): error TS2741: Property 'x' is missing in type '{}' but required in type '{ x: boolean; }'. @@ -24,7 +24,7 @@ tests/cases/conformance/jsx/file.tsx(21,10): error TS2741: Property 'x' is missi var SFC2AndEmptyComp = SFC2 || EmptySFC1; // Error let a = ; - ~~~~~~~~~~~~ + ~ !!! error TS2322: Type '{ x: true; }' is not assignable to type 'IntrinsicAttributes'. !!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes'. let b = ; From dbc17229f79d19a07ad087e5f36f221f4b351e8d Mon Sep 17 00:00:00 2001 From: Nathan Fenner Date: Wed, 18 Sep 2019 14:42:38 -0700 Subject: [PATCH 075/100] report extraneous jsx attribute error on attribute name instead of entire attribute assignment --- src/compiler/checker.ts | 13 ++++--------- .../reference/tsxAttributeResolution1.errors.txt | 6 +++--- .../reference/tsxAttributeResolution11.errors.txt | 2 +- .../reference/tsxAttributeResolution15.errors.txt | 2 +- .../reference/tsxElementResolution11.errors.txt | 2 +- .../reference/tsxElementResolution3.errors.txt | 2 +- .../reference/tsxElementResolution4.errors.txt | 2 +- .../tsxLibraryManagedAttributes.errors.txt | 8 ++++---- .../tsxSpreadAttributesResolution2.errors.txt | 2 +- ...sxStatelessFunctionComponentOverload4.errors.txt | 2 +- .../tsxStatelessFunctionComponents1.errors.txt | 6 +++--- .../tsxStatelessFunctionComponents2.errors.txt | 2 +- 12 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f361657e2f8..5833d2e9c8c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13040,15 +13040,10 @@ namespace ts { // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal. // However, using an object-literal error message will be very confusing to the users so we give different a message. // TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages) - - if (errorNode && isJsxOpeningLikeElement(errorNode.parent)) { - const attributes = errorNode.parent.attributes; - for (const jsxProperty of attributes.properties) { - if (jsxProperty.kind === SyntaxKind.JsxAttribute && jsxProperty.name.escapedText === prop.escapedName) { - // Move the error node to the actual JSX property, instead of pointing to the identifier in the JSX element. - errorNode = jsxProperty; - } - } + if (prop.valueDeclaration && isNamedDeclaration(prop.valueDeclaration) && prop.valueDeclaration.name && prop.valueDeclaration.name.pos !== -1) { + // If the "children" attribute is extraneous `extra` then the declaration's name has no location. + // In that case, do not update the error location, since there's no name to point to. + errorNode = prop.valueDeclaration.name; } reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget)); } diff --git a/tests/baselines/reference/tsxAttributeResolution1.errors.txt b/tests/baselines/reference/tsxAttributeResolution1.errors.txt index 00e35caf3a2..46ccb39e704 100644 --- a/tests/baselines/reference/tsxAttributeResolution1.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution1.errors.txt @@ -38,11 +38,11 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type 'number' is not a !!! error TS2322: Type 'string' is not assignable to type 'number'. !!! related TS6500 tests/cases/conformance/jsx/file.tsx:10:2: The expected type comes from property 'x' which is declared here on type 'Attribs1' ; // Error, no property "y" - ~~~~~ + ~ !!! error TS2322: Type '{ y: number; }' is not assignable to type 'Attribs1'. !!! error TS2322: Property 'y' does not exist on type 'Attribs1'. ; // Error, no property "y" - ~~~~~~~ + ~ !!! error TS2322: Type '{ y: string; }' is not assignable to type 'Attribs1'. !!! error TS2322: Property 'y' does not exist on type 'Attribs1'. ; // Error, "32" is not number @@ -50,7 +50,7 @@ tests/cases/conformance/jsx/file.tsx(30,8): error TS2322: Type 'number' is not a !!! error TS2322: Type 'string' is not assignable to type 'number'. !!! related TS6500 tests/cases/conformance/jsx/file.tsx:10:2: The expected type comes from property 'x' which is declared here on type 'Attribs1' ; // Error, no 'var' property - ~~~~~~~~ + ~~~ !!! error TS2322: Type '{ var: string; }' is not assignable to type 'Attribs1'. !!! error TS2322: Property 'var' does not exist on type 'Attribs1'. diff --git a/tests/baselines/reference/tsxAttributeResolution11.errors.txt b/tests/baselines/reference/tsxAttributeResolution11.errors.txt index 163932ce2e0..d490faad314 100644 --- a/tests/baselines/reference/tsxAttributeResolution11.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution11.errors.txt @@ -27,7 +27,7 @@ tests/cases/conformance/jsx/file.tsx(11,22): error TS2322: Type '{ bar: string; // Should be an OK var x = ; - ~~~~~~~~~~~ + ~~~ !!! error TS2322: Type '{ bar: string; }' is not assignable to type 'IntrinsicAttributes & { ref?: string; }'. !!! error TS2322: Property 'bar' does not exist on type 'IntrinsicAttributes & { ref?: string; }'. diff --git a/tests/baselines/reference/tsxAttributeResolution15.errors.txt b/tests/baselines/reference/tsxAttributeResolution15.errors.txt index b147464b840..7ec97ba4675 100644 --- a/tests/baselines/reference/tsxAttributeResolution15.errors.txt +++ b/tests/baselines/reference/tsxAttributeResolution15.errors.txt @@ -15,7 +15,7 @@ tests/cases/conformance/jsx/file.tsx(14,44): error TS7017: Element implicitly ha // Error let a = - ~~~~~~~~~~~~~ + ~~~~~ !!! error TS2322: Type '{ prop1: string; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. !!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. diff --git a/tests/baselines/reference/tsxElementResolution11.errors.txt b/tests/baselines/reference/tsxElementResolution11.errors.txt index 59ce93a4ccf..cc032610e2b 100644 --- a/tests/baselines/reference/tsxElementResolution11.errors.txt +++ b/tests/baselines/reference/tsxElementResolution11.errors.txt @@ -20,7 +20,7 @@ tests/cases/conformance/jsx/file.tsx(17,7): error TS2322: Type '{ x: number; }' } var Obj2: Obj2type; ; // Error - ~~~~~~ + ~ !!! error TS2322: Type '{ x: number; }' is not assignable to type '{ q?: number; }'. !!! error TS2322: Property 'x' does not exist on type '{ q?: number; }'. diff --git a/tests/baselines/reference/tsxElementResolution3.errors.txt b/tests/baselines/reference/tsxElementResolution3.errors.txt index c5a11b9cbc1..8f8679b3857 100644 --- a/tests/baselines/reference/tsxElementResolution3.errors.txt +++ b/tests/baselines/reference/tsxElementResolution3.errors.txt @@ -15,6 +15,6 @@ tests/cases/conformance/jsx/file.tsx(12,7): error TS2322: Type '{ w: string; }' // Error ; - ~~~~~~~ + ~ !!! error TS2322: Type '{ w: string; }' is not assignable to type '{ n: string; }'. !!! error TS2322: Property 'w' does not exist on type '{ n: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxElementResolution4.errors.txt b/tests/baselines/reference/tsxElementResolution4.errors.txt index ea2ae7b0073..235adbb199a 100644 --- a/tests/baselines/reference/tsxElementResolution4.errors.txt +++ b/tests/baselines/reference/tsxElementResolution4.errors.txt @@ -19,7 +19,7 @@ tests/cases/conformance/jsx/file.tsx(16,7): error TS2322: Type '{ q: string; }' // Error ; - ~~~~ + ~ !!! error TS2322: Type '{ q: string; }' is not assignable to type '{ m: string; }'. !!! error TS2322: Property 'q' does not exist on type '{ m: string; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt b/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt index 6bf817f0c7d..4b4448e42f6 100644 --- a/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt +++ b/tests/baselines/reference/tsxLibraryManagedAttributes.errors.txt @@ -82,7 +82,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 !!! error TS2322: Type '{ foo: number; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: string; }': bar, baz const c = ; const d = ; // Error, baz not a valid prop - ~~~~~~~~~~ + ~~~ !!! error TS2322: Type '{ bar: string; baz: string; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: number; }>'. !!! error TS2322: Property 'bat' does not exist on type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: number; }>'. const e = ; // bar is nullable/undefinable since it's not marked `isRequired` @@ -116,7 +116,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 const k = ; const l = ; // error, no prop named bar - ~~~~~~~~ + ~~~ !!! error TS2322: Type '{ foo: number; bar: string; }' is not assignable to type 'Defaultize<{}, { foo: number; }>'. !!! error TS2322: Property 'bar' does not exist on type 'Defaultize<{}, { foo: number; }>'. const m = ; // error, wrong type @@ -145,7 +145,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 !!! error TS2322: Type '{ foo: string; }' is missing the following properties from type '{ bar: string | number | ReactComponent<{}, {}> | null | undefined; baz: number; }': bar, baz const p = ; const q = ; // Error, baz not a valid prop - ~~~~~~~~~~ + ~~~ !!! error TS2322: Type '{ bar: string; baz: number; bat: string; }' is not assignable to type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. !!! error TS2322: Property 'bat' does not exist on type 'Defaultize; bar: PropTypeChecker; baz: PropTypeChecker; }>, { foo: string; }>'. const r = ; // bar is nullable/undefinable since it's not marked `isRequired` @@ -181,7 +181,7 @@ tests/cases/conformance/jsx/tsxLibraryManagedAttributes.tsx(123,49): error TS232 const x = ; const y = ; // error, no prop named bar - ~~~~~~~~ + ~~~ !!! error TS2322: Type '{ foo: string; bar: string; }' is not assignable to type 'Defaultize'. !!! error TS2322: Property 'bar' does not exist on type 'Defaultize'. const z = ; // error, wrong type diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt b/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt index e46732e0cde..a5f36e5ed08 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt +++ b/tests/baselines/reference/tsxSpreadAttributesResolution2.errors.txt @@ -48,6 +48,6 @@ tests/cases/conformance/jsx/file.tsx(24,40): error TS2322: Type '{ X: string; x: !!! error TS2322: Types of property 'x' are incompatible. !!! error TS2322: Type 'number' is not assignable to type 'string'. let w1 = ; - ~~~~~~ + ~ !!! error TS2322: Type '{ X: string; x: number; y: "2"; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. !!! error TS2322: Property 'X' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & PoisonedProp & { children?: ReactNode; }'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt index 43935105d84..3a47e329162 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload4.errors.txt @@ -117,7 +117,7 @@ tests/cases/conformance/jsx/file.tsx(36,12): error TS2769: No overload matches t !!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:43: The expected type comes from property 'yy1' which is declared here on type 'IntrinsicAttributes & { yy: number; yy1: string; }' const c3 = ; // This is OK becuase all attribute are spread const c4 = ; // extra property; - ~~~~~~~~~~ + ~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(): Element', gave the following error. !!! error TS2769: Type '{ y1: number; yy: number; yy1: string; }' is not assignable to type 'IntrinsicAttributes'. diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt index a8ba635f7a7..7827c0625a4 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents1.errors.txt @@ -32,7 +32,7 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea let a1 = ; // Error let b = ; - ~~~~~~~~~~~~~~ + ~~~~~~ !!! error TS2322: Type '{ naaame: string; }' is not assignable to type 'IntrinsicAttributes & { name: string; }'. !!! error TS2322: Property 'naaame' does not exist on type 'IntrinsicAttributes & { name: string; }'. @@ -47,7 +47,7 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea !!! error TS2322: Type 'number' is not assignable to type 'string'. // Error let f = ; - ~~~~~~~~~~~~~~~ + ~~~~~~~~~~ !!! error TS2322: Type '{ naaaaaaame: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. !!! error TS2322: Property 'naaaaaaame' does not exist on type 'IntrinsicAttributes & { name?: string; }'. @@ -65,7 +65,7 @@ tests/cases/conformance/jsx/file.tsx(45,11): error TS2559: Type '{ prop1: boolea !!! error TS2322: Type '{ prop1: true; }' is not assignable to type 'IntrinsicAttributes'. !!! error TS2322: Property 'prop1' does not exist on type 'IntrinsicAttributes'. let i1 = x.greeting.substr(10)} /> - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~ !!! error TS2322: Type '{ ref: (x: any) => any; }' is not assignable to type 'IntrinsicAttributes'. !!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes'. diff --git a/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt index 57ef8c2efbf..b6727eb5ca8 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponents2.errors.txt @@ -25,7 +25,7 @@ tests/cases/conformance/jsx/file.tsx(35,26): error TS2339: Property 'propertyNot let b = ; // Error - not allowed to specify 'ref' on SFCs let c = ; - ~~~~~~~~~~~ + ~~~ !!! error TS2322: Type '{ ref: string; }' is not assignable to type 'IntrinsicAttributes & { name?: string; }'. !!! error TS2322: Property 'ref' does not exist on type 'IntrinsicAttributes & { name?: string; }'. From 7b77b497810273c2a58f812d5082fab05333893e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Sep 2019 08:26:52 -0700 Subject: [PATCH 076/100] Enable caching for control flow paths that precede loops --- src/compiler/checker.ts | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 463d00c13e2..19ffdf46ae0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17309,24 +17309,31 @@ namespace ts { const antecedentTypes: Type[] = []; let subtypeReduction = false; let firstAntecedentType: FlowType | undefined; - flowLoopNodes[flowLoopCount] = flow; - flowLoopKeys[flowLoopCount] = key; - flowLoopTypes[flowLoopCount] = antecedentTypes; for (const antecedent of flow.antecedents!) { - flowLoopCount++; - const flowType = getTypeAtFlowNode(antecedent); - flowLoopCount--; + let flowType; if (!firstAntecedentType) { - firstAntecedentType = flowType; + // The first antecedent of a loop junction is always the non-looping control + // flow path that leads to the top. + flowType = firstAntecedentType = getTypeAtFlowNode(antecedent); + } + else { + // All but the first antecedent are the looping control flow paths that lead + // back to the loop junction. We track these on the flow loop stack. + flowLoopNodes[flowLoopCount] = flow; + flowLoopKeys[flowLoopCount] = key; + flowLoopTypes[flowLoopCount] = antecedentTypes; + flowLoopCount++; + flowType = getTypeAtFlowNode(antecedent); + flowLoopCount--; + // If we see a value appear in the cache it is a sign that control flow analysis + // was restarted and completed by checkExpressionCached. We can simply pick up + // the resulting type and bail out. + const cached = cache.get(key); + if (cached) { + return cached; + } } const type = getTypeFromFlowType(flowType); - // If we see a value appear in the cache it is a sign that control flow analysis - // was restarted and completed by checkExpressionCached. We can simply pick up - // the resulting type and bail out. - const cached = cache.get(key); - if (cached) { - return cached; - } pushIfUnique(antecedentTypes, type); // If an antecedent type is not a subset of the declared type, we need to perform // subtype reduction. This happens when a "foreign" type is injected into the control From 78057a64ac02a2d6b364fade502ff63edec2cc3e Mon Sep 17 00:00:00 2001 From: Jack Bates Date: Fri, 23 Aug 2019 12:57:44 -0700 Subject: [PATCH 077/100] Allow readonly arguments to Promise.all(), etc. --- src/lib/es2015.promise.d.ts | 22 +++++++++---------- .../reference/correctOrderOfPromiseMethod.js | 5 +++-- .../correctOrderOfPromiseMethod.symbols | 3 ++- .../correctOrderOfPromiseMethod.types | 14 +++++++----- ...inferFromGenericFunctionReturnTypes3.types | 4 ++-- .../baselines/reference/inferenceLimit.types | 4 ++-- .../compiler/correctOrderOfPromiseMethod.ts | 4 ++-- 7 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/lib/es2015.promise.d.ts b/src/lib/es2015.promise.d.ts index 83776137c33..45b0fa5dc59 100644 --- a/src/lib/es2015.promise.d.ts +++ b/src/lib/es2015.promise.d.ts @@ -18,7 +18,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -26,7 +26,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -34,7 +34,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -42,7 +42,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -50,7 +50,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -58,7 +58,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike , T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -66,7 +66,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike ]): Promise<[T1, T2, T3, T4]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike ]): Promise<[T1, T2, T3, T4]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -74,7 +74,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -82,7 +82,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; + all(values: readonly [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises @@ -90,7 +90,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - all(values: (T | PromiseLike)[]): Promise; + all(values: readonly (T | PromiseLike)[]): Promise; /** * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved @@ -98,7 +98,7 @@ interface PromiseConstructor { * @param values An array of Promises. * @returns A new Promise. */ - race(values: T[]): Promise ? U : T>; + race(values: readonly T[]): Promise ? U : T>; /** * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved diff --git a/tests/baselines/reference/correctOrderOfPromiseMethod.js b/tests/baselines/reference/correctOrderOfPromiseMethod.js index 58c98189a43..fadda95374f 100644 --- a/tests/baselines/reference/correctOrderOfPromiseMethod.js +++ b/tests/baselines/reference/correctOrderOfPromiseMethod.js @@ -15,7 +15,7 @@ async function countEverything(): Promise { const [resultA, resultB] = await Promise.all([ providerA(), providerB(), - ]); + ] as const); const dataA: A[] = resultA; const dataB: B[] = resultB; @@ -23,7 +23,8 @@ async function countEverything(): Promise { return dataA.length + dataB.length; } return 0; -} +} + //// [correctOrderOfPromiseMethod.js] var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { diff --git a/tests/baselines/reference/correctOrderOfPromiseMethod.symbols b/tests/baselines/reference/correctOrderOfPromiseMethod.symbols index 290b482e5c7..1e67e9444c6 100644 --- a/tests/baselines/reference/correctOrderOfPromiseMethod.symbols +++ b/tests/baselines/reference/correctOrderOfPromiseMethod.symbols @@ -43,7 +43,7 @@ async function countEverything(): Promise { providerB(), >providerB : Symbol(providerB, Decl(correctOrderOfPromiseMethod.ts, 11, 9)) - ]); + ] as const); const dataA: A[] = resultA; >dataA : Symbol(dataA, Decl(correctOrderOfPromiseMethod.ts, 18, 9)) @@ -69,3 +69,4 @@ async function countEverything(): Promise { } return 0; } + diff --git a/tests/baselines/reference/correctOrderOfPromiseMethod.types b/tests/baselines/reference/correctOrderOfPromiseMethod.types index 5e8eaa72f42..a6f2c46782e 100644 --- a/tests/baselines/reference/correctOrderOfPromiseMethod.types +++ b/tests/baselines/reference/correctOrderOfPromiseMethod.types @@ -28,12 +28,13 @@ async function countEverything(): Promise { const [resultA, resultB] = await Promise.all([ >resultA : A[] >resultB : B[] ->await Promise.all([ providerA(), providerB(), ]) : [A[], B[]] ->Promise.all([ providerA(), providerB(), ]) : Promise<[A[], B[]]> ->Promise.all : { (values: Iterable>): Promise; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: (T | PromiseLike)[]): Promise; } +>await Promise.all([ providerA(), providerB(), ] as const) : [A[], B[]] +>Promise.all([ providerA(), providerB(), ] as const) : Promise<[A[], B[]]> +>Promise.all : { (values: Iterable>): Promise; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: readonly (T | PromiseLike)[]): Promise; } >Promise : PromiseConstructor ->all : { (values: Iterable>): Promise; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: (T | PromiseLike)[]): Promise; } ->[ providerA(), providerB(), ] : [Promise, Promise] +>all : { (values: Iterable>): Promise; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: readonly (T | PromiseLike)[]): Promise; } +>[ providerA(), providerB(), ] as const : readonly [Promise, Promise] +>[ providerA(), providerB(), ] : readonly [Promise, Promise] providerA(), >providerA() : Promise @@ -43,7 +44,7 @@ async function countEverything(): Promise { >providerB() : Promise >providerB : () => Promise - ]); + ] as const); const dataA: A[] = resultA; >dataA : A[] @@ -70,3 +71,4 @@ async function countEverything(): Promise { return 0; >0 : 0 } + diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types index 4c56070fd3c..f9192dd11ba 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types @@ -413,9 +413,9 @@ const f1: F = () => { return Promise.all([ >Promise.all([ { name: "David Gomes", age: 23, position: "GOALKEEPER", }, { name: "Cristiano Ronaldo", age: 33, position: "STRIKER", } ]) : Promise<[{ name: string; age: number; position: "GOALKEEPER"; }, { name: string; age: number; position: "STRIKER"; }]> ->Promise.all : { (values: Iterable>): Promise; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: (T | PromiseLike)[]): Promise; } +>Promise.all : { (values: Iterable>): Promise; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: readonly (T | PromiseLike)[]): Promise; } >Promise : PromiseConstructor ->all : { (values: Iterable>): Promise; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: (T | PromiseLike)[]): Promise; } +>all : { (values: Iterable>): Promise; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: readonly (T | PromiseLike)[]): Promise; } >[ { name: "David Gomes", age: 23, position: "GOALKEEPER", }, { name: "Cristiano Ronaldo", age: 33, position: "STRIKER", } ] : [{ name: string; age: number; position: "GOALKEEPER"; }, { name: string; age: number; position: "STRIKER"; }] { >{ name: "David Gomes", age: 23, position: "GOALKEEPER", } : { name: string; age: number; position: "GOALKEEPER"; } diff --git a/tests/baselines/reference/inferenceLimit.types b/tests/baselines/reference/inferenceLimit.types index 6aa7ab501ea..fc2836e6dea 100644 --- a/tests/baselines/reference/inferenceLimit.types +++ b/tests/baselines/reference/inferenceLimit.types @@ -76,9 +76,9 @@ export class BrokenClass { >Promise.all(result.map(populateItems)) .then((orders: Array) => { resolve(orders); }) : Promise >Promise.all(result.map(populateItems)) .then : (onfulfilled?: (value: unknown[]) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >Promise.all(result.map(populateItems)) : Promise ->Promise.all : { (values: Iterable>): Promise; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: (T | PromiseLike)[]): Promise; } +>Promise.all : { (values: Iterable>): Promise; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: readonly (T | PromiseLike)[]): Promise; } >Promise : PromiseConstructor ->all : { (values: Iterable>): Promise; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: (T | PromiseLike)[]): Promise; } +>all : { (values: Iterable>): Promise; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: readonly [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: readonly (T | PromiseLike)[]): Promise; } >result.map(populateItems) : Promise[] >result.map : (callbackfn: (value: MyModule.MyModel, index: number, array: MyModule.MyModel[]) => U, thisArg?: any) => U[] >result : MyModule.MyModel[] diff --git a/tests/cases/compiler/correctOrderOfPromiseMethod.ts b/tests/cases/compiler/correctOrderOfPromiseMethod.ts index 85f4be9843c..70c730c6b20 100644 --- a/tests/cases/compiler/correctOrderOfPromiseMethod.ts +++ b/tests/cases/compiler/correctOrderOfPromiseMethod.ts @@ -17,7 +17,7 @@ async function countEverything(): Promise { const [resultA, resultB] = await Promise.all([ providerA(), providerB(), - ]); + ] as const); const dataA: A[] = resultA; const dataB: B[] = resultB; @@ -25,4 +25,4 @@ async function countEverything(): Promise { return dataA.length + dataB.length; } return 0; -} \ No newline at end of file +} From 816e3f32ea39320281965ebbda390fde2c0ed667 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Thu, 19 Sep 2019 11:35:19 -0700 Subject: [PATCH 078/100] Fix ESLint extension config (#33501) * Fix ESLint extension config * Delete workingDirectories --- .vscode/settings.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 4f481751900..14f7984e7e9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,8 +6,7 @@ } ], "eslint.options": { - "rulePaths": ["../scripts/eslint/built/rules/"], + "rulePaths": ["./scripts/eslint/built/rules/"], "ext": [".ts"] - }, - "eslint.workingDirectories": ["./src", "./scripts"] + } } \ No newline at end of file From e60d28e6f76e7bbb25e06a1742dc9a24fd7a1f16 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Thu, 19 Sep 2019 14:09:54 -0700 Subject: [PATCH 079/100] Update user baselines (#33508) --- .../baselines/reference/docker/azure-sdk.log | 20 +++---- .../reference/docker/office-ui-fabric.log | 5 +- tests/baselines/reference/user/jimp.log | 52 ------------------- 3 files changed, 14 insertions(+), 63 deletions(-) delete mode 100644 tests/baselines/reference/user/jimp.log diff --git a/tests/baselines/reference/docker/azure-sdk.log b/tests/baselines/reference/docker/azure-sdk.log index fb911c5a367..a7ec47a5a84 100644 --- a/tests/baselines/reference/docker/azure-sdk.log +++ b/tests/baselines/reference/docker/azure-sdk.log @@ -9,11 +9,12 @@ XX of XX: [@azure/abort-controller] completed successfully in ? seconds XX of XX: [@azure/core-auth] completed successfully in ? seconds XX of XX: [@azure/core-tracing] completed successfully in ? seconds XX of XX: [@azure/core-http] completed successfully in ? seconds +XX of XX: [@azure/identity] completed successfully in ? seconds +XX of XX: [@azure/core-amqp] completed successfully in ? seconds XX of XX: [@azure/core-arm] completed successfully in ? seconds XX of XX: [@azure/core-paging] completed successfully in ? seconds -XX of XX: [@azure/identity] completed successfully in ? seconds XX of XX: [@azure/test-utils-recorder] completed successfully in ? seconds -XX of XX: [@azure/core-amqp] completed successfully in ? seconds +XX of XX: [@azure/event-hubs] completed successfully in ? seconds XX of XX: [@azure/event-processor-host] completed successfully in ? seconds XX of XX: [@azure/keyvault-keys] completed successfully in ? seconds XX of XX: [@azure/keyvault-secrets] completed successfully in ? seconds @@ -23,7 +24,7 @@ Warning: You have changed the public API signature for this project. Updating re dist-esm/index.js → dist/index.js... (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency -tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) +tslib (imported by dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/auth.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) @azure/cosmos-sign (imported by dist-esm/auth.js) universal-user-agent (imported by dist-esm/common/platform.js) uuid/v4 (imported by dist-esm/ClientContext.js, dist-esm/client/Item/Items.js) @@ -38,7 +39,7 @@ crypto-hash (imported by dist-esm/queryExecutionContext/EndpointComponent/Ordere fast-json-stable-stringify (imported by dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js) (!) Missing global variable names Use output.globals to specify browser global variable names corresponding to external modules -universal-user-agent (guessing 'userAgent') +universal-user-agent (guessing 'universalUserAgent') tslib (guessing 'tslib') @azure/cosmos-sign (guessing 'cosmosSign') debug (guessing 'debugLib') @@ -55,7 +56,6 @@ atob (guessing 'atob') (!) Circular dependency: dist-esm/index.js -> dist-esm/CosmosClient.js -> dist-esm/client/Database/index.js -> dist-esm/client/Database/Database.js -> dist-esm/client/Container/index.js -> dist-esm/client/Container/Container.js -> dist-esm/client/Script/Scripts.js -> dist-esm/index.js (!) Circular dependency: dist-esm/request/RequestHandler.js -> dist-esm/retry/retryUtility.js -> dist-esm/request/RequestHandler.js created dist/index.js in ?s -XX of XX: [@azure/event-hubs] completed successfully in ? seconds XX of XX: [@azure/eventhubs-checkpointstore-blob] completed successfully in ? seconds XX of XX: [@azure/keyvault-certificates] completed successfully in ? seconds Warning: You have changed the public API signature for this project. Updating review/service-bus.api.md @@ -70,17 +70,17 @@ SUCCESS (22) @azure/core-auth (? seconds) @azure/core-tracing (? seconds) @azure/core-http (? seconds) +@azure/identity (? seconds) +@azure/core-amqp (? seconds) @azure/core-arm (? seconds) @azure/core-paging (? seconds) -@azure/identity (? seconds) @azure/test-utils-recorder (? seconds) -@azure/core-amqp (? seconds) +@azure/event-hubs (? seconds) @azure/event-processor-host (? seconds) @azure/keyvault-keys (? seconds) @azure/keyvault-secrets (? seconds) @azure/app-configuration (? seconds) @azure/core-asynciterator-polyfill (? seconds) -@azure/event-hubs (? seconds) @azure/eventhubs-checkpointstore-blob (? seconds) @azure/keyvault-certificates (? seconds) @azure/storage-blob (? seconds) @@ -96,7 +96,7 @@ Warning: You have changed the public API signature for this project. Updating re dist-esm/index.js → dist/index.js... (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency -tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) +tslib (imported by dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/auth.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) @azure/cosmos-sign (imported by dist-esm/auth.js) universal-user-agent (imported by dist-esm/common/platform.js) uuid/v4 (imported by dist-esm/ClientContext.js, dist-esm/client/Item/Items.js) @@ -111,7 +111,7 @@ crypto-hash (imported by dist-esm/queryExecutionContext/EndpointComponent/Ordere fast-json-stable-stringify (imported by dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js) (!) Missing global variable names Use output.globals to specify browser global variable names corresponding to external modules -universal-user-agent (guessing 'userAgent') +universal-user-agent (guessing 'universalUserAgent') tslib (guessing 'tslib') @azure/cosmos-sign (guessing 'cosmosSign') debug (guessing 'debugLib') diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index 56cc33c98c6..30424b5874c 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -36,7 +36,9 @@ Standard output: @uifabric/migration: Done in ?s. @uifabric/monaco-editor: yarn run vX.X.X @uifabric/monaco-editor: $ just-scripts build --production --lint -@uifabric/monaco-editor: [XX:XX:XX XM] ■ Removing [lib] +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Removing [esm, lib] +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/monaco-editor/tsconfig.json +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib --module esnext --project "/office-ui-fabric-react/packages/monaco-editor/tsconfig.json" @uifabric/monaco-editor: Done in ?s. @uifabric/set-version: yarn run vX.X.X @uifabric/set-version: $ just-scripts build --production --lint @@ -88,6 +90,7 @@ Standard output: @uifabric/merge-styles: PASS src/Stylesheet.test.ts @uifabric/merge-styles: PASS src/extractStyleParts.test.ts @uifabric/merge-styles: PASS src/server.test.ts +@uifabric/merge-styles: PASS src/fontFace.test.ts @uifabric/merge-styles: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/merge-styles/lib/index.d.ts' @uifabric/merge-styles: Done in ?s. @uifabric/jest-serializer-merge-styles: yarn run vX.X.X diff --git a/tests/baselines/reference/user/jimp.log b/tests/baselines/reference/user/jimp.log deleted file mode 100644 index 8aa96e8bb82..00000000000 --- a/tests/baselines/reference/user/jimp.log +++ /dev/null @@ -1,52 +0,0 @@ -Exit Code: 1 -Standard output: -node_modules/@jimp/bmp/index.d.ts(1,38): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/gif/index.d.ts(1,27): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/jpeg/index.d.ts(1,59): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-blit/index.d.ts(1,54): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-blur/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-color/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-contain/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-cover/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-crop/index.d.ts(1,37): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-displace/index.d.ts(1,54): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-dither/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-flip/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-gaussian/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-invert/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-mask/index.d.ts(1,54): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-normalize/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-print/index.d.ts(1,54): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-resize/index.d.ts(1,37): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-rotate/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/plugin-scale/index.d.ts(1,31): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/png/index.d.ts(1,59): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/@jimp/tiff/index.d.ts(1,38): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` -node_modules/jimp/types/ts3.1/index.d.ts(16,8): error TS7016: Could not find a declaration file for module '@jimp/core'. '../../../tests/cases/user/jimp/node_modules/@jimp/core/dist/index.js' implicitly has an 'any' type. - Try `npm install @types/jimp__core` if it exists or add a new declaration (.d.ts) file containing `declare module '@jimp/core';` - - - -Standard error: From d4ad0d53dcb9b5fc529f6455074fad1230522f66 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Sep 2019 06:47:42 -0700 Subject: [PATCH 080/100] Cheaper caching scheme --- src/compiler/checker.ts | 54 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 19ffdf46ae0..b1d7a00bd48 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -819,6 +819,7 @@ namespace ts { let flowLoopCount = 0; let sharedFlowCount = 0; let flowAnalysisDisabled = false; + let flowInvocationCount = 0; const emptyStringType = getLiteralType(""); const zeroType = getLiteralType(0); @@ -834,8 +835,7 @@ namespace ts { const symbolLinks: SymbolLinks[] = []; const nodeLinks: NodeLinks[] = []; const flowLoopCaches: Map[] = []; - const flowAssignmentKeys: string[] = []; - const flowAssignmentTypes: FlowType[] = []; + const flowAssignmentTypes: Type[] = []; const flowLoopNodes: FlowNode[] = []; const flowLoopKeys: string[] = []; const flowLoopTypes: Type[][] = []; @@ -16698,12 +16698,6 @@ namespace ts { getInitialTypeOfBindingElement(node); } - function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression, reference: Node) { - return getConstraintForLocation(node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ? - getInitialType(node) : - getAssignedType(node), reference); - } - function isEmptyArrayAssignment(node: VariableDeclaration | BindingElement | Expression) { return node.kind === SyntaxKind.VariableDeclaration && (node).initializer && isEmptyArrayLiteral((node).initializer!) || @@ -16990,6 +16984,7 @@ namespace ts { if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & TypeFlags.Narrowable)) { return declaredType; } + flowInvocationCount++; const sharedFlowStart = sharedFlowCount; const evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode)); sharedFlowCount = sharedFlowStart; @@ -17022,15 +17017,6 @@ namespace ts { flowDepth++; while (true) { const flags = flow.flags; - if (flags & FlowFlags.Cached) { - const key = getOrSetCacheKey(); - if (key) { - const id = getFlowNodeId(flow); - if (flowAssignmentKeys[id] === key) { - return flowAssignmentTypes[id]; - } - } - } if (flags & FlowFlags.Shared) { // We cache results of flow type resolution for shared nodes that were previously visited in // the same getFlowTypeOfReference invocation. A node is considered shared when it is the @@ -17061,15 +17047,6 @@ namespace ts { flow = (flow).antecedent; continue; } - else if (flowLoopCount === flowLoopStart) { // Only cache assignments when not within loop analysis - const key = getOrSetCacheKey(); - if (key && !isIncomplete(type)) { - flow.flags |= FlowFlags.Cached; - const id = getFlowNodeId(flow); - flowAssignmentKeys[id] = key; - flowAssignmentTypes[id] = type; - } - } } else if (flags & FlowFlags.Condition) { type = getTypeAtFlowCondition(flow); @@ -17122,6 +17099,27 @@ namespace ts { } } + function getInitialOrAssignedType(flow: FlowAssignment, reference: Node) { + const node = flow.node; + if (flow.flags & FlowFlags.Cached) { + const cached = flowAssignmentTypes[getNodeId(node)]; + if (cached) { + return cached; + } + } + const startInvocationCount = flowInvocationCount; + const type = getConstraintForLocation(node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ? + getInitialType(node) : + getAssignedType(node), reference); + // We cache the assigned type when getFlowTypeOfReference was recursively invoked in the + // resolution of the assigned type and we're not within loop analysis. + if (flowInvocationCount !== startInvocationCount && flowLoopCount === flowLoopStart) { + flow.flags |= FlowFlags.Cached; + flowAssignmentTypes[getNodeId(node)] = type; + } + return type; + } + function getTypeAtFlowAssignment(flow: FlowAssignment) { const node = flow.node; // Assignments only narrow the computed type if the declared type is a union type. Thus, we @@ -17135,11 +17133,11 @@ namespace ts { if (isEmptyArrayAssignment(node)) { return getEvolvingArrayType(neverType); } - const assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node, reference)); + const assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(flow, reference)); return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType; } if (declaredType.flags & TypeFlags.Union) { - return getAssignmentReducedType(declaredType, getInitialOrAssignedType(node, reference)); + return getAssignmentReducedType(declaredType, getInitialOrAssignedType(flow, reference)); } return declaredType; } From 7573a6d0f81bafe626bc11f55b46b431ddafbd7a Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Fri, 20 Sep 2019 09:17:19 -0700 Subject: [PATCH 081/100] Update user baselines (#33534) --- tests/baselines/reference/docker/azure-sdk.log | 14 ++++++++------ .../reference/docker/office-ui-fabric.log | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/baselines/reference/docker/azure-sdk.log b/tests/baselines/reference/docker/azure-sdk.log index a7ec47a5a84..ba878ab443a 100644 --- a/tests/baselines/reference/docker/azure-sdk.log +++ b/tests/baselines/reference/docker/azure-sdk.log @@ -18,13 +18,13 @@ XX of XX: [@azure/event-hubs] completed successfully in ? seconds XX of XX: [@azure/event-processor-host] completed successfully in ? seconds XX of XX: [@azure/keyvault-keys] completed successfully in ? seconds XX of XX: [@azure/keyvault-secrets] completed successfully in ? seconds -XX of XX: [@azure/app-configuration] completed successfully in ? seconds +Warning: You have changed the public API signature for this project. Updating review/app-configuration.api.md XX of XX: [@azure/core-asynciterator-polyfill] completed successfully in ? seconds Warning: You have changed the public API signature for this project. Updating review/cosmos.api.md dist-esm/index.js → dist/index.js... (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency -tslib (imported by dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/auth.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) +tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) @azure/cosmos-sign (imported by dist-esm/auth.js) universal-user-agent (imported by dist-esm/common/platform.js) uuid/v4 (imported by dist-esm/ClientContext.js, dist-esm/client/Item/Items.js) @@ -64,7 +64,7 @@ XX of XX: [@azure/storage-file] completed successfully in ? seconds XX of XX: [@azure/storage-queue] completed successfully in ? seconds XX of XX: [@azure/template] completed successfully in ? seconds XX of XX: [testhub] completed successfully in ? seconds -SUCCESS (22) +SUCCESS (21) ================================ @azure/abort-controller (? seconds) @azure/core-auth (? seconds) @@ -79,7 +79,6 @@ SUCCESS (22) @azure/event-processor-host (? seconds) @azure/keyvault-keys (? seconds) @azure/keyvault-secrets (? seconds) -@azure/app-configuration (? seconds) @azure/core-asynciterator-polyfill (? seconds) @azure/eventhubs-checkpointstore-blob (? seconds) @azure/keyvault-certificates (? seconds) @@ -89,14 +88,16 @@ SUCCESS (22) @azure/template (? seconds) testhub (? seconds) ================================ -SUCCESS WITH WARNINGS (2) +SUCCESS WITH WARNINGS (3) ================================ +@azure/app-configuration (? seconds) +Warning: You have changed the public API signature for this project. Updating review/app-configuration.api.md @azure/cosmos (? seconds) Warning: You have changed the public API signature for this project. Updating review/cosmos.api.md dist-esm/index.js → dist/index.js... (!) Unresolved dependencies https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency -tslib (imported by dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/auth.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) +tslib (imported by dist-esm/auth.js, dist-esm/queryIterator.js, dist-esm/CosmosClient.js, dist-esm/plugins/Plugin.js, dist-esm/ClientContext.js, dist-esm/globalEndpointManager.js, dist-esm/client/Conflict/Conflict.js, dist-esm/client/Container/Container.js, dist-esm/client/Container/Containers.js, dist-esm/client/Database/Database.js, dist-esm/client/Database/Databases.js, dist-esm/client/Item/Item.js, dist-esm/client/Item/Items.js, dist-esm/client/Offer/Offer.js, dist-esm/client/Permission/Permission.js, dist-esm/client/Permission/Permissions.js, dist-esm/client/StoredProcedure/StoredProcedure.js, dist-esm/client/StoredProcedure/StoredProcedures.js, dist-esm/client/Trigger/Trigger.js, dist-esm/client/Trigger/Triggers.js, dist-esm/client/User/User.js, dist-esm/client/User/Users.js, dist-esm/client/UserDefinedFunction/UserDefinedFunction.js, dist-esm/client/UserDefinedFunction/UserDefinedFunctions.js, dist-esm/queryExecutionContext/defaultQueryExecutionContext.js, dist-esm/queryExecutionContext/documentProducer.js, dist-esm/queryExecutionContext/parallelQueryExecutionContextBase.js, dist-esm/queryExecutionContext/pipelinedQueryExecutionContext.js, dist-esm/request/request.js, dist-esm/request/RequestHandler.js, dist-esm/ChangeFeedIterator.js, dist-esm/routing/smartRoutingMapProvider.js, dist-esm/queryExecutionContext/EndpointComponent/AggregateEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OffsetLimitEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderByEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/OrderedDistinctEndpointComponent.js, dist-esm/queryExecutionContext/EndpointComponent/UnorderedDistinctEndpointComponent.js, dist-esm/retry/retryUtility.js, dist-esm/routing/partitionKeyRangeCache.js, dist-esm/retry/defaultRetryPolicy.js, dist-esm/retry/endpointDiscoveryRetryPolicy.js, dist-esm/retry/resourceThrottleRetryPolicy.js, dist-esm/retry/sessionRetryPolicy.js) @azure/cosmos-sign (imported by dist-esm/auth.js) universal-user-agent (imported by dist-esm/common/platform.js) uuid/v4 (imported by dist-esm/ClientContext.js, dist-esm/client/Item/Items.js) @@ -136,6 +137,7 @@ rush rebuild ( ? seconds) Standard error: +XX of XX: [@azure/app-configuration] completed with warnings in ? seconds XX of XX: [@azure/cosmos] completed with warnings in ? seconds XX of XX: [@azure/service-bus] completed with warnings in ? seconds Project(s) succeeded with warnings diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index 30424b5874c..7bd402b8327 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -90,7 +90,7 @@ Standard output: @uifabric/merge-styles: PASS src/Stylesheet.test.ts @uifabric/merge-styles: PASS src/extractStyleParts.test.ts @uifabric/merge-styles: PASS src/server.test.ts -@uifabric/merge-styles: PASS src/fontFace.test.ts +@uifabric/merge-styles: PASS src/concatStyleSetsWithProps.test.ts @uifabric/merge-styles: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/merge-styles/lib/index.d.ts' @uifabric/merge-styles: Done in ?s. @uifabric/jest-serializer-merge-styles: yarn run vX.X.X From 007b4b1e31623aa8a108219262819d07ba63202a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Sep 2019 10:24:02 -0700 Subject: [PATCH 082/100] Minor simplification --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b1d7a00bd48..28e20febdcd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17099,7 +17099,7 @@ namespace ts { } } - function getInitialOrAssignedType(flow: FlowAssignment, reference: Node) { + function getInitialOrAssignedType(flow: FlowAssignment) { const node = flow.node; if (flow.flags & FlowFlags.Cached) { const cached = flowAssignmentTypes[getNodeId(node)]; @@ -17133,11 +17133,11 @@ namespace ts { if (isEmptyArrayAssignment(node)) { return getEvolvingArrayType(neverType); } - const assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(flow, reference)); + const assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(flow)); return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType; } if (declaredType.flags & TypeFlags.Union) { - return getAssignmentReducedType(declaredType, getInitialOrAssignedType(flow, reference)); + return getAssignmentReducedType(declaredType, getInitialOrAssignedType(flow)); } return declaredType; } From 26c816f932a0177ffda094dc4b4b46a4b5f582f2 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Fri, 20 Sep 2019 15:20:10 -0400 Subject: [PATCH 083/100] When a packed version of TypeScript ios requested, also send a request to create a build of monaco for the playground --- scripts/post-vsts-artifact-comment.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/post-vsts-artifact-comment.js b/scripts/post-vsts-artifact-comment.js index 6d84294bcfe..5b1685ae040 100644 --- a/scripts/post-vsts-artifact-comment.js +++ b/scripts/post-vsts-artifact-comment.js @@ -28,6 +28,10 @@ async function main() { type: "token", token: process.argv[2] }); + + // Please keep the strings "an installable tgz" and "packed" in this message, as well as the devDependencies section, + // so that the playgrounds deployment process can find these comments. + await gh.issues.createComment({ number: +process.env.SOURCE_ISSUE, owner: "Microsoft", @@ -43,6 +47,9 @@ async function main() { and then running \`npm install\`. ` }); + + // Send a ping to https://github.com/orta/make-monaco-builds#pull-request-builds + await gh.request("POST /repos/orta/make-monaco-builds/dispatches", { event_type: +process.env.SOURCE_ISSUE }) } main().catch(async e => { @@ -61,4 +68,4 @@ main().catch(async e => { body: `Hey @${process.env.REQUESTING_USER}, something went wrong when looking for the build artifact. ([You can check the log here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary)).` }); } -}); \ No newline at end of file +}); From cc3ee3013d419908daf92f4b2b0b7b0cc381fe36 Mon Sep 17 00:00:00 2001 From: Nuno Arruda Date: Fri, 20 Sep 2019 22:11:22 +0200 Subject: [PATCH 084/100] Fix grammar issues on CONTRIBUTING.md (#33535) --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 18c0a352cbd..4b804414ab5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,7 +71,7 @@ Design changes will not be accepted at this time. If you have a design change pr You will need to complete a Contributor License Agreement (CLA). Briefly, this agreement testifies that you are granting us permission to use the submitted change according to the terms of the project's license, and that the work being submitted is under appropriate copyright. -Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Alternatively, download the agreement ([Microsoft Contribution License Agreement.pdf](https://opensource.microsoft.com/pdf/microsoft-contribution-license-agreement.pdf)), sign, scan, and email it back to . Be sure to include your github user name along with the agreement. Once we have received the signed CLA, we'll review the request. +Please submit a Contributor License Agreement (CLA) before submitting a pull request. You may visit https://cla.microsoft.com to sign digitally. Alternatively, download the agreement ([Microsoft Contribution License Agreement.pdf](https://opensource.microsoft.com/pdf/microsoft-contribution-license-agreement.pdf)), sign, scan, and email it back to . Be sure to include your GitHub user name along with the agreement. Once we have received the signed CLA, we'll review the request. ## Housekeeping @@ -148,7 +148,7 @@ You will probably only want to debug one test at a time: gulp runtests-browser --tests=2dArrays ``` -You can specify which browser to use for debugging. Currently Chrome and IE are supported: +You can specify which browser to use for debugging. Currently, Chrome and IE are supported: ```Shell gulp runtests-browser --tests=2dArrays --browser=chrome From 1cad8edfa74ce97d1e868b071997a5354f16f93e Mon Sep 17 00:00:00 2001 From: Nathan Fenner Date: Fri, 20 Sep 2019 14:00:11 -0700 Subject: [PATCH 085/100] check for SyntaxKind.JSXAttribute instead of located-ness of name prop --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5833d2e9c8c..e7954aa5d63 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13040,9 +13040,9 @@ namespace ts { // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal. // However, using an object-literal error message will be very confusing to the users so we give different a message. // TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages) - if (prop.valueDeclaration && isNamedDeclaration(prop.valueDeclaration) && prop.valueDeclaration.name && prop.valueDeclaration.name.pos !== -1) { - // If the "children" attribute is extraneous `extra` then the declaration's name has no location. - // In that case, do not update the error location, since there's no name to point to. + if (prop.valueDeclaration && isJsxAttribute(prop.valueDeclaration)) { + // Note that extraneous children (as in `extra`) don't pass this check, + // since `children` is a SyntaxKind.PropertySignature instead of a SyntaxKind.JsxAttribute. errorNode = prop.valueDeclaration.name; } reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget)); From 21b5418cef70ac23a95570d38758b75b90684b72 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Sep 2019 17:17:39 -0700 Subject: [PATCH 086/100] Add tests --- .../exhaustiveSwitchImplicitReturn.ts | 14 ++ .../controlFlow/assertionTypePredicates1.ts | 128 +++++++++++ .../exhaustiveSwitchStatements1.ts | 199 ++++++++++++++++++ .../controlFlow/neverReturningFunctions1.ts | 158 ++++++++++++++ .../assertionsAndNonReturningFunctions.ts | 65 ++++++ 5 files changed, 564 insertions(+) create mode 100644 tests/cases/conformance/controlFlow/assertionTypePredicates1.ts create mode 100644 tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts create mode 100644 tests/cases/conformance/controlFlow/neverReturningFunctions1.ts create mode 100644 tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.ts diff --git a/tests/cases/compiler/exhaustiveSwitchImplicitReturn.ts b/tests/cases/compiler/exhaustiveSwitchImplicitReturn.ts index b87baffdaf9..7355a5dba30 100644 --- a/tests/cases/compiler/exhaustiveSwitchImplicitReturn.ts +++ b/tests/cases/compiler/exhaustiveSwitchImplicitReturn.ts @@ -40,3 +40,17 @@ function foo5(bar: "a" | "b"): number { return 1; } } + +function foo6(bar: "a", a: boolean, b: boolean): number { + if (a) { + switch (bar) { + case "a": return 1; + } + } + else { + switch (b) { + case true: return -1; + case false: return 0; + } + } +} diff --git a/tests/cases/conformance/controlFlow/assertionTypePredicates1.ts b/tests/cases/conformance/controlFlow/assertionTypePredicates1.ts new file mode 100644 index 00000000000..b20cd42414b --- /dev/null +++ b/tests/cases/conformance/controlFlow/assertionTypePredicates1.ts @@ -0,0 +1,128 @@ +// @strict: true +// @declaration: true + +declare function isString(value: unknown): value is string; +declare function isArrayOfStrings(value: unknown): value is string[]; + +const assert: (value: unknown) => asserts value = value => {} + +declare function assertIsString(value: unknown): asserts value is string; +declare function assertIsArrayOfStrings(value: unknown): asserts value is string[]; +declare function assertDefined(value: T): asserts value is NonNullable; + +function f01(x: unknown) { + if (!!true) { + assert(typeof x === "string"); + x.length; + } + if (!!true) { + assert(x instanceof Error); + x.message; + } + if (!!true) { + assert(typeof x === "boolean" || typeof x === "number"); + x.toLocaleString; + } + if (!!true) { + assert(isArrayOfStrings(x)); + x[0].length; + } + if (!!true) { + assertIsArrayOfStrings(x); + x[0].length; + } + if (!!true) { + assert(x === undefined || typeof x === "string"); + x; // string | undefined + assertDefined(x); + x; // string + } +} + +function f02(x: string | undefined) { + if (!!true) { + assert(x); + x.length; + } + if (!!true) { + assert(x !== undefined); + x.length; + } + if (!!true) { + assertDefined(x); + x.length; + } +} + +function f03(x: string | undefined, assert: (value: unknown) => asserts value) { + assert(x); + x.length; +} + +namespace Debug { + export declare function assert(value: unknown, message?: string): asserts value; + export declare function assertDefined(value: T): asserts value is NonNullable; +} + +function f10(x: string | undefined) { + if (!!true) { + Debug.assert(x); + x.length; + } + if (!!true) { + Debug.assert(x !== undefined); + x.length; + } + if (!!true) { + Debug.assertDefined(x); + x.length; + } +} + +class Test { + assert(value: unknown): asserts value { + if (value) return; + throw new Error(); + } + isTest2(): this is Test2 { + return this instanceof Test2; + } + assertIsTest2(): asserts this is Test2 { + if (this instanceof Test2) return; + throw new Error(); + } + assertThis(): asserts this { + if (!this) return; + throw new Error(); + } + bar() { + this.assertThis(); + this; + } + foo(x: unknown) { + this.assert(typeof x === "string"); + x.length; + if (this.isTest2()) { + this.z; + } + this.assertIsTest2(); + this.z; + } +} + +class Test2 extends Test { + z = 0; +} + +// Invalid constructs + +declare let Q1: new (x: unknown) => x is string; +declare let Q2: new (x: boolean) => asserts x; +declare let Q3: new (x: unknown) => asserts x is string; + +declare class Wat { + get p1(): this is string; + set p1(x: this is string); + get p2(): asserts this is string; + set p2(x: asserts this is string); +} diff --git a/tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts b/tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts new file mode 100644 index 00000000000..9fd0f608ddb --- /dev/null +++ b/tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts @@ -0,0 +1,199 @@ +// @strict: true +// @allowUnreachableCode: false +// @declaration: true + +function f1(x: 1 | 2): string { + if (!!true) { + switch (x) { + case 1: return 'a'; + case 2: return 'b'; + } + x; // Unreachable + } + else { + throw 0; + } +} + +function f2(x: 1 | 2) { + let z: number; + switch (x) { + case 1: z = 10; break; + case 2: z = 20; break; + } + z; // Definitely assigned +} + +function f3(x: 1 | 2) { + switch (x) { + case 1: return 10; + case 2: return 20; + // Default considered reachable to allow defensive coding + default: throw new Error("Bad input"); + } +} + +// Repro from #11572 + +enum E { A, B } + +function f(e: E): number { + switch (e) { + case E.A: return 0 + case E.B: return 1 + } +} + +function g(e: E): number { + if (!true) + return -1 + else + switch (e) { + case E.A: return 0 + case E.B: return 1 + } +} + +// Repro from #12668 + +interface Square { kind: "square"; size: number; } + +interface Rectangle { kind: "rectangle"; width: number; height: number; } + +interface Circle { kind: "circle"; radius: number; } + +interface Triangle { kind: "triangle"; side: number; } + +type Shape = Square | Rectangle | Circle | Triangle; + +function area(s: Shape): number { + let area; + switch (s.kind) { + case "square": area = s.size * s.size; break; + case "rectangle": area = s.width * s.height; break; + case "circle": area = Math.PI * s.radius * s.radius; break; + case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break; + } + return area; +} + +function areaWrapped(s: Shape): number { + let area; + area = (() => { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; + } + })(); + return area; +} + +// Repro from #13241 + +enum MyEnum { + A, + B +} + +function thisGivesError(e: MyEnum): string { + let s: string; + switch (e) { + case MyEnum.A: s = "it was A"; break; + case MyEnum.B: s = "it was B"; break; + } + return s; +} + +function good1(e: MyEnum): string { + let s: string; + switch (e) { + case MyEnum.A: s = "it was A"; break; + case MyEnum.B: s = "it was B"; break; + default: s = "it was something else"; break; + } + return s; +} + +function good2(e: MyEnum): string { + switch (e) { + case MyEnum.A: return "it was A"; + case MyEnum.B: return "it was B"; + } +} + +// Repro from #18362 + +enum Level { + One, + Two, +} + +const doSomethingWithLevel = (level: Level) => { + let next: Level; + switch (level) { + case Level.One: + next = Level.Two; + break; + case Level.Two: + next = Level.One; + break; + } + return next; +}; + +// Repro from #20409 + +interface Square2 { + kind: "square"; + size: number; +} + +interface Circle2 { + kind: "circle"; + radius: number; +} + +type Shape2 = Square2 | Circle2; + +function withDefault(s1: Shape2, s2: Shape2): string { + switch (s1.kind) { + case "square": + return "1"; + case "circle": + switch (s2.kind) { + case "square": + return "2"; + case "circle": + return "3"; + default: + return "never"; + } + } +} + +function withoutDefault(s1: Shape2, s2: Shape2): string { + switch (s1.kind) { + case "square": + return "1"; + case "circle": + switch (s2.kind) { + case "square": + return "2"; + case "circle": + return "3"; + } + } +} + +// Repro from #20823 + +function test4(value: 1 | 2) { + let x: string; + switch (value) { + case 1: x = "one"; break; + case 2: x = "two"; break; + } + return x; +} diff --git a/tests/cases/conformance/controlFlow/neverReturningFunctions1.ts b/tests/cases/conformance/controlFlow/neverReturningFunctions1.ts new file mode 100644 index 00000000000..63e7ecf786f --- /dev/null +++ b/tests/cases/conformance/controlFlow/neverReturningFunctions1.ts @@ -0,0 +1,158 @@ +// @strict: true +// @allowUnreachableCode: false +// @declaration: true + +function fail(message?: string): never { + throw new Error(message); +} + +function f01(x: string | undefined) { + if (x === undefined) fail("undefined argument"); + x.length; // string +} + +function f02(x: number): number { + if (x >= 0) return x; + fail("negative number"); + x; // Unreachable +} + +function f03(x: string) { + x; // string + fail(); + x; // Unreachable +} + +function f11(x: string | undefined, fail: (message?: string) => never) { + if (x === undefined) fail("undefined argument"); + x.length; // string +} + +function f12(x: number, fail: (message?: string) => never): number { + if (x >= 0) return x; + fail("negative number"); + x; // Unreachable +} + +function f13(x: string, fail: (message?: string) => never) { + x; // string + fail(); + x; // Unreachable +} + +namespace Debug { + export declare function fail(message?: string): never; +} + +function f21(x: string | undefined) { + if (x === undefined) Debug.fail("undefined argument"); + x.length; // string +} + +function f22(x: number): number { + if (x >= 0) return x; + Debug.fail("negative number"); + x; // Unreachable +} + +function f23(x: string) { + x; // string + Debug.fail(); + x; // Unreachable +} + +function f24(x: string) { + x; // string + ((Debug).fail)(); + x; // Unreachable +} + +class Test { + fail(message?: string): never { + throw new Error(message); + } + f1(x: string | undefined) { + if (x === undefined) this.fail("undefined argument"); + x.length; // string + } + f2(x: number): number { + if (x >= 0) return x; + this.fail("negative number"); + x; // Unreachable + } + f3(x: string) { + x; // string + this.fail(); + x; // Unreachable + } +} + +function f30(x: string | number | undefined) { + if (typeof x === "string") { + fail(); + x; // Unreachable + } + else { + x; // number | undefined + if (x !== undefined) { + x; // number + fail(); + x; // Unreachable + } + else { + x; // undefined + fail(); + x; // Unreachable + } + x; // Unreachable + } + x; // Unreachable +} + +function f31(x: { a: string | number }) { + if (typeof x.a === "string") { + fail(); + x; // Unreachable + x.a; // Unreachable + } + x; // { a: string | number } + x.a; // number +} + +function f40(x: number) { + try { + x; + fail(); + x; // Unreachable + } + finally { + x; + fail(); + x; // Unreachable + } + x; // Unreachable +} + +function f41(x: number) { + try { + x; + } + finally { + x; + fail(); + x; // Unreachable + } + x; // Unreachable +} + +function f42(x: number) { + try { + x; + fail(); + x; // Unreachable + } + finally { + x; + } + x; // Unreachable +} diff --git a/tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.ts b/tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.ts new file mode 100644 index 00000000000..9a15a5b5245 --- /dev/null +++ b/tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.ts @@ -0,0 +1,65 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @allowUnreachableCode: false +// @filename: assertionsAndNonReturningFunctions.js + +/** @typedef {(check: boolean) => asserts check} AssertFunc */ + +/** @type {AssertFunc} */ +const assert = check => { + if (!check) throw new Error(); +} + +/** @type {(x: unknown) => asserts x is string } */ +function assertIsString(x) { + if (!(typeof x === "string")) throw new Error(); +} + +/** + * @param {boolean} check + * @returns {asserts check} +*/ +function assert2(check) { + if (!check) throw new Error(); +} + +/** + * @returns {never} + */ +function fail() { + throw new Error(); +} + +/** + * @param {*} x + */ +function f1(x) { + if (!!true) { + assert(typeof x === "string"); + x.length; + } + if (!!true) { + assert2(typeof x === "string"); + x.length; + } + if (!!true) { + assertIsString(x); + x.length; + } + if (!!true) { + fail(); + x; // Unreachable + } +} + +/** + * @param {boolean} b + */ +function f2(b) { + switch (b) { + case true: return 1; + case false: return 0; + } + b; // Unreachable +} From 97d69d442d78b30caef06101b27758d7d97c8e3f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Sep 2019 17:18:08 -0700 Subject: [PATCH 087/100] Accept new baselines --- .../assertionTypePredicates1.errors.txt | 150 +++++ .../reference/assertionTypePredicates1.js | 289 +++++++++ .../assertionTypePredicates1.symbols | 359 +++++++++++ .../reference/assertionTypePredicates1.types | 438 +++++++++++++ ...ertionsAndNonReturningFunctions.errors.txt | 69 ++ ...assertionsAndNonReturningFunctions.symbols | 109 ++++ .../assertionsAndNonReturningFunctions.types | 152 +++++ .../exhaustiveSwitchImplicitReturn.errors.txt | 14 + .../exhaustiveSwitchImplicitReturn.js | 27 + .../exhaustiveSwitchImplicitReturn.symbols | 25 + .../exhaustiveSwitchImplicitReturn.types | 33 + .../exhaustiveSwitchStatements1.errors.txt | 202 ++++++ .../reference/exhaustiveSwitchStatements1.js | 437 +++++++++++++ .../exhaustiveSwitchStatements1.symbols | 503 +++++++++++++++ .../exhaustiveSwitchStatements1.types | 595 ++++++++++++++++++ .../neverReturningFunctions1.errors.txt | 227 +++++++ .../reference/neverReturningFunctions1.js | 337 ++++++++++ .../neverReturningFunctions1.symbols | 387 ++++++++++++ .../reference/neverReturningFunctions1.types | 439 +++++++++++++ 19 files changed, 4792 insertions(+) create mode 100644 tests/baselines/reference/assertionTypePredicates1.errors.txt create mode 100644 tests/baselines/reference/assertionTypePredicates1.js create mode 100644 tests/baselines/reference/assertionTypePredicates1.symbols create mode 100644 tests/baselines/reference/assertionTypePredicates1.types create mode 100644 tests/baselines/reference/assertionsAndNonReturningFunctions.errors.txt create mode 100644 tests/baselines/reference/assertionsAndNonReturningFunctions.symbols create mode 100644 tests/baselines/reference/assertionsAndNonReturningFunctions.types create mode 100644 tests/baselines/reference/exhaustiveSwitchStatements1.errors.txt create mode 100644 tests/baselines/reference/exhaustiveSwitchStatements1.js create mode 100644 tests/baselines/reference/exhaustiveSwitchStatements1.symbols create mode 100644 tests/baselines/reference/exhaustiveSwitchStatements1.types create mode 100644 tests/baselines/reference/neverReturningFunctions1.errors.txt create mode 100644 tests/baselines/reference/neverReturningFunctions1.js create mode 100644 tests/baselines/reference/neverReturningFunctions1.symbols create mode 100644 tests/baselines/reference/neverReturningFunctions1.types diff --git a/tests/baselines/reference/assertionTypePredicates1.errors.txt b/tests/baselines/reference/assertionTypePredicates1.errors.txt new file mode 100644 index 00000000000..91d2e869bd2 --- /dev/null +++ b/tests/baselines/reference/assertionTypePredicates1.errors.txt @@ -0,0 +1,150 @@ +tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(116,37): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(117,37): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(118,37): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(121,15): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(122,15): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(123,15): error TS1228: A type predicate is only allowed in return type position for functions and methods. +tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(124,15): error TS1228: A type predicate is only allowed in return type position for functions and methods. + + +==== tests/cases/conformance/controlFlow/assertionTypePredicates1.ts (7 errors) ==== + declare function isString(value: unknown): value is string; + declare function isArrayOfStrings(value: unknown): value is string[]; + + const assert: (value: unknown) => asserts value = value => {} + + declare function assertIsString(value: unknown): asserts value is string; + declare function assertIsArrayOfStrings(value: unknown): asserts value is string[]; + declare function assertDefined(value: T): asserts value is NonNullable; + + function f01(x: unknown) { + if (!!true) { + assert(typeof x === "string"); + x.length; + } + if (!!true) { + assert(x instanceof Error); + x.message; + } + if (!!true) { + assert(typeof x === "boolean" || typeof x === "number"); + x.toLocaleString; + } + if (!!true) { + assert(isArrayOfStrings(x)); + x[0].length; + } + if (!!true) { + assertIsArrayOfStrings(x); + x[0].length; + } + if (!!true) { + assert(x === undefined || typeof x === "string"); + x; // string | undefined + assertDefined(x); + x; // string + } + } + + function f02(x: string | undefined) { + if (!!true) { + assert(x); + x.length; + } + if (!!true) { + assert(x !== undefined); + x.length; + } + if (!!true) { + assertDefined(x); + x.length; + } + } + + function f03(x: string | undefined, assert: (value: unknown) => asserts value) { + assert(x); + x.length; + } + + namespace Debug { + export declare function assert(value: unknown, message?: string): asserts value; + export declare function assertDefined(value: T): asserts value is NonNullable; + } + + function f10(x: string | undefined) { + if (!!true) { + Debug.assert(x); + x.length; + } + if (!!true) { + Debug.assert(x !== undefined); + x.length; + } + if (!!true) { + Debug.assertDefined(x); + x.length; + } + } + + class Test { + assert(value: unknown): asserts value { + if (value) return; + throw new Error(); + } + isTest2(): this is Test2 { + return this instanceof Test2; + } + assertIsTest2(): asserts this is Test2 { + if (this instanceof Test2) return; + throw new Error(); + } + assertThis(): asserts this { + if (!this) return; + throw new Error(); + } + bar() { + this.assertThis(); + this; + } + foo(x: unknown) { + this.assert(typeof x === "string"); + x.length; + if (this.isTest2()) { + this.z; + } + this.assertIsTest2(); + this.z; + } + } + + class Test2 extends Test { + z = 0; + } + + // Invalid constructs + + declare let Q1: new (x: unknown) => x is string; + ~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + declare let Q2: new (x: boolean) => asserts x; + ~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + declare let Q3: new (x: unknown) => asserts x is string; + ~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + + declare class Wat { + get p1(): this is string; + ~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + set p1(x: this is string); + ~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + get p2(): asserts this is string; + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + set p2(x: asserts this is string); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1228: A type predicate is only allowed in return type position for functions and methods. + } + \ No newline at end of file diff --git a/tests/baselines/reference/assertionTypePredicates1.js b/tests/baselines/reference/assertionTypePredicates1.js new file mode 100644 index 00000000000..ad21d116b73 --- /dev/null +++ b/tests/baselines/reference/assertionTypePredicates1.js @@ -0,0 +1,289 @@ +//// [assertionTypePredicates1.ts] +declare function isString(value: unknown): value is string; +declare function isArrayOfStrings(value: unknown): value is string[]; + +const assert: (value: unknown) => asserts value = value => {} + +declare function assertIsString(value: unknown): asserts value is string; +declare function assertIsArrayOfStrings(value: unknown): asserts value is string[]; +declare function assertDefined(value: T): asserts value is NonNullable; + +function f01(x: unknown) { + if (!!true) { + assert(typeof x === "string"); + x.length; + } + if (!!true) { + assert(x instanceof Error); + x.message; + } + if (!!true) { + assert(typeof x === "boolean" || typeof x === "number"); + x.toLocaleString; + } + if (!!true) { + assert(isArrayOfStrings(x)); + x[0].length; + } + if (!!true) { + assertIsArrayOfStrings(x); + x[0].length; + } + if (!!true) { + assert(x === undefined || typeof x === "string"); + x; // string | undefined + assertDefined(x); + x; // string + } +} + +function f02(x: string | undefined) { + if (!!true) { + assert(x); + x.length; + } + if (!!true) { + assert(x !== undefined); + x.length; + } + if (!!true) { + assertDefined(x); + x.length; + } +} + +function f03(x: string | undefined, assert: (value: unknown) => asserts value) { + assert(x); + x.length; +} + +namespace Debug { + export declare function assert(value: unknown, message?: string): asserts value; + export declare function assertDefined(value: T): asserts value is NonNullable; +} + +function f10(x: string | undefined) { + if (!!true) { + Debug.assert(x); + x.length; + } + if (!!true) { + Debug.assert(x !== undefined); + x.length; + } + if (!!true) { + Debug.assertDefined(x); + x.length; + } +} + +class Test { + assert(value: unknown): asserts value { + if (value) return; + throw new Error(); + } + isTest2(): this is Test2 { + return this instanceof Test2; + } + assertIsTest2(): asserts this is Test2 { + if (this instanceof Test2) return; + throw new Error(); + } + assertThis(): asserts this { + if (!this) return; + throw new Error(); + } + bar() { + this.assertThis(); + this; + } + foo(x: unknown) { + this.assert(typeof x === "string"); + x.length; + if (this.isTest2()) { + this.z; + } + this.assertIsTest2(); + this.z; + } +} + +class Test2 extends Test { + z = 0; +} + +// Invalid constructs + +declare let Q1: new (x: unknown) => x is string; +declare let Q2: new (x: boolean) => asserts x; +declare let Q3: new (x: unknown) => asserts x is string; + +declare class Wat { + get p1(): this is string; + set p1(x: this is string); + get p2(): asserts this is string; + set p2(x: asserts this is string); +} + + +//// [assertionTypePredicates1.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var assert = function (value) { }; +function f01(x) { + if (!!true) { + assert(typeof x === "string"); + x.length; + } + if (!!true) { + assert(x instanceof Error); + x.message; + } + if (!!true) { + assert(typeof x === "boolean" || typeof x === "number"); + x.toLocaleString; + } + if (!!true) { + assert(isArrayOfStrings(x)); + x[0].length; + } + if (!!true) { + assertIsArrayOfStrings(x); + x[0].length; + } + if (!!true) { + assert(x === undefined || typeof x === "string"); + x; // string | undefined + assertDefined(x); + x; // string + } +} +function f02(x) { + if (!!true) { + assert(x); + x.length; + } + if (!!true) { + assert(x !== undefined); + x.length; + } + if (!!true) { + assertDefined(x); + x.length; + } +} +function f03(x, assert) { + assert(x); + x.length; +} +var Debug; +(function (Debug) { +})(Debug || (Debug = {})); +function f10(x) { + if (!!true) { + Debug.assert(x); + x.length; + } + if (!!true) { + Debug.assert(x !== undefined); + x.length; + } + if (!!true) { + Debug.assertDefined(x); + x.length; + } +} +var Test = /** @class */ (function () { + function Test() { + } + Test.prototype.assert = function (value) { + if (value) + return; + throw new Error(); + }; + Test.prototype.isTest2 = function () { + return this instanceof Test2; + }; + Test.prototype.assertIsTest2 = function () { + if (this instanceof Test2) + return; + throw new Error(); + }; + Test.prototype.assertThis = function () { + if (!this) + return; + throw new Error(); + }; + Test.prototype.bar = function () { + this.assertThis(); + this; + }; + Test.prototype.foo = function (x) { + this.assert(typeof x === "string"); + x.length; + if (this.isTest2()) { + this.z; + } + this.assertIsTest2(); + this.z; + }; + return Test; +}()); +var Test2 = /** @class */ (function (_super) { + __extends(Test2, _super); + function Test2() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.z = 0; + return _this; + } + return Test2; +}(Test)); + + +//// [assertionTypePredicates1.d.ts] +declare function isString(value: unknown): value is string; +declare function isArrayOfStrings(value: unknown): value is string[]; +declare const assert: (value: unknown) => asserts value; +declare function assertIsString(value: unknown): asserts value is string; +declare function assertIsArrayOfStrings(value: unknown): asserts value is string[]; +declare function assertDefined(value: T): asserts value is NonNullable; +declare function f01(x: unknown): void; +declare function f02(x: string | undefined): void; +declare function f03(x: string | undefined, assert: (value: unknown) => asserts value): void; +declare namespace Debug { + function assert(value: unknown, message?: string): asserts value; + function assertDefined(value: T): asserts value is NonNullable; +} +declare function f10(x: string | undefined): void; +declare class Test { + assert(value: unknown): asserts value; + isTest2(): this is Test2; + assertIsTest2(): asserts this is Test2; + assertThis(): asserts this; + bar(): void; + foo(x: unknown): void; +} +declare class Test2 extends Test { + z: number; +} +declare let Q1: new (x: unknown) => x is string; +declare let Q2: new (x: boolean) => asserts x; +declare let Q3: new (x: unknown) => asserts x is string; +declare class Wat { + get p1(): this is string; + set p1(x: this is string); + get p2(): asserts this is string; + set p2(x: asserts this is string); +} diff --git a/tests/baselines/reference/assertionTypePredicates1.symbols b/tests/baselines/reference/assertionTypePredicates1.symbols new file mode 100644 index 00000000000..c68a1926aff --- /dev/null +++ b/tests/baselines/reference/assertionTypePredicates1.symbols @@ -0,0 +1,359 @@ +=== tests/cases/conformance/controlFlow/assertionTypePredicates1.ts === +declare function isString(value: unknown): value is string; +>isString : Symbol(isString, Decl(assertionTypePredicates1.ts, 0, 0)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 0, 26)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 0, 26)) + +declare function isArrayOfStrings(value: unknown): value is string[]; +>isArrayOfStrings : Symbol(isArrayOfStrings, Decl(assertionTypePredicates1.ts, 0, 59)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 1, 34)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 1, 34)) + +const assert: (value: unknown) => asserts value = value => {} +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 3, 15)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 3, 15)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 3, 49)) + +declare function assertIsString(value: unknown): asserts value is string; +>assertIsString : Symbol(assertIsString, Decl(assertionTypePredicates1.ts, 3, 61)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 5, 32)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 5, 32)) + +declare function assertIsArrayOfStrings(value: unknown): asserts value is string[]; +>assertIsArrayOfStrings : Symbol(assertIsArrayOfStrings, Decl(assertionTypePredicates1.ts, 5, 73)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 6, 40)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 6, 40)) + +declare function assertDefined(value: T): asserts value is NonNullable; +>assertDefined : Symbol(assertDefined, Decl(assertionTypePredicates1.ts, 6, 83)) +>T : Symbol(T, Decl(assertionTypePredicates1.ts, 7, 31)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 7, 34)) +>T : Symbol(T, Decl(assertionTypePredicates1.ts, 7, 31)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 7, 34)) +>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(assertionTypePredicates1.ts, 7, 31)) + +function f01(x: unknown) { +>f01 : Symbol(f01, Decl(assertionTypePredicates1.ts, 7, 77)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + + if (!!true) { + assert(typeof x === "string"); +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assert(x instanceof Error); +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + x.message; +>x.message : Symbol(Error.message, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) +>message : Symbol(Error.message, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assert(typeof x === "boolean" || typeof x === "number"); +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + + x.toLocaleString; +>x.toLocaleString : Symbol(toLocaleString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) +>toLocaleString : Symbol(toLocaleString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assert(isArrayOfStrings(x)); +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5)) +>isArrayOfStrings : Symbol(isArrayOfStrings, Decl(assertionTypePredicates1.ts, 0, 59)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + + x[0].length; +>x[0].length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assertIsArrayOfStrings(x); +>assertIsArrayOfStrings : Symbol(assertIsArrayOfStrings, Decl(assertionTypePredicates1.ts, 5, 73)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + + x[0].length; +>x[0].length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assert(x === undefined || typeof x === "string"); +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) +>undefined : Symbol(undefined) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + + x; // string | undefined +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + + assertDefined(x); +>assertDefined : Symbol(assertDefined, Decl(assertionTypePredicates1.ts, 6, 83)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + + x; // string +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 9, 13)) + } +} + +function f02(x: string | undefined) { +>f02 : Symbol(f02, Decl(assertionTypePredicates1.ts, 36, 1)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13)) + + if (!!true) { + assert(x); +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assert(x !== undefined); +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 3, 5)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13)) +>undefined : Symbol(undefined) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assertDefined(x); +>assertDefined : Symbol(assertDefined, Decl(assertionTypePredicates1.ts, 6, 83)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 38, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } +} + +function f03(x: string | undefined, assert: (value: unknown) => asserts value) { +>f03 : Symbol(f03, Decl(assertionTypePredicates1.ts, 51, 1)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 53, 13)) +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 53, 35)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 53, 45)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 53, 45)) + + assert(x); +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 53, 35)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 53, 13)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 53, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +} + +namespace Debug { +>Debug : Symbol(Debug, Decl(assertionTypePredicates1.ts, 56, 1)) + + export declare function assert(value: unknown, message?: string): asserts value; +>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 58, 17)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 59, 35)) +>message : Symbol(message, Decl(assertionTypePredicates1.ts, 59, 50)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 59, 35)) + + export declare function assertDefined(value: T): asserts value is NonNullable; +>assertDefined : Symbol(assertDefined, Decl(assertionTypePredicates1.ts, 59, 84)) +>T : Symbol(T, Decl(assertionTypePredicates1.ts, 60, 42)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 60, 45)) +>T : Symbol(T, Decl(assertionTypePredicates1.ts, 60, 42)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 60, 45)) +>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(assertionTypePredicates1.ts, 60, 42)) +} + +function f10(x: string | undefined) { +>f10 : Symbol(f10, Decl(assertionTypePredicates1.ts, 61, 1)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13)) + + if (!!true) { + Debug.assert(x); +>Debug.assert : Symbol(Debug.assert, Decl(assertionTypePredicates1.ts, 58, 17)) +>Debug : Symbol(Debug, Decl(assertionTypePredicates1.ts, 56, 1)) +>assert : Symbol(Debug.assert, Decl(assertionTypePredicates1.ts, 58, 17)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + Debug.assert(x !== undefined); +>Debug.assert : Symbol(Debug.assert, Decl(assertionTypePredicates1.ts, 58, 17)) +>Debug : Symbol(Debug, Decl(assertionTypePredicates1.ts, 56, 1)) +>assert : Symbol(Debug.assert, Decl(assertionTypePredicates1.ts, 58, 17)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13)) +>undefined : Symbol(undefined) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + Debug.assertDefined(x); +>Debug.assertDefined : Symbol(Debug.assertDefined, Decl(assertionTypePredicates1.ts, 59, 84)) +>Debug : Symbol(Debug, Decl(assertionTypePredicates1.ts, 56, 1)) +>assertDefined : Symbol(Debug.assertDefined, Decl(assertionTypePredicates1.ts, 59, 84)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 63, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } +} + +class Test { +>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) + + assert(value: unknown): asserts value { +>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 78, 12)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 79, 11)) +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 79, 11)) + + if (value) return; +>value : Symbol(value, Decl(assertionTypePredicates1.ts, 79, 11)) + + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } + isTest2(): this is Test2 { +>isTest2 : Symbol(Test.isTest2, Decl(assertionTypePredicates1.ts, 82, 5)) +>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1)) + + return this instanceof Test2; +>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) +>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1)) + } + assertIsTest2(): asserts this is Test2 { +>assertIsTest2 : Symbol(Test.assertIsTest2, Decl(assertionTypePredicates1.ts, 85, 5)) +>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1)) + + if (this instanceof Test2) return; +>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) +>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1)) + + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } + assertThis(): asserts this { +>assertThis : Symbol(Test.assertThis, Decl(assertionTypePredicates1.ts, 89, 5)) + + if (!this) return; +>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) + + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } + bar() { +>bar : Symbol(Test.bar, Decl(assertionTypePredicates1.ts, 93, 5)) + + this.assertThis(); +>this.assertThis : Symbol(Test.assertThis, Decl(assertionTypePredicates1.ts, 89, 5)) +>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) +>assertThis : Symbol(Test.assertThis, Decl(assertionTypePredicates1.ts, 89, 5)) + + this; +>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) + } + foo(x: unknown) { +>foo : Symbol(Test.foo, Decl(assertionTypePredicates1.ts, 97, 5)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 98, 8)) + + this.assert(typeof x === "string"); +>this.assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 78, 12)) +>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) +>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 78, 12)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 98, 8)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 98, 8)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + + if (this.isTest2()) { +>this.isTest2 : Symbol(Test.isTest2, Decl(assertionTypePredicates1.ts, 82, 5)) +>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) +>isTest2 : Symbol(Test.isTest2, Decl(assertionTypePredicates1.ts, 82, 5)) + + this.z; +>this.z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26)) +>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26)) + } + this.assertIsTest2(); +>this.assertIsTest2 : Symbol(Test.assertIsTest2, Decl(assertionTypePredicates1.ts, 85, 5)) +>this : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) +>assertIsTest2 : Symbol(Test.assertIsTest2, Decl(assertionTypePredicates1.ts, 85, 5)) + + this.z; +>this.z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26)) +>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26)) + } +} + +class Test2 extends Test { +>Test2 : Symbol(Test2, Decl(assertionTypePredicates1.ts, 107, 1)) +>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 76, 1)) + + z = 0; +>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 109, 26)) +} + +// Invalid constructs + +declare let Q1: new (x: unknown) => x is string; +>Q1 : Symbol(Q1, Decl(assertionTypePredicates1.ts, 115, 11)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 115, 21)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 115, 21)) + +declare let Q2: new (x: boolean) => asserts x; +>Q2 : Symbol(Q2, Decl(assertionTypePredicates1.ts, 116, 11)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 116, 21)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 116, 21)) + +declare let Q3: new (x: unknown) => asserts x is string; +>Q3 : Symbol(Q3, Decl(assertionTypePredicates1.ts, 117, 11)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 117, 21)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 117, 21)) + +declare class Wat { +>Wat : Symbol(Wat, Decl(assertionTypePredicates1.ts, 117, 56)) + + get p1(): this is string; +>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 119, 19), Decl(assertionTypePredicates1.ts, 120, 29)) + + set p1(x: this is string); +>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 119, 19), Decl(assertionTypePredicates1.ts, 120, 29)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 121, 11)) + + get p2(): asserts this is string; +>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 121, 30), Decl(assertionTypePredicates1.ts, 122, 37)) + + set p2(x: asserts this is string); +>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 121, 30), Decl(assertionTypePredicates1.ts, 122, 37)) +>x : Symbol(x, Decl(assertionTypePredicates1.ts, 123, 11)) +} + diff --git a/tests/baselines/reference/assertionTypePredicates1.types b/tests/baselines/reference/assertionTypePredicates1.types new file mode 100644 index 00000000000..f72ec641013 --- /dev/null +++ b/tests/baselines/reference/assertionTypePredicates1.types @@ -0,0 +1,438 @@ +=== tests/cases/conformance/controlFlow/assertionTypePredicates1.ts === +declare function isString(value: unknown): value is string; +>isString : (value: unknown) => value is string +>value : unknown + +declare function isArrayOfStrings(value: unknown): value is string[]; +>isArrayOfStrings : (value: unknown) => value is string[] +>value : unknown + +const assert: (value: unknown) => asserts value = value => {} +>assert : (value: unknown) => asserts value +>value : unknown +>value => {} : (value: unknown) => void +>value : unknown + +declare function assertIsString(value: unknown): asserts value is string; +>assertIsString : (value: unknown) => asserts value is string +>value : unknown + +declare function assertIsArrayOfStrings(value: unknown): asserts value is string[]; +>assertIsArrayOfStrings : (value: unknown) => asserts value is string[] +>value : unknown + +declare function assertDefined(value: T): asserts value is NonNullable; +>assertDefined : (value: T) => asserts value is NonNullable +>value : T + +function f01(x: unknown) { +>f01 : (x: unknown) => void +>x : unknown + + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(typeof x === "string"); +>assert(typeof x === "string") : void +>assert : (value: unknown) => asserts value +>typeof x === "string" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"string" : "string" + + x.length; +>x.length : number +>x : string +>length : number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(x instanceof Error); +>assert(x instanceof Error) : void +>assert : (value: unknown) => asserts value +>x instanceof Error : boolean +>x : unknown +>Error : ErrorConstructor + + x.message; +>x.message : string +>x : Error +>message : string + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(typeof x === "boolean" || typeof x === "number"); +>assert(typeof x === "boolean" || typeof x === "number") : void +>assert : (value: unknown) => asserts value +>typeof x === "boolean" || typeof x === "number" : boolean +>typeof x === "boolean" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"boolean" : "boolean" +>typeof x === "number" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"number" : "number" + + x.toLocaleString; +>x.toLocaleString : ((locales?: string | string[] | undefined, options?: Intl.NumberFormatOptions | undefined) => string) | (() => string) +>x : number | boolean +>toLocaleString : ((locales?: string | string[] | undefined, options?: Intl.NumberFormatOptions | undefined) => string) | (() => string) + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(isArrayOfStrings(x)); +>assert(isArrayOfStrings(x)) : void +>assert : (value: unknown) => asserts value +>isArrayOfStrings(x) : boolean +>isArrayOfStrings : (value: unknown) => value is string[] +>x : unknown + + x[0].length; +>x[0].length : number +>x[0] : string +>x : string[] +>0 : 0 +>length : number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assertIsArrayOfStrings(x); +>assertIsArrayOfStrings(x) : void +>assertIsArrayOfStrings : (value: unknown) => asserts value is string[] +>x : unknown + + x[0].length; +>x[0].length : number +>x[0] : string +>x : string[] +>0 : 0 +>length : number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(x === undefined || typeof x === "string"); +>assert(x === undefined || typeof x === "string") : void +>assert : (value: unknown) => asserts value +>x === undefined || typeof x === "string" : boolean +>x === undefined : boolean +>x : unknown +>undefined : undefined +>typeof x === "string" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"string" : "string" + + x; // string | undefined +>x : string | undefined + + assertDefined(x); +>assertDefined(x) : void +>assertDefined : (value: T) => asserts value is NonNullable +>x : string | undefined + + x; // string +>x : string + } +} + +function f02(x: string | undefined) { +>f02 : (x: string | undefined) => void +>x : string | undefined + + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(x); +>assert(x) : void +>assert : (value: unknown) => asserts value +>x : string | undefined + + x.length; +>x.length : number +>x : string +>length : number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assert(x !== undefined); +>assert(x !== undefined) : void +>assert : (value: unknown) => asserts value +>x !== undefined : boolean +>x : string | undefined +>undefined : undefined + + x.length; +>x.length : number +>x : string +>length : number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + assertDefined(x); +>assertDefined(x) : void +>assertDefined : (value: T) => asserts value is NonNullable +>x : string | undefined + + x.length; +>x.length : number +>x : string +>length : number + } +} + +function f03(x: string | undefined, assert: (value: unknown) => asserts value) { +>f03 : (x: string | undefined, assert: (value: unknown) => asserts value) => void +>x : string | undefined +>assert : (value: unknown) => asserts value +>value : unknown + + assert(x); +>assert(x) : void +>assert : (value: unknown) => asserts value +>x : string | undefined + + x.length; +>x.length : number +>x : string +>length : number +} + +namespace Debug { +>Debug : typeof Debug + + export declare function assert(value: unknown, message?: string): asserts value; +>assert : (value: unknown, message?: string | undefined) => asserts value +>value : unknown +>message : string | undefined + + export declare function assertDefined(value: T): asserts value is NonNullable; +>assertDefined : (value: T) => asserts value is NonNullable +>value : T +} + +function f10(x: string | undefined) { +>f10 : (x: string | undefined) => void +>x : string | undefined + + if (!!true) { +>!!true : true +>!true : false +>true : true + + Debug.assert(x); +>Debug.assert(x) : void +>Debug.assert : (value: unknown, message?: string | undefined) => asserts value +>Debug : typeof Debug +>assert : (value: unknown, message?: string | undefined) => asserts value +>x : string | undefined + + x.length; +>x.length : number +>x : string +>length : number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + Debug.assert(x !== undefined); +>Debug.assert(x !== undefined) : void +>Debug.assert : (value: unknown, message?: string | undefined) => asserts value +>Debug : typeof Debug +>assert : (value: unknown, message?: string | undefined) => asserts value +>x !== undefined : boolean +>x : string | undefined +>undefined : undefined + + x.length; +>x.length : number +>x : string +>length : number + } + if (!!true) { +>!!true : true +>!true : false +>true : true + + Debug.assertDefined(x); +>Debug.assertDefined(x) : void +>Debug.assertDefined : (value: T) => asserts value is NonNullable +>Debug : typeof Debug +>assertDefined : (value: T) => asserts value is NonNullable +>x : string | undefined + + x.length; +>x.length : number +>x : string +>length : number + } +} + +class Test { +>Test : Test + + assert(value: unknown): asserts value { +>assert : (value: unknown) => asserts value +>value : unknown + + if (value) return; +>value : unknown + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor + } + isTest2(): this is Test2 { +>isTest2 : () => this is Test2 + + return this instanceof Test2; +>this instanceof Test2 : boolean +>this : this +>Test2 : typeof Test2 + } + assertIsTest2(): asserts this is Test2 { +>assertIsTest2 : () => asserts this is Test2 + + if (this instanceof Test2) return; +>this instanceof Test2 : boolean +>this : this +>Test2 : typeof Test2 + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor + } + assertThis(): asserts this { +>assertThis : () => asserts this + + if (!this) return; +>!this : false +>this : this + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor + } + bar() { +>bar : () => void + + this.assertThis(); +>this.assertThis() : void +>this.assertThis : () => asserts this +>this : this +>assertThis : () => asserts this + + this; +>this : this + } + foo(x: unknown) { +>foo : (x: unknown) => void +>x : unknown + + this.assert(typeof x === "string"); +>this.assert(typeof x === "string") : void +>this.assert : (value: unknown) => asserts value +>this : this +>assert : (value: unknown) => asserts value +>typeof x === "string" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"string" : "string" + + x.length; +>x.length : number +>x : string +>length : number + + if (this.isTest2()) { +>this.isTest2() : boolean +>this.isTest2 : () => this is Test2 +>this : this +>isTest2 : () => this is Test2 + + this.z; +>this.z : number +>this : this & Test2 +>z : number + } + this.assertIsTest2(); +>this.assertIsTest2() : void +>this.assertIsTest2 : () => asserts this is Test2 +>this : this +>assertIsTest2 : () => asserts this is Test2 + + this.z; +>this.z : number +>this : this & Test2 +>z : number + } +} + +class Test2 extends Test { +>Test2 : Test2 +>Test : Test + + z = 0; +>z : number +>0 : 0 +} + +// Invalid constructs + +declare let Q1: new (x: unknown) => x is string; +>Q1 : new (x: unknown) => x is string +>x : unknown + +declare let Q2: new (x: boolean) => asserts x; +>Q2 : new (x: boolean) => asserts x +>x : boolean + +declare let Q3: new (x: unknown) => asserts x is string; +>Q3 : new (x: unknown) => asserts x is string +>x : unknown + +declare class Wat { +>Wat : Wat + + get p1(): this is string; +>p1 : boolean + + set p1(x: this is string); +>p1 : boolean +>x : boolean + + get p2(): asserts this is string; +>p2 : void + + set p2(x: asserts this is string); +>p2 : void +>x : void +} + diff --git a/tests/baselines/reference/assertionsAndNonReturningFunctions.errors.txt b/tests/baselines/reference/assertionsAndNonReturningFunctions.errors.txt new file mode 100644 index 00000000000..e1648d7643d --- /dev/null +++ b/tests/baselines/reference/assertionsAndNonReturningFunctions.errors.txt @@ -0,0 +1,69 @@ +tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js(46,9): error TS7027: Unreachable code detected. +tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js(58,5): error TS7027: Unreachable code detected. + + +==== tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js (2 errors) ==== + /** @typedef {(check: boolean) => asserts check} AssertFunc */ + + /** @type {AssertFunc} */ + const assert = check => { + if (!check) throw new Error(); + } + + /** @type {(x: unknown) => asserts x is string } */ + function assertIsString(x) { + if (!(typeof x === "string")) throw new Error(); + } + + /** + * @param {boolean} check + * @returns {asserts check} + */ + function assert2(check) { + if (!check) throw new Error(); + } + + /** + * @returns {never} + */ + function fail() { + throw new Error(); + } + + /** + * @param {*} x + */ + function f1(x) { + if (!!true) { + assert(typeof x === "string"); + x.length; + } + if (!!true) { + assert2(typeof x === "string"); + x.length; + } + if (!!true) { + assertIsString(x); + x.length; + } + if (!!true) { + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + } + + /** + * @param {boolean} b + */ + function f2(b) { + switch (b) { + case true: return 1; + case false: return 0; + } + b; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + \ No newline at end of file diff --git a/tests/baselines/reference/assertionsAndNonReturningFunctions.symbols b/tests/baselines/reference/assertionsAndNonReturningFunctions.symbols new file mode 100644 index 00000000000..88931cffbd8 --- /dev/null +++ b/tests/baselines/reference/assertionsAndNonReturningFunctions.symbols @@ -0,0 +1,109 @@ +=== tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js === +/** @typedef {(check: boolean) => asserts check} AssertFunc */ + +/** @type {AssertFunc} */ +const assert = check => { +>assert : Symbol(assert, Decl(assertionsAndNonReturningFunctions.js, 3, 5)) +>check : Symbol(check, Decl(assertionsAndNonReturningFunctions.js, 3, 14)) + + if (!check) throw new Error(); +>check : Symbol(check, Decl(assertionsAndNonReturningFunctions.js, 3, 14)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +/** @type {(x: unknown) => asserts x is string } */ +function assertIsString(x) { +>assertIsString : Symbol(assertIsString, Decl(assertionsAndNonReturningFunctions.js, 5, 1)) +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 8, 24)) + + if (!(typeof x === "string")) throw new Error(); +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 8, 24)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +/** + * @param {boolean} check + * @returns {asserts check} +*/ +function assert2(check) { +>assert2 : Symbol(assert2, Decl(assertionsAndNonReturningFunctions.js, 10, 1)) +>check : Symbol(check, Decl(assertionsAndNonReturningFunctions.js, 16, 17)) + + if (!check) throw new Error(); +>check : Symbol(check, Decl(assertionsAndNonReturningFunctions.js, 16, 17)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +/** + * @returns {never} + */ +function fail() { +>fail : Symbol(fail, Decl(assertionsAndNonReturningFunctions.js, 18, 1)) + + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +/** + * @param {*} x + */ +function f1(x) { +>f1 : Symbol(f1, Decl(assertionsAndNonReturningFunctions.js, 25, 1)) +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12)) + + if (!!true) { + assert(typeof x === "string"); +>assert : Symbol(assert, Decl(assertionsAndNonReturningFunctions.js, 3, 5)) +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assert2(typeof x === "string"); +>assert2 : Symbol(assert2, Decl(assertionsAndNonReturningFunctions.js, 10, 1)) +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + assertIsString(x); +>assertIsString : Symbol(assertIsString, Decl(assertionsAndNonReturningFunctions.js, 5, 1)) +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12)) + + x.length; +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + if (!!true) { + fail(); +>fail : Symbol(fail, Decl(assertionsAndNonReturningFunctions.js, 18, 1)) + + x; // Unreachable +>x : Symbol(x, Decl(assertionsAndNonReturningFunctions.js, 30, 12)) + } +} + +/** + * @param {boolean} b + */ +function f2(b) { +>f2 : Symbol(f2, Decl(assertionsAndNonReturningFunctions.js, 47, 1)) +>b : Symbol(b, Decl(assertionsAndNonReturningFunctions.js, 52, 12)) + + switch (b) { +>b : Symbol(b, Decl(assertionsAndNonReturningFunctions.js, 52, 12)) + + case true: return 1; + case false: return 0; + } + b; // Unreachable +>b : Symbol(b, Decl(assertionsAndNonReturningFunctions.js, 52, 12)) +} + diff --git a/tests/baselines/reference/assertionsAndNonReturningFunctions.types b/tests/baselines/reference/assertionsAndNonReturningFunctions.types new file mode 100644 index 00000000000..32100b6c3d2 --- /dev/null +++ b/tests/baselines/reference/assertionsAndNonReturningFunctions.types @@ -0,0 +1,152 @@ +=== tests/cases/conformance/jsdoc/assertionsAndNonReturningFunctions.js === +/** @typedef {(check: boolean) => asserts check} AssertFunc */ + +/** @type {AssertFunc} */ +const assert = check => { +>assert : (check: boolean) => asserts check +>check => { if (!check) throw new Error();} : (check: boolean) => asserts check +>check : boolean + + if (!check) throw new Error(); +>!check : boolean +>check : boolean +>new Error() : Error +>Error : ErrorConstructor +} + +/** @type {(x: unknown) => asserts x is string } */ +function assertIsString(x) { +>assertIsString : (x: unknown) => asserts x is string +>x : unknown + + if (!(typeof x === "string")) throw new Error(); +>!(typeof x === "string") : boolean +>(typeof x === "string") : boolean +>typeof x === "string" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"string" : "string" +>new Error() : Error +>Error : ErrorConstructor +} + +/** + * @param {boolean} check + * @returns {asserts check} +*/ +function assert2(check) { +>assert2 : (check: boolean) => asserts check +>check : boolean + + if (!check) throw new Error(); +>!check : boolean +>check : boolean +>new Error() : Error +>Error : ErrorConstructor +} + +/** + * @returns {never} + */ +function fail() { +>fail : () => never + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} + +/** + * @param {*} x + */ +function f1(x) { +>f1 : (x: any) => void +>x : any + + if (!!true) { +>!!true : boolean +>!true : boolean +>true : true + + assert(typeof x === "string"); +>assert(typeof x === "string") : void +>assert : (check: boolean) => asserts check +>typeof x === "string" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : any +>"string" : "string" + + x.length; +>x.length : number +>x : string +>length : number + } + if (!!true) { +>!!true : boolean +>!true : boolean +>true : true + + assert2(typeof x === "string"); +>assert2(typeof x === "string") : void +>assert2 : (check: boolean) => asserts check +>typeof x === "string" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : any +>"string" : "string" + + x.length; +>x.length : number +>x : string +>length : number + } + if (!!true) { +>!!true : boolean +>!true : boolean +>true : true + + assertIsString(x); +>assertIsString(x) : void +>assertIsString : (x: unknown) => asserts x is string +>x : any + + x.length; +>x.length : number +>x : string +>length : number + } + if (!!true) { +>!!true : boolean +>!true : boolean +>true : true + + fail(); +>fail() : never +>fail : () => never + + x; // Unreachable +>x : any + } +} + +/** + * @param {boolean} b + */ +function f2(b) { +>f2 : (b: boolean) => 1 | 0 +>b : boolean + + switch (b) { +>b : boolean + + case true: return 1; +>true : true +>1 : 1 + + case false: return 0; +>false : false +>0 : 0 + } + b; // Unreachable +>b : never +} + diff --git a/tests/baselines/reference/exhaustiveSwitchImplicitReturn.errors.txt b/tests/baselines/reference/exhaustiveSwitchImplicitReturn.errors.txt index 43b5467f0d2..89daa42c268 100644 --- a/tests/baselines/reference/exhaustiveSwitchImplicitReturn.errors.txt +++ b/tests/baselines/reference/exhaustiveSwitchImplicitReturn.errors.txt @@ -44,4 +44,18 @@ tests/cases/compiler/exhaustiveSwitchImplicitReturn.ts(35,32): error TS7030: Not return 1; } } + + function foo6(bar: "a", a: boolean, b: boolean): number { + if (a) { + switch (bar) { + case "a": return 1; + } + } + else { + switch (b) { + case true: return -1; + case false: return 0; + } + } + } \ No newline at end of file diff --git a/tests/baselines/reference/exhaustiveSwitchImplicitReturn.js b/tests/baselines/reference/exhaustiveSwitchImplicitReturn.js index 5f8bf348c5f..9877f251993 100644 --- a/tests/baselines/reference/exhaustiveSwitchImplicitReturn.js +++ b/tests/baselines/reference/exhaustiveSwitchImplicitReturn.js @@ -39,6 +39,20 @@ function foo5(bar: "a" | "b"): number { return 1; } } + +function foo6(bar: "a", a: boolean, b: boolean): number { + if (a) { + switch (bar) { + case "a": return 1; + } + } + else { + switch (b) { + case true: return -1; + case false: return 0; + } + } +} //// [exhaustiveSwitchImplicitReturn.js] @@ -75,3 +89,16 @@ function foo5(bar) { return 1; } } +function foo6(bar, a, b) { + if (a) { + switch (bar) { + case "a": return 1; + } + } + else { + switch (b) { + case true: return -1; + case false: return 0; + } + } +} diff --git a/tests/baselines/reference/exhaustiveSwitchImplicitReturn.symbols b/tests/baselines/reference/exhaustiveSwitchImplicitReturn.symbols index d93a5228362..dcad190a9b3 100644 --- a/tests/baselines/reference/exhaustiveSwitchImplicitReturn.symbols +++ b/tests/baselines/reference/exhaustiveSwitchImplicitReturn.symbols @@ -69,3 +69,28 @@ function foo5(bar: "a" | "b"): number { } } +function foo6(bar: "a", a: boolean, b: boolean): number { +>foo6 : Symbol(foo6, Decl(exhaustiveSwitchImplicitReturn.ts, 39, 1)) +>bar : Symbol(bar, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 14)) +>a : Symbol(a, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 23)) +>b : Symbol(b, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 35)) + + if (a) { +>a : Symbol(a, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 23)) + + switch (bar) { +>bar : Symbol(bar, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 14)) + + case "a": return 1; + } + } + else { + switch (b) { +>b : Symbol(b, Decl(exhaustiveSwitchImplicitReturn.ts, 41, 35)) + + case true: return -1; + case false: return 0; + } + } +} + diff --git a/tests/baselines/reference/exhaustiveSwitchImplicitReturn.types b/tests/baselines/reference/exhaustiveSwitchImplicitReturn.types index c868aa99b8f..c72b3b24477 100644 --- a/tests/baselines/reference/exhaustiveSwitchImplicitReturn.types +++ b/tests/baselines/reference/exhaustiveSwitchImplicitReturn.types @@ -85,3 +85,36 @@ function foo5(bar: "a" | "b"): number { } } +function foo6(bar: "a", a: boolean, b: boolean): number { +>foo6 : (bar: "a", a: boolean, b: boolean) => number +>bar : "a" +>a : boolean +>b : boolean + + if (a) { +>a : boolean + + switch (bar) { +>bar : "a" + + case "a": return 1; +>"a" : "a" +>1 : 1 + } + } + else { + switch (b) { +>b : boolean + + case true: return -1; +>true : true +>-1 : -1 +>1 : 1 + + case false: return 0; +>false : false +>0 : 0 + } + } +} + diff --git a/tests/baselines/reference/exhaustiveSwitchStatements1.errors.txt b/tests/baselines/reference/exhaustiveSwitchStatements1.errors.txt new file mode 100644 index 00000000000..4a54518413d --- /dev/null +++ b/tests/baselines/reference/exhaustiveSwitchStatements1.errors.txt @@ -0,0 +1,202 @@ +tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(7,9): error TS7027: Unreachable code detected. + + +==== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts (1 errors) ==== + function f1(x: 1 | 2): string { + if (!!true) { + switch (x) { + case 1: return 'a'; + case 2: return 'b'; + } + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + else { + throw 0; + } + } + + function f2(x: 1 | 2) { + let z: number; + switch (x) { + case 1: z = 10; break; + case 2: z = 20; break; + } + z; // Definitely assigned + } + + function f3(x: 1 | 2) { + switch (x) { + case 1: return 10; + case 2: return 20; + // Default considered reachable to allow defensive coding + default: throw new Error("Bad input"); + } + } + + // Repro from #11572 + + enum E { A, B } + + function f(e: E): number { + switch (e) { + case E.A: return 0 + case E.B: return 1 + } + } + + function g(e: E): number { + if (!true) + return -1 + else + switch (e) { + case E.A: return 0 + case E.B: return 1 + } + } + + // Repro from #12668 + + interface Square { kind: "square"; size: number; } + + interface Rectangle { kind: "rectangle"; width: number; height: number; } + + interface Circle { kind: "circle"; radius: number; } + + interface Triangle { kind: "triangle"; side: number; } + + type Shape = Square | Rectangle | Circle | Triangle; + + function area(s: Shape): number { + let area; + switch (s.kind) { + case "square": area = s.size * s.size; break; + case "rectangle": area = s.width * s.height; break; + case "circle": area = Math.PI * s.radius * s.radius; break; + case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break; + } + return area; + } + + function areaWrapped(s: Shape): number { + let area; + area = (() => { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; + } + })(); + return area; + } + + // Repro from #13241 + + enum MyEnum { + A, + B + } + + function thisGivesError(e: MyEnum): string { + let s: string; + switch (e) { + case MyEnum.A: s = "it was A"; break; + case MyEnum.B: s = "it was B"; break; + } + return s; + } + + function good1(e: MyEnum): string { + let s: string; + switch (e) { + case MyEnum.A: s = "it was A"; break; + case MyEnum.B: s = "it was B"; break; + default: s = "it was something else"; break; + } + return s; + } + + function good2(e: MyEnum): string { + switch (e) { + case MyEnum.A: return "it was A"; + case MyEnum.B: return "it was B"; + } + } + + // Repro from #18362 + + enum Level { + One, + Two, + } + + const doSomethingWithLevel = (level: Level) => { + let next: Level; + switch (level) { + case Level.One: + next = Level.Two; + break; + case Level.Two: + next = Level.One; + break; + } + return next; + }; + + // Repro from #20409 + + interface Square2 { + kind: "square"; + size: number; + } + + interface Circle2 { + kind: "circle"; + radius: number; + } + + type Shape2 = Square2 | Circle2; + + function withDefault(s1: Shape2, s2: Shape2): string { + switch (s1.kind) { + case "square": + return "1"; + case "circle": + switch (s2.kind) { + case "square": + return "2"; + case "circle": + return "3"; + default: + return "never"; + } + } + } + + function withoutDefault(s1: Shape2, s2: Shape2): string { + switch (s1.kind) { + case "square": + return "1"; + case "circle": + switch (s2.kind) { + case "square": + return "2"; + case "circle": + return "3"; + } + } + } + + // Repro from #20823 + + function test4(value: 1 | 2) { + let x: string; + switch (value) { + case 1: x = "one"; break; + case 2: x = "two"; break; + } + return x; + } + \ No newline at end of file diff --git a/tests/baselines/reference/exhaustiveSwitchStatements1.js b/tests/baselines/reference/exhaustiveSwitchStatements1.js new file mode 100644 index 00000000000..a39db3b8101 --- /dev/null +++ b/tests/baselines/reference/exhaustiveSwitchStatements1.js @@ -0,0 +1,437 @@ +//// [exhaustiveSwitchStatements1.ts] +function f1(x: 1 | 2): string { + if (!!true) { + switch (x) { + case 1: return 'a'; + case 2: return 'b'; + } + x; // Unreachable + } + else { + throw 0; + } +} + +function f2(x: 1 | 2) { + let z: number; + switch (x) { + case 1: z = 10; break; + case 2: z = 20; break; + } + z; // Definitely assigned +} + +function f3(x: 1 | 2) { + switch (x) { + case 1: return 10; + case 2: return 20; + // Default considered reachable to allow defensive coding + default: throw new Error("Bad input"); + } +} + +// Repro from #11572 + +enum E { A, B } + +function f(e: E): number { + switch (e) { + case E.A: return 0 + case E.B: return 1 + } +} + +function g(e: E): number { + if (!true) + return -1 + else + switch (e) { + case E.A: return 0 + case E.B: return 1 + } +} + +// Repro from #12668 + +interface Square { kind: "square"; size: number; } + +interface Rectangle { kind: "rectangle"; width: number; height: number; } + +interface Circle { kind: "circle"; radius: number; } + +interface Triangle { kind: "triangle"; side: number; } + +type Shape = Square | Rectangle | Circle | Triangle; + +function area(s: Shape): number { + let area; + switch (s.kind) { + case "square": area = s.size * s.size; break; + case "rectangle": area = s.width * s.height; break; + case "circle": area = Math.PI * s.radius * s.radius; break; + case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break; + } + return area; +} + +function areaWrapped(s: Shape): number { + let area; + area = (() => { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; + } + })(); + return area; +} + +// Repro from #13241 + +enum MyEnum { + A, + B +} + +function thisGivesError(e: MyEnum): string { + let s: string; + switch (e) { + case MyEnum.A: s = "it was A"; break; + case MyEnum.B: s = "it was B"; break; + } + return s; +} + +function good1(e: MyEnum): string { + let s: string; + switch (e) { + case MyEnum.A: s = "it was A"; break; + case MyEnum.B: s = "it was B"; break; + default: s = "it was something else"; break; + } + return s; +} + +function good2(e: MyEnum): string { + switch (e) { + case MyEnum.A: return "it was A"; + case MyEnum.B: return "it was B"; + } +} + +// Repro from #18362 + +enum Level { + One, + Two, +} + +const doSomethingWithLevel = (level: Level) => { + let next: Level; + switch (level) { + case Level.One: + next = Level.Two; + break; + case Level.Two: + next = Level.One; + break; + } + return next; +}; + +// Repro from #20409 + +interface Square2 { + kind: "square"; + size: number; +} + +interface Circle2 { + kind: "circle"; + radius: number; +} + +type Shape2 = Square2 | Circle2; + +function withDefault(s1: Shape2, s2: Shape2): string { + switch (s1.kind) { + case "square": + return "1"; + case "circle": + switch (s2.kind) { + case "square": + return "2"; + case "circle": + return "3"; + default: + return "never"; + } + } +} + +function withoutDefault(s1: Shape2, s2: Shape2): string { + switch (s1.kind) { + case "square": + return "1"; + case "circle": + switch (s2.kind) { + case "square": + return "2"; + case "circle": + return "3"; + } + } +} + +// Repro from #20823 + +function test4(value: 1 | 2) { + let x: string; + switch (value) { + case 1: x = "one"; break; + case 2: x = "two"; break; + } + return x; +} + + +//// [exhaustiveSwitchStatements1.js] +"use strict"; +function f1(x) { + if (!!true) { + switch (x) { + case 1: return 'a'; + case 2: return 'b'; + } + x; // Unreachable + } + else { + throw 0; + } +} +function f2(x) { + var z; + switch (x) { + case 1: + z = 10; + break; + case 2: + z = 20; + break; + } + z; // Definitely assigned +} +function f3(x) { + switch (x) { + case 1: return 10; + case 2: return 20; + // Default considered reachable to allow defensive coding + default: throw new Error("Bad input"); + } +} +// Repro from #11572 +var E; +(function (E) { + E[E["A"] = 0] = "A"; + E[E["B"] = 1] = "B"; +})(E || (E = {})); +function f(e) { + switch (e) { + case E.A: return 0; + case E.B: return 1; + } +} +function g(e) { + if (!true) + return -1; + else + switch (e) { + case E.A: return 0; + case E.B: return 1; + } +} +function area(s) { + var area; + switch (s.kind) { + case "square": + area = s.size * s.size; + break; + case "rectangle": + area = s.width * s.height; + break; + case "circle": + area = Math.PI * s.radius * s.radius; + break; + case "triangle": + area = Math.sqrt(3) / 4 * s.side * s.side; + break; + } + return area; +} +function areaWrapped(s) { + var area; + area = (function () { + switch (s.kind) { + case "square": return s.size * s.size; + case "rectangle": return s.width * s.height; + case "circle": return Math.PI * s.radius * s.radius; + case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; + } + })(); + return area; +} +// Repro from #13241 +var MyEnum; +(function (MyEnum) { + MyEnum[MyEnum["A"] = 0] = "A"; + MyEnum[MyEnum["B"] = 1] = "B"; +})(MyEnum || (MyEnum = {})); +function thisGivesError(e) { + var s; + switch (e) { + case MyEnum.A: + s = "it was A"; + break; + case MyEnum.B: + s = "it was B"; + break; + } + return s; +} +function good1(e) { + var s; + switch (e) { + case MyEnum.A: + s = "it was A"; + break; + case MyEnum.B: + s = "it was B"; + break; + default: + s = "it was something else"; + break; + } + return s; +} +function good2(e) { + switch (e) { + case MyEnum.A: return "it was A"; + case MyEnum.B: return "it was B"; + } +} +// Repro from #18362 +var Level; +(function (Level) { + Level[Level["One"] = 0] = "One"; + Level[Level["Two"] = 1] = "Two"; +})(Level || (Level = {})); +var doSomethingWithLevel = function (level) { + var next; + switch (level) { + case Level.One: + next = Level.Two; + break; + case Level.Two: + next = Level.One; + break; + } + return next; +}; +function withDefault(s1, s2) { + switch (s1.kind) { + case "square": + return "1"; + case "circle": + switch (s2.kind) { + case "square": + return "2"; + case "circle": + return "3"; + default: + return "never"; + } + } +} +function withoutDefault(s1, s2) { + switch (s1.kind) { + case "square": + return "1"; + case "circle": + switch (s2.kind) { + case "square": + return "2"; + case "circle": + return "3"; + } + } +} +// Repro from #20823 +function test4(value) { + var x; + switch (value) { + case 1: + x = "one"; + break; + case 2: + x = "two"; + break; + } + return x; +} + + +//// [exhaustiveSwitchStatements1.d.ts] +declare function f1(x: 1 | 2): string; +declare function f2(x: 1 | 2): void; +declare function f3(x: 1 | 2): 10 | 20; +declare enum E { + A = 0, + B = 1 +} +declare function f(e: E): number; +declare function g(e: E): number; +interface Square { + kind: "square"; + size: number; +} +interface Rectangle { + kind: "rectangle"; + width: number; + height: number; +} +interface Circle { + kind: "circle"; + radius: number; +} +interface Triangle { + kind: "triangle"; + side: number; +} +declare type Shape = Square | Rectangle | Circle | Triangle; +declare function area(s: Shape): number; +declare function areaWrapped(s: Shape): number; +declare enum MyEnum { + A = 0, + B = 1 +} +declare function thisGivesError(e: MyEnum): string; +declare function good1(e: MyEnum): string; +declare function good2(e: MyEnum): string; +declare enum Level { + One = 0, + Two = 1 +} +declare const doSomethingWithLevel: (level: Level) => Level; +interface Square2 { + kind: "square"; + size: number; +} +interface Circle2 { + kind: "circle"; + radius: number; +} +declare type Shape2 = Square2 | Circle2; +declare function withDefault(s1: Shape2, s2: Shape2): string; +declare function withoutDefault(s1: Shape2, s2: Shape2): string; +declare function test4(value: 1 | 2): string; diff --git a/tests/baselines/reference/exhaustiveSwitchStatements1.symbols b/tests/baselines/reference/exhaustiveSwitchStatements1.symbols new file mode 100644 index 00000000000..8beb3911883 --- /dev/null +++ b/tests/baselines/reference/exhaustiveSwitchStatements1.symbols @@ -0,0 +1,503 @@ +=== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts === +function f1(x: 1 | 2): string { +>f1 : Symbol(f1, Decl(exhaustiveSwitchStatements1.ts, 0, 0)) +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 0, 12)) + + if (!!true) { + switch (x) { +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 0, 12)) + + case 1: return 'a'; + case 2: return 'b'; + } + x; // Unreachable +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 0, 12)) + } + else { + throw 0; + } +} + +function f2(x: 1 | 2) { +>f2 : Symbol(f2, Decl(exhaustiveSwitchStatements1.ts, 11, 1)) +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 13, 12)) + + let z: number; +>z : Symbol(z, Decl(exhaustiveSwitchStatements1.ts, 14, 7)) + + switch (x) { +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 13, 12)) + + case 1: z = 10; break; +>z : Symbol(z, Decl(exhaustiveSwitchStatements1.ts, 14, 7)) + + case 2: z = 20; break; +>z : Symbol(z, Decl(exhaustiveSwitchStatements1.ts, 14, 7)) + } + z; // Definitely assigned +>z : Symbol(z, Decl(exhaustiveSwitchStatements1.ts, 14, 7)) +} + +function f3(x: 1 | 2) { +>f3 : Symbol(f3, Decl(exhaustiveSwitchStatements1.ts, 20, 1)) +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 22, 12)) + + switch (x) { +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 22, 12)) + + case 1: return 10; + case 2: return 20; + // Default considered reachable to allow defensive coding + default: throw new Error("Bad input"); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } +} + +// Repro from #11572 + +enum E { A, B } +>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1)) +>A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8)) +>B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11)) + +function f(e: E): number { +>f : Symbol(f, Decl(exhaustiveSwitchStatements1.ts, 33, 15)) +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 35, 11)) +>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1)) + + switch (e) { +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 35, 11)) + + case E.A: return 0 +>E.A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8)) +>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1)) +>A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8)) + + case E.B: return 1 +>E.B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11)) +>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1)) +>B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11)) + } +} + +function g(e: E): number { +>g : Symbol(g, Decl(exhaustiveSwitchStatements1.ts, 40, 1)) +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 42, 11)) +>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1)) + + if (!true) + return -1 + else + switch (e) { +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 42, 11)) + + case E.A: return 0 +>E.A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8)) +>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1)) +>A : Symbol(E.A, Decl(exhaustiveSwitchStatements1.ts, 33, 8)) + + case E.B: return 1 +>E.B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11)) +>E : Symbol(E, Decl(exhaustiveSwitchStatements1.ts, 29, 1)) +>B : Symbol(E.B, Decl(exhaustiveSwitchStatements1.ts, 33, 11)) + } +} + +// Repro from #12668 + +interface Square { kind: "square"; size: number; } +>Square : Symbol(Square, Decl(exhaustiveSwitchStatements1.ts, 50, 1)) +>kind : Symbol(Square.kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18)) +>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) + +interface Rectangle { kind: "rectangle"; width: number; height: number; } +>Rectangle : Symbol(Rectangle, Decl(exhaustiveSwitchStatements1.ts, 54, 50)) +>kind : Symbol(Rectangle.kind, Decl(exhaustiveSwitchStatements1.ts, 56, 21)) +>width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40)) +>height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55)) + +interface Circle { kind: "circle"; radius: number; } +>Circle : Symbol(Circle, Decl(exhaustiveSwitchStatements1.ts, 56, 73)) +>kind : Symbol(Circle.kind, Decl(exhaustiveSwitchStatements1.ts, 58, 18)) +>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) + +interface Triangle { kind: "triangle"; side: number; } +>Triangle : Symbol(Triangle, Decl(exhaustiveSwitchStatements1.ts, 58, 52)) +>kind : Symbol(Triangle.kind, Decl(exhaustiveSwitchStatements1.ts, 60, 20)) +>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) + +type Shape = Square | Rectangle | Circle | Triangle; +>Shape : Symbol(Shape, Decl(exhaustiveSwitchStatements1.ts, 60, 54)) +>Square : Symbol(Square, Decl(exhaustiveSwitchStatements1.ts, 50, 1)) +>Rectangle : Symbol(Rectangle, Decl(exhaustiveSwitchStatements1.ts, 54, 50)) +>Circle : Symbol(Circle, Decl(exhaustiveSwitchStatements1.ts, 56, 73)) +>Triangle : Symbol(Triangle, Decl(exhaustiveSwitchStatements1.ts, 58, 52)) + +function area(s: Shape): number { +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 62, 52)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>Shape : Symbol(Shape, Decl(exhaustiveSwitchStatements1.ts, 60, 54)) + + let area; +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7)) + + switch (s.kind) { +>s.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18), Decl(exhaustiveSwitchStatements1.ts, 56, 21), Decl(exhaustiveSwitchStatements1.ts, 58, 18), Decl(exhaustiveSwitchStatements1.ts, 60, 20)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18), Decl(exhaustiveSwitchStatements1.ts, 56, 21), Decl(exhaustiveSwitchStatements1.ts, 58, 18), Decl(exhaustiveSwitchStatements1.ts, 60, 20)) + + case "square": area = s.size * s.size; break; +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7)) +>s.size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) +>s.size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) + + case "rectangle": area = s.width * s.height; break; +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7)) +>s.width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40)) +>s.height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55)) + + case "circle": area = Math.PI * s.radius * s.radius; break; +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7)) +>Math.PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) +>s.radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) +>s.radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) + + case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break; +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7)) +>Math.sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --)) +>s.side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) +>s.side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 64, 14)) +>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) + } + return area; +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 65, 7)) +} + +function areaWrapped(s: Shape): number { +>areaWrapped : Symbol(areaWrapped, Decl(exhaustiveSwitchStatements1.ts, 73, 1)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>Shape : Symbol(Shape, Decl(exhaustiveSwitchStatements1.ts, 60, 54)) + + let area; +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 76, 7)) + + area = (() => { +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 76, 7)) + + switch (s.kind) { +>s.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18), Decl(exhaustiveSwitchStatements1.ts, 56, 21), Decl(exhaustiveSwitchStatements1.ts, 58, 18), Decl(exhaustiveSwitchStatements1.ts, 60, 20)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 54, 18), Decl(exhaustiveSwitchStatements1.ts, 56, 21), Decl(exhaustiveSwitchStatements1.ts, 58, 18), Decl(exhaustiveSwitchStatements1.ts, 60, 20)) + + case "square": return s.size * s.size; +>s.size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) +>s.size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>size : Symbol(Square.size, Decl(exhaustiveSwitchStatements1.ts, 54, 34)) + + case "rectangle": return s.width * s.height; +>s.width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>width : Symbol(Rectangle.width, Decl(exhaustiveSwitchStatements1.ts, 56, 40)) +>s.height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>height : Symbol(Rectangle.height, Decl(exhaustiveSwitchStatements1.ts, 56, 55)) + + case "circle": return Math.PI * s.radius * s.radius; +>Math.PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --)) +>s.radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) +>s.radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>radius : Symbol(Circle.radius, Decl(exhaustiveSwitchStatements1.ts, 58, 34)) + + case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; +>Math.sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --)) +>s.side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) +>s.side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 75, 21)) +>side : Symbol(Triangle.side, Decl(exhaustiveSwitchStatements1.ts, 60, 38)) + } + })(); + return area; +>area : Symbol(area, Decl(exhaustiveSwitchStatements1.ts, 76, 7)) +} + +// Repro from #13241 + +enum MyEnum { +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) + + A, +>A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13)) + + B +>B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3)) +} + +function thisGivesError(e: MyEnum): string { +>thisGivesError : Symbol(thisGivesError, Decl(exhaustiveSwitchStatements1.ts, 93, 1)) +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 95, 24)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) + + let s: string; +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 96, 4)) + + switch (e) { +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 95, 24)) + + case MyEnum.A: s = "it was A"; break; +>MyEnum.A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) +>A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 96, 4)) + + case MyEnum.B: s = "it was B"; break; +>MyEnum.B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) +>B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 96, 4)) + } + return s; +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 96, 4)) +} + +function good1(e: MyEnum): string { +>good1 : Symbol(good1, Decl(exhaustiveSwitchStatements1.ts, 102, 1)) +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 104, 15)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) + + let s: string; +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4)) + + switch (e) { +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 104, 15)) + + case MyEnum.A: s = "it was A"; break; +>MyEnum.A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) +>A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4)) + + case MyEnum.B: s = "it was B"; break; +>MyEnum.B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) +>B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3)) +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4)) + + default: s = "it was something else"; break; +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4)) + } + return s; +>s : Symbol(s, Decl(exhaustiveSwitchStatements1.ts, 105, 4)) +} + +function good2(e: MyEnum): string { +>good2 : Symbol(good2, Decl(exhaustiveSwitchStatements1.ts, 112, 1)) +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 114, 15)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) + + switch (e) { +>e : Symbol(e, Decl(exhaustiveSwitchStatements1.ts, 114, 15)) + + case MyEnum.A: return "it was A"; +>MyEnum.A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) +>A : Symbol(MyEnum.A, Decl(exhaustiveSwitchStatements1.ts, 90, 13)) + + case MyEnum.B: return "it was B"; +>MyEnum.B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3)) +>MyEnum : Symbol(MyEnum, Decl(exhaustiveSwitchStatements1.ts, 86, 1)) +>B : Symbol(MyEnum.B, Decl(exhaustiveSwitchStatements1.ts, 91, 3)) + } +} + +// Repro from #18362 + +enum Level { +>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1)) + + One, +>One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12)) + + Two, +>Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6)) +} + +const doSomethingWithLevel = (level: Level) => { +>doSomethingWithLevel : Symbol(doSomethingWithLevel, Decl(exhaustiveSwitchStatements1.ts, 128, 5)) +>level : Symbol(level, Decl(exhaustiveSwitchStatements1.ts, 128, 30)) +>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1)) + + let next: Level; +>next : Symbol(next, Decl(exhaustiveSwitchStatements1.ts, 129, 5)) +>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1)) + + switch (level) { +>level : Symbol(level, Decl(exhaustiveSwitchStatements1.ts, 128, 30)) + + case Level.One: +>Level.One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12)) +>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1)) +>One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12)) + + next = Level.Two; +>next : Symbol(next, Decl(exhaustiveSwitchStatements1.ts, 129, 5)) +>Level.Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6)) +>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1)) +>Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6)) + + break; + case Level.Two: +>Level.Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6)) +>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1)) +>Two : Symbol(Level.Two, Decl(exhaustiveSwitchStatements1.ts, 124, 6)) + + next = Level.One; +>next : Symbol(next, Decl(exhaustiveSwitchStatements1.ts, 129, 5)) +>Level.One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12)) +>Level : Symbol(Level, Decl(exhaustiveSwitchStatements1.ts, 119, 1)) +>One : Symbol(Level.One, Decl(exhaustiveSwitchStatements1.ts, 123, 12)) + + break; + } + return next; +>next : Symbol(next, Decl(exhaustiveSwitchStatements1.ts, 129, 5)) + +}; + +// Repro from #20409 + +interface Square2 { +>Square2 : Symbol(Square2, Decl(exhaustiveSwitchStatements1.ts, 139, 2)) + + kind: "square"; +>kind : Symbol(Square2.kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19)) + + size: number; +>size : Symbol(Square2.size, Decl(exhaustiveSwitchStatements1.ts, 144, 19)) +} + +interface Circle2 { +>Circle2 : Symbol(Circle2, Decl(exhaustiveSwitchStatements1.ts, 146, 1)) + + kind: "circle"; +>kind : Symbol(Circle2.kind, Decl(exhaustiveSwitchStatements1.ts, 148, 19)) + + radius: number; +>radius : Symbol(Circle2.radius, Decl(exhaustiveSwitchStatements1.ts, 149, 19)) +} + +type Shape2 = Square2 | Circle2; +>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1)) +>Square2 : Symbol(Square2, Decl(exhaustiveSwitchStatements1.ts, 139, 2)) +>Circle2 : Symbol(Circle2, Decl(exhaustiveSwitchStatements1.ts, 146, 1)) + +function withDefault(s1: Shape2, s2: Shape2): string { +>withDefault : Symbol(withDefault, Decl(exhaustiveSwitchStatements1.ts, 153, 32)) +>s1 : Symbol(s1, Decl(exhaustiveSwitchStatements1.ts, 155, 21)) +>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1)) +>s2 : Symbol(s2, Decl(exhaustiveSwitchStatements1.ts, 155, 32)) +>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1)) + + switch (s1.kind) { +>s1.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19)) +>s1 : Symbol(s1, Decl(exhaustiveSwitchStatements1.ts, 155, 21)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19)) + + case "square": + return "1"; + case "circle": + switch (s2.kind) { +>s2.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19)) +>s2 : Symbol(s2, Decl(exhaustiveSwitchStatements1.ts, 155, 32)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19)) + + case "square": + return "2"; + case "circle": + return "3"; + default: + return "never"; + } + } +} + +function withoutDefault(s1: Shape2, s2: Shape2): string { +>withoutDefault : Symbol(withoutDefault, Decl(exhaustiveSwitchStatements1.ts, 169, 1)) +>s1 : Symbol(s1, Decl(exhaustiveSwitchStatements1.ts, 171, 24)) +>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1)) +>s2 : Symbol(s2, Decl(exhaustiveSwitchStatements1.ts, 171, 35)) +>Shape2 : Symbol(Shape2, Decl(exhaustiveSwitchStatements1.ts, 151, 1)) + + switch (s1.kind) { +>s1.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19)) +>s1 : Symbol(s1, Decl(exhaustiveSwitchStatements1.ts, 171, 24)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19)) + + case "square": + return "1"; + case "circle": + switch (s2.kind) { +>s2.kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19)) +>s2 : Symbol(s2, Decl(exhaustiveSwitchStatements1.ts, 171, 35)) +>kind : Symbol(kind, Decl(exhaustiveSwitchStatements1.ts, 143, 19), Decl(exhaustiveSwitchStatements1.ts, 148, 19)) + + case "square": + return "2"; + case "circle": + return "3"; + } + } +} + +// Repro from #20823 + +function test4(value: 1 | 2) { +>test4 : Symbol(test4, Decl(exhaustiveSwitchStatements1.ts, 183, 1)) +>value : Symbol(value, Decl(exhaustiveSwitchStatements1.ts, 187, 15)) + + let x: string; +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 188, 7)) + + switch (value) { +>value : Symbol(value, Decl(exhaustiveSwitchStatements1.ts, 187, 15)) + + case 1: x = "one"; break; +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 188, 7)) + + case 2: x = "two"; break; +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 188, 7)) + } + return x; +>x : Symbol(x, Decl(exhaustiveSwitchStatements1.ts, 188, 7)) +} + diff --git a/tests/baselines/reference/exhaustiveSwitchStatements1.types b/tests/baselines/reference/exhaustiveSwitchStatements1.types new file mode 100644 index 00000000000..04a9bf531ce --- /dev/null +++ b/tests/baselines/reference/exhaustiveSwitchStatements1.types @@ -0,0 +1,595 @@ +=== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts === +function f1(x: 1 | 2): string { +>f1 : (x: 1 | 2) => string +>x : 1 | 2 + + if (!!true) { +>!!true : true +>!true : false +>true : true + + switch (x) { +>x : 1 | 2 + + case 1: return 'a'; +>1 : 1 +>'a' : "a" + + case 2: return 'b'; +>2 : 2 +>'b' : "b" + } + x; // Unreachable +>x : never + } + else { + throw 0; +>0 : 0 + } +} + +function f2(x: 1 | 2) { +>f2 : (x: 1 | 2) => void +>x : 1 | 2 + + let z: number; +>z : number + + switch (x) { +>x : 1 | 2 + + case 1: z = 10; break; +>1 : 1 +>z = 10 : 10 +>z : number +>10 : 10 + + case 2: z = 20; break; +>2 : 2 +>z = 20 : 20 +>z : number +>20 : 20 + } + z; // Definitely assigned +>z : number +} + +function f3(x: 1 | 2) { +>f3 : (x: 1 | 2) => 10 | 20 +>x : 1 | 2 + + switch (x) { +>x : 1 | 2 + + case 1: return 10; +>1 : 1 +>10 : 10 + + case 2: return 20; +>2 : 2 +>20 : 20 + + // Default considered reachable to allow defensive coding + default: throw new Error("Bad input"); +>new Error("Bad input") : Error +>Error : ErrorConstructor +>"Bad input" : "Bad input" + } +} + +// Repro from #11572 + +enum E { A, B } +>E : E +>A : E.A +>B : E.B + +function f(e: E): number { +>f : (e: E) => number +>e : E + + switch (e) { +>e : E + + case E.A: return 0 +>E.A : E.A +>E : typeof E +>A : E.A +>0 : 0 + + case E.B: return 1 +>E.B : E.B +>E : typeof E +>B : E.B +>1 : 1 + } +} + +function g(e: E): number { +>g : (e: E) => number +>e : E + + if (!true) +>!true : false +>true : true + + return -1 +>-1 : -1 +>1 : 1 + + else + switch (e) { +>e : E + + case E.A: return 0 +>E.A : E.A +>E : typeof E +>A : E.A +>0 : 0 + + case E.B: return 1 +>E.B : E.B +>E : typeof E +>B : E.B +>1 : 1 + } +} + +// Repro from #12668 + +interface Square { kind: "square"; size: number; } +>kind : "square" +>size : number + +interface Rectangle { kind: "rectangle"; width: number; height: number; } +>kind : "rectangle" +>width : number +>height : number + +interface Circle { kind: "circle"; radius: number; } +>kind : "circle" +>radius : number + +interface Triangle { kind: "triangle"; side: number; } +>kind : "triangle" +>side : number + +type Shape = Square | Rectangle | Circle | Triangle; +>Shape : Shape + +function area(s: Shape): number { +>area : (s: Shape) => number +>s : Shape + + let area; +>area : any + + switch (s.kind) { +>s.kind : "square" | "rectangle" | "circle" | "triangle" +>s : Shape +>kind : "square" | "rectangle" | "circle" | "triangle" + + case "square": area = s.size * s.size; break; +>"square" : "square" +>area = s.size * s.size : number +>area : any +>s.size * s.size : number +>s.size : number +>s : Square +>size : number +>s.size : number +>s : Square +>size : number + + case "rectangle": area = s.width * s.height; break; +>"rectangle" : "rectangle" +>area = s.width * s.height : number +>area : any +>s.width * s.height : number +>s.width : number +>s : Rectangle +>width : number +>s.height : number +>s : Rectangle +>height : number + + case "circle": area = Math.PI * s.radius * s.radius; break; +>"circle" : "circle" +>area = Math.PI * s.radius * s.radius : number +>area : any +>Math.PI * s.radius * s.radius : number +>Math.PI * s.radius : number +>Math.PI : number +>Math : Math +>PI : number +>s.radius : number +>s : Circle +>radius : number +>s.radius : number +>s : Circle +>radius : number + + case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break; +>"triangle" : "triangle" +>area = Math.sqrt(3) / 4 * s.side * s.side : number +>area : any +>Math.sqrt(3) / 4 * s.side * s.side : number +>Math.sqrt(3) / 4 * s.side : number +>Math.sqrt(3) / 4 : number +>Math.sqrt(3) : number +>Math.sqrt : (x: number) => number +>Math : Math +>sqrt : (x: number) => number +>3 : 3 +>4 : 4 +>s.side : number +>s : Triangle +>side : number +>s.side : number +>s : Triangle +>side : number + } + return area; +>area : number +} + +function areaWrapped(s: Shape): number { +>areaWrapped : (s: Shape) => number +>s : Shape + + let area; +>area : any + + area = (() => { +>area = (() => { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; } })() : number +>area : any +>(() => { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; } })() : number +>(() => { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; } }) : () => number +>() => { switch (s.kind) { case "square": return s.size * s.size; case "rectangle": return s.width * s.height; case "circle": return Math.PI * s.radius * s.radius; case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; } } : () => number + + switch (s.kind) { +>s.kind : "square" | "rectangle" | "circle" | "triangle" +>s : Shape +>kind : "square" | "rectangle" | "circle" | "triangle" + + case "square": return s.size * s.size; +>"square" : "square" +>s.size * s.size : number +>s.size : number +>s : Square +>size : number +>s.size : number +>s : Square +>size : number + + case "rectangle": return s.width * s.height; +>"rectangle" : "rectangle" +>s.width * s.height : number +>s.width : number +>s : Rectangle +>width : number +>s.height : number +>s : Rectangle +>height : number + + case "circle": return Math.PI * s.radius * s.radius; +>"circle" : "circle" +>Math.PI * s.radius * s.radius : number +>Math.PI * s.radius : number +>Math.PI : number +>Math : Math +>PI : number +>s.radius : number +>s : Circle +>radius : number +>s.radius : number +>s : Circle +>radius : number + + case "triangle": return Math.sqrt(3) / 4 * s.side * s.side; +>"triangle" : "triangle" +>Math.sqrt(3) / 4 * s.side * s.side : number +>Math.sqrt(3) / 4 * s.side : number +>Math.sqrt(3) / 4 : number +>Math.sqrt(3) : number +>Math.sqrt : (x: number) => number +>Math : Math +>sqrt : (x: number) => number +>3 : 3 +>4 : 4 +>s.side : number +>s : Triangle +>side : number +>s.side : number +>s : Triangle +>side : number + } + })(); + return area; +>area : number +} + +// Repro from #13241 + +enum MyEnum { +>MyEnum : MyEnum + + A, +>A : MyEnum.A + + B +>B : MyEnum.B +} + +function thisGivesError(e: MyEnum): string { +>thisGivesError : (e: MyEnum) => string +>e : MyEnum + + let s: string; +>s : string + + switch (e) { +>e : MyEnum + + case MyEnum.A: s = "it was A"; break; +>MyEnum.A : MyEnum.A +>MyEnum : typeof MyEnum +>A : MyEnum.A +>s = "it was A" : "it was A" +>s : string +>"it was A" : "it was A" + + case MyEnum.B: s = "it was B"; break; +>MyEnum.B : MyEnum.B +>MyEnum : typeof MyEnum +>B : MyEnum.B +>s = "it was B" : "it was B" +>s : string +>"it was B" : "it was B" + } + return s; +>s : string +} + +function good1(e: MyEnum): string { +>good1 : (e: MyEnum) => string +>e : MyEnum + + let s: string; +>s : string + + switch (e) { +>e : MyEnum + + case MyEnum.A: s = "it was A"; break; +>MyEnum.A : MyEnum.A +>MyEnum : typeof MyEnum +>A : MyEnum.A +>s = "it was A" : "it was A" +>s : string +>"it was A" : "it was A" + + case MyEnum.B: s = "it was B"; break; +>MyEnum.B : MyEnum.B +>MyEnum : typeof MyEnum +>B : MyEnum.B +>s = "it was B" : "it was B" +>s : string +>"it was B" : "it was B" + + default: s = "it was something else"; break; +>s = "it was something else" : "it was something else" +>s : string +>"it was something else" : "it was something else" + } + return s; +>s : string +} + +function good2(e: MyEnum): string { +>good2 : (e: MyEnum) => string +>e : MyEnum + + switch (e) { +>e : MyEnum + + case MyEnum.A: return "it was A"; +>MyEnum.A : MyEnum.A +>MyEnum : typeof MyEnum +>A : MyEnum.A +>"it was A" : "it was A" + + case MyEnum.B: return "it was B"; +>MyEnum.B : MyEnum.B +>MyEnum : typeof MyEnum +>B : MyEnum.B +>"it was B" : "it was B" + } +} + +// Repro from #18362 + +enum Level { +>Level : Level + + One, +>One : Level.One + + Two, +>Two : Level.Two +} + +const doSomethingWithLevel = (level: Level) => { +>doSomethingWithLevel : (level: Level) => Level +>(level: Level) => { let next: Level; switch (level) { case Level.One: next = Level.Two; break; case Level.Two: next = Level.One; break; } return next;} : (level: Level) => Level +>level : Level + + let next: Level; +>next : Level + + switch (level) { +>level : Level + + case Level.One: +>Level.One : Level.One +>Level : typeof Level +>One : Level.One + + next = Level.Two; +>next = Level.Two : Level.Two +>next : Level +>Level.Two : Level.Two +>Level : typeof Level +>Two : Level.Two + + break; + case Level.Two: +>Level.Two : Level.Two +>Level : typeof Level +>Two : Level.Two + + next = Level.One; +>next = Level.One : Level.One +>next : Level +>Level.One : Level.One +>Level : typeof Level +>One : Level.One + + break; + } + return next; +>next : Level + +}; + +// Repro from #20409 + +interface Square2 { + kind: "square"; +>kind : "square" + + size: number; +>size : number +} + +interface Circle2 { + kind: "circle"; +>kind : "circle" + + radius: number; +>radius : number +} + +type Shape2 = Square2 | Circle2; +>Shape2 : Shape2 + +function withDefault(s1: Shape2, s2: Shape2): string { +>withDefault : (s1: Shape2, s2: Shape2) => string +>s1 : Shape2 +>s2 : Shape2 + + switch (s1.kind) { +>s1.kind : "square" | "circle" +>s1 : Shape2 +>kind : "square" | "circle" + + case "square": +>"square" : "square" + + return "1"; +>"1" : "1" + + case "circle": +>"circle" : "circle" + + switch (s2.kind) { +>s2.kind : "square" | "circle" +>s2 : Shape2 +>kind : "square" | "circle" + + case "square": +>"square" : "square" + + return "2"; +>"2" : "2" + + case "circle": +>"circle" : "circle" + + return "3"; +>"3" : "3" + + default: + return "never"; +>"never" : "never" + } + } +} + +function withoutDefault(s1: Shape2, s2: Shape2): string { +>withoutDefault : (s1: Shape2, s2: Shape2) => string +>s1 : Shape2 +>s2 : Shape2 + + switch (s1.kind) { +>s1.kind : "square" | "circle" +>s1 : Shape2 +>kind : "square" | "circle" + + case "square": +>"square" : "square" + + return "1"; +>"1" : "1" + + case "circle": +>"circle" : "circle" + + switch (s2.kind) { +>s2.kind : "square" | "circle" +>s2 : Shape2 +>kind : "square" | "circle" + + case "square": +>"square" : "square" + + return "2"; +>"2" : "2" + + case "circle": +>"circle" : "circle" + + return "3"; +>"3" : "3" + } + } +} + +// Repro from #20823 + +function test4(value: 1 | 2) { +>test4 : (value: 1 | 2) => string +>value : 1 | 2 + + let x: string; +>x : string + + switch (value) { +>value : 1 | 2 + + case 1: x = "one"; break; +>1 : 1 +>x = "one" : "one" +>x : string +>"one" : "one" + + case 2: x = "two"; break; +>2 : 2 +>x = "two" : "two" +>x : string +>"two" : "two" + } + return x; +>x : string +} + diff --git a/tests/baselines/reference/neverReturningFunctions1.errors.txt b/tests/baselines/reference/neverReturningFunctions1.errors.txt new file mode 100644 index 00000000000..f8656bbed08 --- /dev/null +++ b/tests/baselines/reference/neverReturningFunctions1.errors.txt @@ -0,0 +1,227 @@ +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(13,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(19,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(30,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(36,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(51,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(57,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(63,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(77,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(82,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(89,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(96,13): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(101,13): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(103,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(105,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(111,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(112,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(122,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(127,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(129,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(139,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(141,5): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(148,9): error TS7027: Unreachable code detected. +tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(153,5): error TS7027: Unreachable code detected. + + +==== tests/cases/conformance/controlFlow/neverReturningFunctions1.ts (23 errors) ==== + function fail(message?: string): never { + throw new Error(message); + } + + function f01(x: string | undefined) { + if (x === undefined) fail("undefined argument"); + x.length; // string + } + + function f02(x: number): number { + if (x >= 0) return x; + fail("negative number"); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + function f03(x: string) { + x; // string + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + function f11(x: string | undefined, fail: (message?: string) => never) { + if (x === undefined) fail("undefined argument"); + x.length; // string + } + + function f12(x: number, fail: (message?: string) => never): number { + if (x >= 0) return x; + fail("negative number"); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + function f13(x: string, fail: (message?: string) => never) { + x; // string + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + namespace Debug { + export declare function fail(message?: string): never; + } + + function f21(x: string | undefined) { + if (x === undefined) Debug.fail("undefined argument"); + x.length; // string + } + + function f22(x: number): number { + if (x >= 0) return x; + Debug.fail("negative number"); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + function f23(x: string) { + x; // string + Debug.fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + function f24(x: string) { + x; // string + ((Debug).fail)(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + class Test { + fail(message?: string): never { + throw new Error(message); + } + f1(x: string | undefined) { + if (x === undefined) this.fail("undefined argument"); + x.length; // string + } + f2(x: number): number { + if (x >= 0) return x; + this.fail("negative number"); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + f3(x: string) { + x; // string + this.fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + } + + function f30(x: string | number | undefined) { + if (typeof x === "string") { + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + else { + x; // number | undefined + if (x !== undefined) { + x; // number + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + else { + x; // undefined + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + function f31(x: { a: string | number }) { + if (typeof x.a === "string") { + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + x.a; // Unreachable + ~~~~ +!!! error TS7027: Unreachable code detected. + } + x; // { a: string | number } + x.a; // number + } + + function f40(x: number) { + try { + x; + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + finally { + x; + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + function f41(x: number) { + try { + x; + } + finally { + x; + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + + function f42(x: number) { + try { + x; + fail(); + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + finally { + x; + } + x; // Unreachable + ~~ +!!! error TS7027: Unreachable code detected. + } + \ No newline at end of file diff --git a/tests/baselines/reference/neverReturningFunctions1.js b/tests/baselines/reference/neverReturningFunctions1.js new file mode 100644 index 00000000000..cce75c6668a --- /dev/null +++ b/tests/baselines/reference/neverReturningFunctions1.js @@ -0,0 +1,337 @@ +//// [neverReturningFunctions1.ts] +function fail(message?: string): never { + throw new Error(message); +} + +function f01(x: string | undefined) { + if (x === undefined) fail("undefined argument"); + x.length; // string +} + +function f02(x: number): number { + if (x >= 0) return x; + fail("negative number"); + x; // Unreachable +} + +function f03(x: string) { + x; // string + fail(); + x; // Unreachable +} + +function f11(x: string | undefined, fail: (message?: string) => never) { + if (x === undefined) fail("undefined argument"); + x.length; // string +} + +function f12(x: number, fail: (message?: string) => never): number { + if (x >= 0) return x; + fail("negative number"); + x; // Unreachable +} + +function f13(x: string, fail: (message?: string) => never) { + x; // string + fail(); + x; // Unreachable +} + +namespace Debug { + export declare function fail(message?: string): never; +} + +function f21(x: string | undefined) { + if (x === undefined) Debug.fail("undefined argument"); + x.length; // string +} + +function f22(x: number): number { + if (x >= 0) return x; + Debug.fail("negative number"); + x; // Unreachable +} + +function f23(x: string) { + x; // string + Debug.fail(); + x; // Unreachable +} + +function f24(x: string) { + x; // string + ((Debug).fail)(); + x; // Unreachable +} + +class Test { + fail(message?: string): never { + throw new Error(message); + } + f1(x: string | undefined) { + if (x === undefined) this.fail("undefined argument"); + x.length; // string + } + f2(x: number): number { + if (x >= 0) return x; + this.fail("negative number"); + x; // Unreachable + } + f3(x: string) { + x; // string + this.fail(); + x; // Unreachable + } +} + +function f30(x: string | number | undefined) { + if (typeof x === "string") { + fail(); + x; // Unreachable + } + else { + x; // number | undefined + if (x !== undefined) { + x; // number + fail(); + x; // Unreachable + } + else { + x; // undefined + fail(); + x; // Unreachable + } + x; // Unreachable + } + x; // Unreachable +} + +function f31(x: { a: string | number }) { + if (typeof x.a === "string") { + fail(); + x; // Unreachable + x.a; // Unreachable + } + x; // { a: string | number } + x.a; // number +} + +function f40(x: number) { + try { + x; + fail(); + x; // Unreachable + } + finally { + x; + fail(); + x; // Unreachable + } + x; // Unreachable +} + +function f41(x: number) { + try { + x; + } + finally { + x; + fail(); + x; // Unreachable + } + x; // Unreachable +} + +function f42(x: number) { + try { + x; + fail(); + x; // Unreachable + } + finally { + x; + } + x; // Unreachable +} + + +//// [neverReturningFunctions1.js] +"use strict"; +function fail(message) { + throw new Error(message); +} +function f01(x) { + if (x === undefined) + fail("undefined argument"); + x.length; // string +} +function f02(x) { + if (x >= 0) + return x; + fail("negative number"); + x; // Unreachable +} +function f03(x) { + x; // string + fail(); + x; // Unreachable +} +function f11(x, fail) { + if (x === undefined) + fail("undefined argument"); + x.length; // string +} +function f12(x, fail) { + if (x >= 0) + return x; + fail("negative number"); + x; // Unreachable +} +function f13(x, fail) { + x; // string + fail(); + x; // Unreachable +} +var Debug; +(function (Debug) { +})(Debug || (Debug = {})); +function f21(x) { + if (x === undefined) + Debug.fail("undefined argument"); + x.length; // string +} +function f22(x) { + if (x >= 0) + return x; + Debug.fail("negative number"); + x; // Unreachable +} +function f23(x) { + x; // string + Debug.fail(); + x; // Unreachable +} +function f24(x) { + x; // string + ((Debug).fail)(); + x; // Unreachable +} +var Test = /** @class */ (function () { + function Test() { + } + Test.prototype.fail = function (message) { + throw new Error(message); + }; + Test.prototype.f1 = function (x) { + if (x === undefined) + this.fail("undefined argument"); + x.length; // string + }; + Test.prototype.f2 = function (x) { + if (x >= 0) + return x; + this.fail("negative number"); + x; // Unreachable + }; + Test.prototype.f3 = function (x) { + x; // string + this.fail(); + x; // Unreachable + }; + return Test; +}()); +function f30(x) { + if (typeof x === "string") { + fail(); + x; // Unreachable + } + else { + x; // number | undefined + if (x !== undefined) { + x; // number + fail(); + x; // Unreachable + } + else { + x; // undefined + fail(); + x; // Unreachable + } + x; // Unreachable + } + x; // Unreachable +} +function f31(x) { + if (typeof x.a === "string") { + fail(); + x; // Unreachable + x.a; // Unreachable + } + x; // { a: string | number } + x.a; // number +} +function f40(x) { + try { + x; + fail(); + x; // Unreachable + } + finally { + x; + fail(); + x; // Unreachable + } + x; // Unreachable +} +function f41(x) { + try { + x; + } + finally { + x; + fail(); + x; // Unreachable + } + x; // Unreachable +} +function f42(x) { + try { + x; + fail(); + x; // Unreachable + } + finally { + x; + } + x; // Unreachable +} + + +//// [neverReturningFunctions1.d.ts] +declare function fail(message?: string): never; +declare function f01(x: string | undefined): void; +declare function f02(x: number): number; +declare function f03(x: string): void; +declare function f11(x: string | undefined, fail: (message?: string) => never): void; +declare function f12(x: number, fail: (message?: string) => never): number; +declare function f13(x: string, fail: (message?: string) => never): void; +declare namespace Debug { + function fail(message?: string): never; +} +declare function f21(x: string | undefined): void; +declare function f22(x: number): number; +declare function f23(x: string): void; +declare function f24(x: string): void; +declare class Test { + fail(message?: string): never; + f1(x: string | undefined): void; + f2(x: number): number; + f3(x: string): void; +} +declare function f30(x: string | number | undefined): void; +declare function f31(x: { + a: string | number; +}): void; +declare function f40(x: number): void; +declare function f41(x: number): void; +declare function f42(x: number): void; diff --git a/tests/baselines/reference/neverReturningFunctions1.symbols b/tests/baselines/reference/neverReturningFunctions1.symbols new file mode 100644 index 00000000000..7f1b5c489ac --- /dev/null +++ b/tests/baselines/reference/neverReturningFunctions1.symbols @@ -0,0 +1,387 @@ +=== tests/cases/conformance/controlFlow/neverReturningFunctions1.ts === +function fail(message?: string): never { +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) +>message : Symbol(message, Decl(neverReturningFunctions1.ts, 0, 14)) + + throw new Error(message); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>message : Symbol(message, Decl(neverReturningFunctions1.ts, 0, 14)) +} + +function f01(x: string | undefined) { +>f01 : Symbol(f01, Decl(neverReturningFunctions1.ts, 2, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 4, 13)) + + if (x === undefined) fail("undefined argument"); +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 4, 13)) +>undefined : Symbol(undefined) +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x.length; // string +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 4, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +} + +function f02(x: number): number { +>f02 : Symbol(f02, Decl(neverReturningFunctions1.ts, 7, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 9, 13)) + + if (x >= 0) return x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 9, 13)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 9, 13)) + + fail("negative number"); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 9, 13)) +} + +function f03(x: string) { +>f03 : Symbol(f03, Decl(neverReturningFunctions1.ts, 13, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 15, 13)) + + x; // string +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 15, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 15, 13)) +} + +function f11(x: string | undefined, fail: (message?: string) => never) { +>f11 : Symbol(f11, Decl(neverReturningFunctions1.ts, 19, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 21, 13)) +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 21, 35)) +>message : Symbol(message, Decl(neverReturningFunctions1.ts, 21, 43)) + + if (x === undefined) fail("undefined argument"); +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 21, 13)) +>undefined : Symbol(undefined) +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 21, 35)) + + x.length; // string +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 21, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +} + +function f12(x: number, fail: (message?: string) => never): number { +>f12 : Symbol(f12, Decl(neverReturningFunctions1.ts, 24, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 26, 13)) +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 26, 23)) +>message : Symbol(message, Decl(neverReturningFunctions1.ts, 26, 31)) + + if (x >= 0) return x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 26, 13)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 26, 13)) + + fail("negative number"); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 26, 23)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 26, 13)) +} + +function f13(x: string, fail: (message?: string) => never) { +>f13 : Symbol(f13, Decl(neverReturningFunctions1.ts, 30, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 32, 13)) +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 32, 23)) +>message : Symbol(message, Decl(neverReturningFunctions1.ts, 32, 31)) + + x; // string +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 32, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 32, 23)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 32, 13)) +} + +namespace Debug { +>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1)) + + export declare function fail(message?: string): never; +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 38, 17)) +>message : Symbol(message, Decl(neverReturningFunctions1.ts, 39, 33)) +} + +function f21(x: string | undefined) { +>f21 : Symbol(f21, Decl(neverReturningFunctions1.ts, 40, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 42, 13)) + + if (x === undefined) Debug.fail("undefined argument"); +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 42, 13)) +>undefined : Symbol(undefined) +>Debug.fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17)) +>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1)) +>fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17)) + + x.length; // string +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 42, 13)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +} + +function f22(x: number): number { +>f22 : Symbol(f22, Decl(neverReturningFunctions1.ts, 45, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 47, 13)) + + if (x >= 0) return x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 47, 13)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 47, 13)) + + Debug.fail("negative number"); +>Debug.fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17)) +>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1)) +>fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 47, 13)) +} + +function f23(x: string) { +>f23 : Symbol(f23, Decl(neverReturningFunctions1.ts, 51, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 53, 13)) + + x; // string +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 53, 13)) + + Debug.fail(); +>Debug.fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17)) +>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1)) +>fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 53, 13)) +} + +function f24(x: string) { +>f24 : Symbol(f24, Decl(neverReturningFunctions1.ts, 57, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 59, 13)) + + x; // string +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 59, 13)) + + ((Debug).fail)(); +>(Debug).fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17)) +>Debug : Symbol(Debug, Decl(neverReturningFunctions1.ts, 36, 1)) +>fail : Symbol(Debug.fail, Decl(neverReturningFunctions1.ts, 38, 17)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 59, 13)) +} + +class Test { +>Test : Symbol(Test, Decl(neverReturningFunctions1.ts, 63, 1)) + + fail(message?: string): never { +>fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12)) +>message : Symbol(message, Decl(neverReturningFunctions1.ts, 66, 9)) + + throw new Error(message); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>message : Symbol(message, Decl(neverReturningFunctions1.ts, 66, 9)) + } + f1(x: string | undefined) { +>f1 : Symbol(Test.f1, Decl(neverReturningFunctions1.ts, 68, 5)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 69, 7)) + + if (x === undefined) this.fail("undefined argument"); +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 69, 7)) +>undefined : Symbol(undefined) +>this.fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12)) +>this : Symbol(Test, Decl(neverReturningFunctions1.ts, 63, 1)) +>fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12)) + + x.length; // string +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 69, 7)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + } + f2(x: number): number { +>f2 : Symbol(Test.f2, Decl(neverReturningFunctions1.ts, 72, 5)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 73, 7)) + + if (x >= 0) return x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 73, 7)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 73, 7)) + + this.fail("negative number"); +>this.fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12)) +>this : Symbol(Test, Decl(neverReturningFunctions1.ts, 63, 1)) +>fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 73, 7)) + } + f3(x: string) { +>f3 : Symbol(Test.f3, Decl(neverReturningFunctions1.ts, 77, 5)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 78, 7)) + + x; // string +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 78, 7)) + + this.fail(); +>this.fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12)) +>this : Symbol(Test, Decl(neverReturningFunctions1.ts, 63, 1)) +>fail : Symbol(Test.fail, Decl(neverReturningFunctions1.ts, 65, 12)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 78, 7)) + } +} + +function f30(x: string | number | undefined) { +>f30 : Symbol(f30, Decl(neverReturningFunctions1.ts, 83, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + + if (typeof x === "string") { +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + } + else { + x; // number | undefined +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + + if (x !== undefined) { +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) +>undefined : Symbol(undefined) + + x; // number +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + } + else { + x; // undefined +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + } + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) + } + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 85, 13)) +} + +function f31(x: { a: string | number }) { +>f31 : Symbol(f31, Decl(neverReturningFunctions1.ts, 105, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13)) +>a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17)) + + if (typeof x.a === "string") { +>x.a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13)) +>a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13)) + + x.a; // Unreachable +>x.a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13)) +>a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17)) + } + x; // { a: string | number } +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13)) + + x.a; // number +>x.a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 107, 13)) +>a : Symbol(a, Decl(neverReturningFunctions1.ts, 107, 17)) +} + +function f40(x: number) { +>f40 : Symbol(f40, Decl(neverReturningFunctions1.ts, 115, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13)) + + try { + x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13)) + } + finally { + x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13)) + } + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 117, 13)) +} + +function f41(x: number) { +>f41 : Symbol(f41, Decl(neverReturningFunctions1.ts, 129, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13)) + + try { + x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13)) + } + finally { + x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13)) + } + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 131, 13)) +} + +function f42(x: number) { +>f42 : Symbol(f42, Decl(neverReturningFunctions1.ts, 141, 1)) +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13)) + + try { + x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13)) + + fail(); +>fail : Symbol(fail, Decl(neverReturningFunctions1.ts, 0, 0)) + + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13)) + } + finally { + x; +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13)) + } + x; // Unreachable +>x : Symbol(x, Decl(neverReturningFunctions1.ts, 143, 13)) +} + diff --git a/tests/baselines/reference/neverReturningFunctions1.types b/tests/baselines/reference/neverReturningFunctions1.types new file mode 100644 index 00000000000..e7d6afa36a5 --- /dev/null +++ b/tests/baselines/reference/neverReturningFunctions1.types @@ -0,0 +1,439 @@ +=== tests/cases/conformance/controlFlow/neverReturningFunctions1.ts === +function fail(message?: string): never { +>fail : (message?: string | undefined) => never +>message : string | undefined + + throw new Error(message); +>new Error(message) : Error +>Error : ErrorConstructor +>message : string | undefined +} + +function f01(x: string | undefined) { +>f01 : (x: string | undefined) => void +>x : string | undefined + + if (x === undefined) fail("undefined argument"); +>x === undefined : boolean +>x : string | undefined +>undefined : undefined +>fail("undefined argument") : never +>fail : (message?: string | undefined) => never +>"undefined argument" : "undefined argument" + + x.length; // string +>x.length : number +>x : string +>length : number +} + +function f02(x: number): number { +>f02 : (x: number) => number +>x : number + + if (x >= 0) return x; +>x >= 0 : boolean +>x : number +>0 : 0 +>x : number + + fail("negative number"); +>fail("negative number") : never +>fail : (message?: string | undefined) => never +>"negative number" : "negative number" + + x; // Unreachable +>x : number +} + +function f03(x: string) { +>f03 : (x: string) => void +>x : string + + x; // string +>x : string + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : string +} + +function f11(x: string | undefined, fail: (message?: string) => never) { +>f11 : (x: string | undefined, fail: (message?: string | undefined) => never) => void +>x : string | undefined +>fail : (message?: string | undefined) => never +>message : string | undefined + + if (x === undefined) fail("undefined argument"); +>x === undefined : boolean +>x : string | undefined +>undefined : undefined +>fail("undefined argument") : never +>fail : (message?: string | undefined) => never +>"undefined argument" : "undefined argument" + + x.length; // string +>x.length : number +>x : string +>length : number +} + +function f12(x: number, fail: (message?: string) => never): number { +>f12 : (x: number, fail: (message?: string | undefined) => never) => number +>x : number +>fail : (message?: string | undefined) => never +>message : string | undefined + + if (x >= 0) return x; +>x >= 0 : boolean +>x : number +>0 : 0 +>x : number + + fail("negative number"); +>fail("negative number") : never +>fail : (message?: string | undefined) => never +>"negative number" : "negative number" + + x; // Unreachable +>x : number +} + +function f13(x: string, fail: (message?: string) => never) { +>f13 : (x: string, fail: (message?: string | undefined) => never) => void +>x : string +>fail : (message?: string | undefined) => never +>message : string | undefined + + x; // string +>x : string + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : string +} + +namespace Debug { +>Debug : typeof Debug + + export declare function fail(message?: string): never; +>fail : (message?: string | undefined) => never +>message : string | undefined +} + +function f21(x: string | undefined) { +>f21 : (x: string | undefined) => void +>x : string | undefined + + if (x === undefined) Debug.fail("undefined argument"); +>x === undefined : boolean +>x : string | undefined +>undefined : undefined +>Debug.fail("undefined argument") : never +>Debug.fail : (message?: string | undefined) => never +>Debug : typeof Debug +>fail : (message?: string | undefined) => never +>"undefined argument" : "undefined argument" + + x.length; // string +>x.length : number +>x : string +>length : number +} + +function f22(x: number): number { +>f22 : (x: number) => number +>x : number + + if (x >= 0) return x; +>x >= 0 : boolean +>x : number +>0 : 0 +>x : number + + Debug.fail("negative number"); +>Debug.fail("negative number") : never +>Debug.fail : (message?: string | undefined) => never +>Debug : typeof Debug +>fail : (message?: string | undefined) => never +>"negative number" : "negative number" + + x; // Unreachable +>x : number +} + +function f23(x: string) { +>f23 : (x: string) => void +>x : string + + x; // string +>x : string + + Debug.fail(); +>Debug.fail() : never +>Debug.fail : (message?: string | undefined) => never +>Debug : typeof Debug +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : string +} + +function f24(x: string) { +>f24 : (x: string) => void +>x : string + + x; // string +>x : string + + ((Debug).fail)(); +>((Debug).fail)() : never +>((Debug).fail) : (message?: string | undefined) => never +>(Debug).fail : (message?: string | undefined) => never +>(Debug) : typeof Debug +>Debug : typeof Debug +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : string +} + +class Test { +>Test : Test + + fail(message?: string): never { +>fail : (message?: string | undefined) => never +>message : string | undefined + + throw new Error(message); +>new Error(message) : Error +>Error : ErrorConstructor +>message : string | undefined + } + f1(x: string | undefined) { +>f1 : (x: string | undefined) => void +>x : string | undefined + + if (x === undefined) this.fail("undefined argument"); +>x === undefined : boolean +>x : string | undefined +>undefined : undefined +>this.fail("undefined argument") : never +>this.fail : (message?: string | undefined) => never +>this : this +>fail : (message?: string | undefined) => never +>"undefined argument" : "undefined argument" + + x.length; // string +>x.length : number +>x : string +>length : number + } + f2(x: number): number { +>f2 : (x: number) => number +>x : number + + if (x >= 0) return x; +>x >= 0 : boolean +>x : number +>0 : 0 +>x : number + + this.fail("negative number"); +>this.fail("negative number") : never +>this.fail : (message?: string | undefined) => never +>this : this +>fail : (message?: string | undefined) => never +>"negative number" : "negative number" + + x; // Unreachable +>x : number + } + f3(x: string) { +>f3 : (x: string) => void +>x : string + + x; // string +>x : string + + this.fail(); +>this.fail() : never +>this.fail : (message?: string | undefined) => never +>this : this +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : string + } +} + +function f30(x: string | number | undefined) { +>f30 : (x: string | number | undefined) => void +>x : string | number | undefined + + if (typeof x === "string") { +>typeof x === "string" : boolean +>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : string | number | undefined +>"string" : "string" + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : string | number | undefined + } + else { + x; // number | undefined +>x : number | undefined + + if (x !== undefined) { +>x !== undefined : boolean +>x : number | undefined +>undefined : undefined + + x; // number +>x : number + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : string | number | undefined + } + else { + x; // undefined +>x : undefined + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : string | number | undefined + } + x; // Unreachable +>x : string | number | undefined + } + x; // Unreachable +>x : string | number | undefined +} + +function f31(x: { a: string | number }) { +>f31 : (x: { a: string | number; }) => void +>x : { a: string | number; } +>a : string | number + + if (typeof x.a === "string") { +>typeof x.a === "string" : boolean +>typeof x.a : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x.a : string | number +>x : { a: string | number; } +>a : string | number +>"string" : "string" + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : { a: string | number; } + + x.a; // Unreachable +>x.a : string | number +>x : { a: string | number; } +>a : string | number + } + x; // { a: string | number } +>x : { a: string | number; } + + x.a; // number +>x.a : number +>x : { a: string | number; } +>a : number +} + +function f40(x: number) { +>f40 : (x: number) => void +>x : number + + try { + x; +>x : number + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : number + } + finally { + x; +>x : number + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : number + } + x; // Unreachable +>x : number +} + +function f41(x: number) { +>f41 : (x: number) => void +>x : number + + try { + x; +>x : number + } + finally { + x; +>x : number + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : number + } + x; // Unreachable +>x : number +} + +function f42(x: number) { +>f42 : (x: number) => void +>x : number + + try { + x; +>x : number + + fail(); +>fail() : never +>fail : (message?: string | undefined) => never + + x; // Unreachable +>x : number + } + finally { + x; +>x : number + } + x; // Unreachable +>x : number +} + From bcdf33d8de066b827e8251875675b7a0084446c5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Sep 2019 17:44:19 -0700 Subject: [PATCH 088/100] Fix forEachChild --- src/compiler/parser.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9852ee8feb7..edaa7ebeaeb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -165,7 +165,8 @@ namespace ts { return visitNode(cbNode, (node).typeName) || visitNodes(cbNode, cbNodes, (node).typeArguments); case SyntaxKind.TypePredicate: - return visitNode(cbNode, (node).parameterName) || + return visitNode(cbNode, (node).assertsModifier) || + visitNode(cbNode, (node).parameterName) || visitNode(cbNode, (node).type); case SyntaxKind.TypeQuery: return visitNode(cbNode, (node).exprName); From 0da541528e89f5483a44fc0b200d9b537d93a0b6 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Mon, 23 Sep 2019 14:08:43 -0400 Subject: [PATCH 089/100] Remove errors from the gulpfile --- Gulpfile.js | 2 ++ scripts/types/ambient.d.ts | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Gulpfile.js b/Gulpfile.js index 51127f9822d..1f930e3b019 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -333,6 +333,8 @@ task("run-eslint-rules-tests").description = "Runs the eslint rule tests"; const lintFoldStart = async () => { if (fold.isTravis()) console.log(fold.start("lint")); }; const lintFoldEnd = async () => { if (fold.isTravis()) console.log(fold.end("lint")); }; + +/** @type { (folder: string) => { (): Promise; displayName?: string } } */ const eslint = (folder) => async () => { const ESLINTRC_CI = ".eslintrc.ci.json"; const isCIEnv = cmdLineOptions.ci || process.env.CI === "true"; diff --git a/scripts/types/ambient.d.ts b/scripts/types/ambient.d.ts index 9ea70adee50..d48de7c05d7 100644 --- a/scripts/types/ambient.d.ts +++ b/scripts/types/ambient.d.ts @@ -76,10 +76,15 @@ declare module "undertaker" { interface TaskFunctionParams { flags?: Record; } + interface TaskFunctionWrapped { + description: string + flags: { [name: string]: string } + } } declare module "gulp-sourcemaps" { interface WriteOptions { destPath?: string; } -} \ No newline at end of file + +} From 86c7d84457290d98e71a4d5b6f50623bc3221bde Mon Sep 17 00:00:00 2001 From: Nathan Fenner Date: Mon, 23 Sep 2019 12:02:13 -0700 Subject: [PATCH 090/100] update missing baselines --- tests/baselines/reference/checkJsxChildrenProperty15.errors.txt | 2 +- tests/baselines/reference/tsxUnionElementType4.errors.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/checkJsxChildrenProperty15.errors.txt b/tests/baselines/reference/checkJsxChildrenProperty15.errors.txt index fa034be0f18..d0be275765f 100644 --- a/tests/baselines/reference/checkJsxChildrenProperty15.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenProperty15.errors.txt @@ -17,7 +17,7 @@ tests/cases/conformance/jsx/file.tsx(12,13): error TS2322: Type '{ children: Ele // Not OK (excess children) const k3 = } />; - ~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~ !!! error TS2322: Type '{ children: Element; }' is not assignable to type 'IntrinsicAttributes'. !!! error TS2322: Property 'children' does not exist on type 'IntrinsicAttributes'. const k4 =
; diff --git a/tests/baselines/reference/tsxUnionElementType4.errors.txt b/tests/baselines/reference/tsxUnionElementType4.errors.txt index 2048b100c11..40463bcbb79 100644 --- a/tests/baselines/reference/tsxUnionElementType4.errors.txt +++ b/tests/baselines/reference/tsxUnionElementType4.errors.txt @@ -42,7 +42,7 @@ tests/cases/conformance/jsx/file.tsx(34,22): error TS2322: Type '{ prop: true; } !!! error TS2322: Type 'true' is not assignable to type 'never'. !!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }' let b = - ~~~~~~ + ~ !!! error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. !!! error TS2322: Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes & { children?: ReactNode; }'. let c = ; From f9ca8ba6f863e2de07b6bcf224ecb8460fc17016 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Mon, 23 Sep 2019 14:09:51 -0700 Subject: [PATCH 091/100] Update user baselines (#33557) --- tests/baselines/reference/docker/office-ui-fabric.log | 2 +- tests/baselines/reference/user/prettier.log | 4 +--- tests/baselines/reference/user/webpack.log | 10 ---------- 3 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 tests/baselines/reference/user/webpack.log diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index 7bd402b8327..9cda725e39e 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -134,9 +134,9 @@ Standard output: @uifabric/utilities: PASS src/warn/warnControlledUsage.test.ts @uifabric/utilities: PASS src/focus.test.tsx @uifabric/utilities: PASS src/styled.test.tsx +@uifabric/utilities: PASS src/customizations/Customizer.test.tsx @uifabric/utilities: PASS src/EventGroup.test.ts @uifabric/utilities: PASS src/array.test.ts -@uifabric/utilities: PASS src/customizations/Customizer.test.tsx @uifabric/utilities: PASS src/math.test.ts @uifabric/utilities: PASS src/warn/warn.test.ts @uifabric/utilities: PASS src/dom/dom.test.ts diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log index 93ccd99a0d6..635c0bc0b36 100644 --- a/tests/baselines/reference/user/prettier.log +++ b/tests/baselines/reference/user/prettier.log @@ -169,7 +169,7 @@ src/language-html/syntax-vue.js(14,27): error TS2339: Property 'right' does not src/language-html/utils.js(10,30): error TS2307: Cannot find module 'html-tag-names'. src/language-html/utils.js(11,39): error TS2307: Cannot find module 'html-element-attributes'. src/language-html/utils.js(444,17): error TS2554: Expected 0 arguments, but got 1. -src/language-js/comments.js(864,64): error TS2554: Expected 0 arguments, but got 1. +src/language-js/comments.js(865,64): error TS2554: Expected 0 arguments, but got 1. src/language-js/index.js(9,26): error TS2307: Cannot find module 'linguist-languages/data/JavaScript'. src/language-js/index.js(9,65): error TS2345: Argument of type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { interpreters: string[]; }; }' is not assignable to parameter of type '{ extend: any; override: any; exclude: any; }'. Property 'exclude' is missing in type '{ override: { since: string; parsers: string[]; vscodeLanguageIds: string[]; }; extend: { interpreters: string[]; }; }' but required in type '{ extend: any; override: any; exclude: any; }'. @@ -335,8 +335,6 @@ src/main/options-normalizer.js(36,35): error TS2339: Property 'blue' does not ex src/main/options-normalizer.js(54,5): error TS2525: Initializer provides no value for this binding element and the binding element has no default value. src/main/options-normalizer.js(74,16): error TS2341: Property '_hasDeprecationWarned' is private and only accessible within class 'Normalizer'. src/main/options-normalizer.js(80,39): error TS2341: Property '_hasDeprecationWarned' is private and only accessible within class 'Normalizer'. -src/main/options-normalizer.js(90,44): error TS2345: Argument of type '{ name: string; }' is not assignable to parameter of type 'SchemaHandlers'. - Object literal may only specify known properties, and 'name' does not exist in type 'SchemaHandlers'. src/main/options-normalizer.js(99,11): error TS2345: Argument of type '{ name: any; sourceName: any; }' is not assignable to parameter of type 'SchemaHandlers'. Object literal may only specify known properties, and 'name' does not exist in type 'SchemaHandlers'. src/main/options-normalizer.js(143,13): error TS2769: No overload matches this call. diff --git a/tests/baselines/reference/user/webpack.log b/tests/baselines/reference/user/webpack.log deleted file mode 100644 index d1fbc9df903..00000000000 --- a/tests/baselines/reference/user/webpack.log +++ /dev/null @@ -1,10 +0,0 @@ -Exit Code: 1 -Standard output: -lib/Compilation.js(575,5): error TS2322: Type 'number | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | ... 29 more ... | "trimRight"' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. -lib/Compiler.js(228,48): error TS2345: Argument of type 'number | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | ... 29 more ... | "trimRight"' is not assignable to parameter of type 'string'. - Type 'number' is not assignable to type 'string'. - - - -Standard error: From 84e857b6f3624fcb01db807affa49ca8d9580f3b Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 23 Sep 2019 15:57:32 -0700 Subject: [PATCH 092/100] use forEachEntry --- src/services/codefixes/inferFromUsage.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 090c241b05d..5dd34782885 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -947,22 +947,19 @@ namespace ts.codefix { function allPropertiesAreAssignableToUsage(type: Type, usage: Usage) { if (!usage.properties) return false; - let result = true; - usage.properties.forEach((propUsage, name) => { + return !forEachEntry(usage.properties, (propUsage, name) => { const source = checker.getTypeOfPropertyOfType(type, name as string); if (!source) { - result = false; - return; + return true; } if (propUsage.calls) { const sigs = checker.getSignaturesOfType(source, SignatureKind.Call); - result = result && !!sigs.length && checker.isTypeAssignableTo(source, getFunctionFromCalls(propUsage.calls)); + return !sigs.length || !checker.isTypeAssignableTo(source, getFunctionFromCalls(propUsage.calls)); } else { - result = result && checker.isTypeAssignableTo(source, combineFromUsage(propUsage)); + return !checker.isTypeAssignableTo(source, combineFromUsage(propUsage)); } }); - return result; } /** From 6c2ae12559508b594f7038f8d6165b92ec89c58c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Sep 2019 15:58:03 -0700 Subject: [PATCH 093/100] Relax the constraints of isValidBaseType to allow base types to be constructor types (#33146) * Relax the constraints of isValidBaseType to allow base types to be constructor types * Fix nit * Reduce confusion between isConstructorType and isValidBaseType * Update comment --- src/compiler/checker.ts | 19 +++-- src/compiler/types.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../baseConstraintOfDecorator.errors.txt | 17 +--- .../baseConstraintOfDecorator.symbols | 1 + .../reference/baseConstraintOfDecorator.types | 8 +- .../mixinIntersectionIsValidbaseType.js | 77 +++++++++++++++++++ .../mixinIntersectionIsValidbaseType.symbols | 74 ++++++++++++++++++ .../mixinIntersectionIsValidbaseType.types | 67 ++++++++++++++++ .../mixinIntersectionIsValidbaseType.ts | 27 +++++++ 11 files changed, 271 insertions(+), 25 deletions(-) create mode 100644 tests/baselines/reference/mixinIntersectionIsValidbaseType.js create mode 100644 tests/baselines/reference/mixinIntersectionIsValidbaseType.symbols create mode 100644 tests/baselines/reference/mixinIntersectionIsValidbaseType.types create mode 100644 tests/cases/compiler/mixinIntersectionIsValidbaseType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a3be2cfce43..e29f46f2dec 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5985,7 +5985,9 @@ namespace ts { function getBaseTypeVariableOfClass(symbol: Symbol) { const baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol)); - return baseConstructorType.flags & TypeFlags.TypeVariable ? baseConstructorType : undefined; + return baseConstructorType.flags & TypeFlags.TypeVariable ? baseConstructorType : + baseConstructorType.flags & TypeFlags.Intersection ? find((baseConstructorType as IntersectionType).types, t => !!(t.flags & TypeFlags.TypeVariable)) : + undefined; } function getTypeOfFuncClassEnumModule(symbol: Symbol): Type { @@ -6263,12 +6265,12 @@ namespace ts { } function isConstructorType(type: Type): boolean { - if (isValidBaseType(type) && getSignaturesOfType(type, SignatureKind.Construct).length > 0) { + if (getSignaturesOfType(type, SignatureKind.Construct).length > 0) { return true; } if (type.flags & TypeFlags.TypeVariable) { const constraint = getBaseConstraintOfType(type); - return !!constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint); + return !!constraint && isMixinConstructorType(constraint); } return false; } @@ -6429,9 +6431,16 @@ namespace ts { return true; } - // A valid base type is `any`, any non-generic object type or intersection of non-generic - // object types. + // A valid base type is `any`, an object type or intersection of object types. function isValidBaseType(type: Type): type is BaseType { + if (type.flags & TypeFlags.TypeParameter) { + const constraint = getBaseConstraintOfType(type); + if (constraint) { + return isValidBaseType(constraint); + } + } + // TODO: Given that we allow type parmeters here now, is this `!isGenericMappedType(type)` check really needed? + // There's no reason a `T` should be allowed while a `Readonly` should not. return !!(type.flags & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.Any)) && !isGenericMappedType(type) || !!(type.flags & TypeFlags.Intersection) && every((type).types, isValidBaseType); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1828d056405..e20518ed119 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4202,7 +4202,7 @@ namespace ts { } // Object type or intersection of object types - export type BaseType = ObjectType | IntersectionType; + export type BaseType = ObjectType | IntersectionType | TypeVariable; // Also `any` and `object` export interface InterfaceTypeWithDeclaredMembers extends InterfaceType { declaredProperties: Symbol[]; // Declared members diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 79450ca83c9..c87d62b1139 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2340,7 +2340,7 @@ declare namespace ts { localTypeParameters: TypeParameter[] | undefined; thisType: TypeParameter | undefined; } - export type BaseType = ObjectType | IntersectionType; + export type BaseType = ObjectType | IntersectionType | TypeVariable; export interface InterfaceTypeWithDeclaredMembers extends InterfaceType { declaredProperties: Symbol[]; declaredCallSignatures: Signature[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f0ae718d570..9c509d34a95 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2340,7 +2340,7 @@ declare namespace ts { localTypeParameters: TypeParameter[] | undefined; thisType: TypeParameter | undefined; } - export type BaseType = ObjectType | IntersectionType; + export type BaseType = ObjectType | IntersectionType | TypeVariable; export interface InterfaceTypeWithDeclaredMembers extends InterfaceType { declaredProperties: Symbol[]; declaredCallSignatures: Signature[]; diff --git a/tests/baselines/reference/baseConstraintOfDecorator.errors.txt b/tests/baselines/reference/baseConstraintOfDecorator.errors.txt index 8317e5c55c6..8aad9f6fead 100644 --- a/tests/baselines/reference/baseConstraintOfDecorator.errors.txt +++ b/tests/baselines/reference/baseConstraintOfDecorator.errors.txt @@ -1,11 +1,10 @@ tests/cases/compiler/baseConstraintOfDecorator.ts(2,5): error TS2322: Type 'typeof decoratorFunc' is not assignable to type 'TFunction'. 'typeof decoratorFunc' is assignable to the constraint of type 'TFunction', but 'TFunction' could be instantiated with a different subtype of constraint '{}'. tests/cases/compiler/baseConstraintOfDecorator.ts(2,40): error TS2507: Type 'TFunction' is not a constructor function type. -tests/cases/compiler/baseConstraintOfDecorator.ts(12,5): error TS2322: Type 'typeof decoratorFunc' is not assignable to type 'TFunction'. -tests/cases/compiler/baseConstraintOfDecorator.ts(12,40): error TS2507: Type 'TFunction' is not a constructor function type. +tests/cases/compiler/baseConstraintOfDecorator.ts(12,18): error TS2545: A mixin class must have a constructor with a single rest parameter of type 'any[]'. -==== tests/cases/compiler/baseConstraintOfDecorator.ts (4 errors) ==== +==== tests/cases/compiler/baseConstraintOfDecorator.ts (3 errors) ==== export function classExtender(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void): TFunction { return class decoratorFunc extends superClass { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -29,20 +28,12 @@ tests/cases/compiler/baseConstraintOfDecorator.ts(12,40): error TS2507: Type 'TF class MyClass { private x; } export function classExtender2 MyClass>(superClass: TFunction, _instanceModifier: (instance: any, args: any[]) => void): TFunction { return class decoratorFunc extends superClass { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ~~~~~~~~~~ -!!! error TS2507: Type 'TFunction' is not a constructor function type. -!!! related TS2735 tests/cases/compiler/baseConstraintOfDecorator.ts:11:32: Did you mean for 'TFunction' to be constrained to type 'new (...args: any[]) => MyClass'? + ~~~~~~~~~~~~~ +!!! error TS2545: A mixin class must have a constructor with a single rest parameter of type 'any[]'. constructor(...args: any[]) { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ super(...args); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ _instanceModifier(this, args); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } - ~~~~~~~~~ }; - ~~~~~~ -!!! error TS2322: Type 'typeof decoratorFunc' is not assignable to type 'TFunction'. } \ No newline at end of file diff --git a/tests/baselines/reference/baseConstraintOfDecorator.symbols b/tests/baselines/reference/baseConstraintOfDecorator.symbols index 9048d7ed568..0a1dad239af 100644 --- a/tests/baselines/reference/baseConstraintOfDecorator.symbols +++ b/tests/baselines/reference/baseConstraintOfDecorator.symbols @@ -51,6 +51,7 @@ export function classExtender2 MyCl >args : Symbol(args, Decl(baseConstraintOfDecorator.ts, 12, 20)) super(...args); +>super : Symbol(TFunction, Decl(baseConstraintOfDecorator.ts, 10, 31)) >args : Symbol(args, Decl(baseConstraintOfDecorator.ts, 12, 20)) _instanceModifier(this, args); diff --git a/tests/baselines/reference/baseConstraintOfDecorator.types b/tests/baselines/reference/baseConstraintOfDecorator.types index a5a277c5d2a..78c77ee78a2 100644 --- a/tests/baselines/reference/baseConstraintOfDecorator.types +++ b/tests/baselines/reference/baseConstraintOfDecorator.types @@ -42,16 +42,16 @@ export function classExtender2 MyCl >args : any[] return class decoratorFunc extends superClass { ->class decoratorFunc extends superClass { constructor(...args: any[]) { super(...args); _instanceModifier(this, args); } } : typeof decoratorFunc ->decoratorFunc : typeof decoratorFunc ->superClass : TFunction +>class decoratorFunc extends superClass { constructor(...args: any[]) { super(...args); _instanceModifier(this, args); } } : { new (...args: any[]): decoratorFunc; prototype: classExtender2.decoratorFunc; } & TFunction +>decoratorFunc : { new (...args: any[]): decoratorFunc; prototype: classExtender2.decoratorFunc; } & TFunction +>superClass : MyClass constructor(...args: any[]) { >args : any[] super(...args); >super(...args) : void ->super : any +>super : TFunction >...args : any >args : any[] diff --git a/tests/baselines/reference/mixinIntersectionIsValidbaseType.js b/tests/baselines/reference/mixinIntersectionIsValidbaseType.js new file mode 100644 index 00000000000..ed02aecd53f --- /dev/null +++ b/tests/baselines/reference/mixinIntersectionIsValidbaseType.js @@ -0,0 +1,77 @@ +//// [mixinIntersectionIsValidbaseType.ts] +export type Constructor = new (...args: any[]) => T; + +export interface Initable { + init(...args: any[]): void; +} + +/** + * Plain mixin where the superclass must be Initable + */ +export const Serializable = & Initable>( + SuperClass: K +) => { + const LocalMixin = (InnerSuperClass: K) => { + return class SerializableLocal extends InnerSuperClass { + } + }; + let ResultClass = LocalMixin(SuperClass); + return ResultClass; +}; + +const AMixin = & Initable>(SuperClass: K) => { + let SomeHowOkay = class A extends SuperClass { + }; + + let SomeHowNotOkay = class A extends Serializable(SuperClass) { + }; +}; + +//// [mixinIntersectionIsValidbaseType.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +/** + * Plain mixin where the superclass must be Initable + */ +exports.Serializable = function (SuperClass) { + var LocalMixin = function (InnerSuperClass) { + return /** @class */ (function (_super) { + __extends(SerializableLocal, _super); + function SerializableLocal() { + return _super !== null && _super.apply(this, arguments) || this; + } + return SerializableLocal; + }(InnerSuperClass)); + }; + var ResultClass = LocalMixin(SuperClass); + return ResultClass; +}; +var AMixin = function (SuperClass) { + var SomeHowOkay = /** @class */ (function (_super) { + __extends(A, _super); + function A() { + return _super !== null && _super.apply(this, arguments) || this; + } + return A; + }(SuperClass)); + var SomeHowNotOkay = /** @class */ (function (_super) { + __extends(A, _super); + function A() { + return _super !== null && _super.apply(this, arguments) || this; + } + return A; + }(exports.Serializable(SuperClass))); +}; diff --git a/tests/baselines/reference/mixinIntersectionIsValidbaseType.symbols b/tests/baselines/reference/mixinIntersectionIsValidbaseType.symbols new file mode 100644 index 00000000000..69fe63bab23 --- /dev/null +++ b/tests/baselines/reference/mixinIntersectionIsValidbaseType.symbols @@ -0,0 +1,74 @@ +=== tests/cases/compiler/mixinIntersectionIsValidbaseType.ts === +export type Constructor = new (...args: any[]) => T; +>Constructor : Symbol(Constructor, Decl(mixinIntersectionIsValidbaseType.ts, 0, 0)) +>T : Symbol(T, Decl(mixinIntersectionIsValidbaseType.ts, 0, 24)) +>args : Symbol(args, Decl(mixinIntersectionIsValidbaseType.ts, 0, 58)) +>T : Symbol(T, Decl(mixinIntersectionIsValidbaseType.ts, 0, 24)) + +export interface Initable { +>Initable : Symbol(Initable, Decl(mixinIntersectionIsValidbaseType.ts, 0, 79)) + + init(...args: any[]): void; +>init : Symbol(Initable.init, Decl(mixinIntersectionIsValidbaseType.ts, 2, 27)) +>args : Symbol(args, Decl(mixinIntersectionIsValidbaseType.ts, 3, 9)) +} + +/** + * Plain mixin where the superclass must be Initable + */ +export const Serializable = & Initable>( +>Serializable : Symbol(Serializable, Decl(mixinIntersectionIsValidbaseType.ts, 9, 12)) +>K : Symbol(K, Decl(mixinIntersectionIsValidbaseType.ts, 9, 29)) +>Constructor : Symbol(Constructor, Decl(mixinIntersectionIsValidbaseType.ts, 0, 0)) +>Initable : Symbol(Initable, Decl(mixinIntersectionIsValidbaseType.ts, 0, 79)) +>Initable : Symbol(Initable, Decl(mixinIntersectionIsValidbaseType.ts, 0, 79)) + + SuperClass: K +>SuperClass : Symbol(SuperClass, Decl(mixinIntersectionIsValidbaseType.ts, 9, 73)) +>K : Symbol(K, Decl(mixinIntersectionIsValidbaseType.ts, 9, 29)) + +) => { + const LocalMixin = (InnerSuperClass: K) => { +>LocalMixin : Symbol(LocalMixin, Decl(mixinIntersectionIsValidbaseType.ts, 12, 9)) +>InnerSuperClass : Symbol(InnerSuperClass, Decl(mixinIntersectionIsValidbaseType.ts, 12, 24)) +>K : Symbol(K, Decl(mixinIntersectionIsValidbaseType.ts, 9, 29)) + + return class SerializableLocal extends InnerSuperClass { +>SerializableLocal : Symbol(SerializableLocal, Decl(mixinIntersectionIsValidbaseType.ts, 13, 14)) +>InnerSuperClass : Symbol(InnerSuperClass, Decl(mixinIntersectionIsValidbaseType.ts, 12, 24)) + } + }; + let ResultClass = LocalMixin(SuperClass); +>ResultClass : Symbol(ResultClass, Decl(mixinIntersectionIsValidbaseType.ts, 16, 7)) +>LocalMixin : Symbol(LocalMixin, Decl(mixinIntersectionIsValidbaseType.ts, 12, 9)) +>SuperClass : Symbol(SuperClass, Decl(mixinIntersectionIsValidbaseType.ts, 9, 73)) + + return ResultClass; +>ResultClass : Symbol(ResultClass, Decl(mixinIntersectionIsValidbaseType.ts, 16, 7)) + +}; + +const AMixin = & Initable>(SuperClass: K) => { +>AMixin : Symbol(AMixin, Decl(mixinIntersectionIsValidbaseType.ts, 20, 5)) +>K : Symbol(K, Decl(mixinIntersectionIsValidbaseType.ts, 20, 16)) +>Constructor : Symbol(Constructor, Decl(mixinIntersectionIsValidbaseType.ts, 0, 0)) +>Initable : Symbol(Initable, Decl(mixinIntersectionIsValidbaseType.ts, 0, 79)) +>Initable : Symbol(Initable, Decl(mixinIntersectionIsValidbaseType.ts, 0, 79)) +>SuperClass : Symbol(SuperClass, Decl(mixinIntersectionIsValidbaseType.ts, 20, 60)) +>K : Symbol(K, Decl(mixinIntersectionIsValidbaseType.ts, 20, 16)) + + let SomeHowOkay = class A extends SuperClass { +>SomeHowOkay : Symbol(SomeHowOkay, Decl(mixinIntersectionIsValidbaseType.ts, 21, 7)) +>A : Symbol(A, Decl(mixinIntersectionIsValidbaseType.ts, 21, 21)) +>SuperClass : Symbol(SuperClass, Decl(mixinIntersectionIsValidbaseType.ts, 20, 60)) + + }; + + let SomeHowNotOkay = class A extends Serializable(SuperClass) { +>SomeHowNotOkay : Symbol(SomeHowNotOkay, Decl(mixinIntersectionIsValidbaseType.ts, 24, 7)) +>A : Symbol(A, Decl(mixinIntersectionIsValidbaseType.ts, 24, 24)) +>Serializable : Symbol(Serializable, Decl(mixinIntersectionIsValidbaseType.ts, 9, 12)) +>SuperClass : Symbol(SuperClass, Decl(mixinIntersectionIsValidbaseType.ts, 20, 60)) + + }; +}; diff --git a/tests/baselines/reference/mixinIntersectionIsValidbaseType.types b/tests/baselines/reference/mixinIntersectionIsValidbaseType.types new file mode 100644 index 00000000000..c828188dcd6 --- /dev/null +++ b/tests/baselines/reference/mixinIntersectionIsValidbaseType.types @@ -0,0 +1,67 @@ +=== tests/cases/compiler/mixinIntersectionIsValidbaseType.ts === +export type Constructor = new (...args: any[]) => T; +>Constructor : Constructor +>args : any[] + +export interface Initable { + init(...args: any[]): void; +>init : (...args: any[]) => void +>args : any[] +} + +/** + * Plain mixin where the superclass must be Initable + */ +export const Serializable = & Initable>( +>Serializable : & Initable>(SuperClass: K) => { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +> & Initable>( SuperClass: K) => { const LocalMixin = (InnerSuperClass: K) => { return class SerializableLocal extends InnerSuperClass { } }; let ResultClass = LocalMixin(SuperClass); return ResultClass;} : & Initable>(SuperClass: K) => { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K + + SuperClass: K +>SuperClass : K + +) => { + const LocalMixin = (InnerSuperClass: K) => { +>LocalMixin : (InnerSuperClass: K) => { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +>(InnerSuperClass: K) => { return class SerializableLocal extends InnerSuperClass { } } : (InnerSuperClass: K) => { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +>InnerSuperClass : K + + return class SerializableLocal extends InnerSuperClass { +>class SerializableLocal extends InnerSuperClass { } : { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +>SerializableLocal : { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +>InnerSuperClass : Initable + } + }; + let ResultClass = LocalMixin(SuperClass); +>ResultClass : { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +>LocalMixin(SuperClass) : { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +>LocalMixin : (InnerSuperClass: K) => { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +>SuperClass : K + + return ResultClass; +>ResultClass : { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K + +}; + +const AMixin = & Initable>(SuperClass: K) => { +>AMixin : & Initable>(SuperClass: K) => void +> & Initable>(SuperClass: K) => { let SomeHowOkay = class A extends SuperClass { }; let SomeHowNotOkay = class A extends Serializable(SuperClass) { };} : & Initable>(SuperClass: K) => void +>SuperClass : K + + let SomeHowOkay = class A extends SuperClass { +>SomeHowOkay : { new (...args: any[]): A; prototype: AMixin.A; init(...args: any[]): void; } & K +>class A extends SuperClass { } : { new (...args: any[]): A; prototype: AMixin.A; init(...args: any[]): void; } & K +>A : { new (...args: any[]): A; prototype: AMixin.A; init(...args: any[]): void; } & K +>SuperClass : Initable + + }; + + let SomeHowNotOkay = class A extends Serializable(SuperClass) { +>SomeHowNotOkay : { new (...args: any[]): A; prototype: AMixin.A; init: (...args: any[]) => void; } & K +>class A extends Serializable(SuperClass) { } : { new (...args: any[]): A; prototype: AMixin.A; init: (...args: any[]) => void; } & K +>A : { new (...args: any[]): A; prototype: AMixin.A; init: (...args: any[]) => void; } & K +>Serializable(SuperClass) : Serializable.SerializableLocal & Initable +>Serializable : & Initable>(SuperClass: K) => { new (...args: any[]): SerializableLocal; prototype: Serializable.SerializableLocal; init(...args: any[]): void; } & K +>SuperClass : K + + }; +}; diff --git a/tests/cases/compiler/mixinIntersectionIsValidbaseType.ts b/tests/cases/compiler/mixinIntersectionIsValidbaseType.ts new file mode 100644 index 00000000000..4f446a9db8d --- /dev/null +++ b/tests/cases/compiler/mixinIntersectionIsValidbaseType.ts @@ -0,0 +1,27 @@ +export type Constructor = new (...args: any[]) => T; + +export interface Initable { + init(...args: any[]): void; +} + +/** + * Plain mixin where the superclass must be Initable + */ +export const Serializable = & Initable>( + SuperClass: K +) => { + const LocalMixin = (InnerSuperClass: K) => { + return class SerializableLocal extends InnerSuperClass { + } + }; + let ResultClass = LocalMixin(SuperClass); + return ResultClass; +}; + +const AMixin = & Initable>(SuperClass: K) => { + let SomeHowOkay = class A extends SuperClass { + }; + + let SomeHowNotOkay = class A extends Serializable(SuperClass) { + }; +}; \ No newline at end of file From 26caa3793e310e271ddee8adc1804486e5b0749f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Sep 2019 16:08:44 -0700 Subject: [PATCH 094/100] Introduce flattened error reporting for properties, call signatures, and construct signatures (#33473) * Introduce flattened error reporting for properties, call signatures, and construct signatures * Update message, specialize output for argument-less signatures * Skip leading signature incompatability flattening * Add return type specialized message --- scripts/processDiagnosticMessages.ts | 10 +- src/compiler/checker.ts | 226 +++++++++++++++--- src/compiler/diagnosticMessages.json | 29 +++ src/compiler/types.ts | 2 + .../reference/arrayLiterals3.errors.txt | 14 +- ...typeIsAssignableToReadonlyArray.errors.txt | 14 +- .../assignFromBooleanInterface2.errors.txt | 10 +- .../asyncFunctionDeclaration15_es5.errors.txt | 14 +- .../reference/bigintWithLib.errors.txt | 28 +-- .../reference/booleanAssignment.errors.txt | 10 +- ...atureAssignabilityInInheritance.errors.txt | 24 +- ...tureAssignabilityInInheritance3.errors.txt | 32 ++- .../checkJsxChildrenCanBeTupleType.errors.txt | 12 +- .../complexRecursiveCollections.errors.txt | 42 ++-- ...atureAssignabilityInInheritance.errors.txt | 24 +- ...tureAssignabilityInInheritance3.errors.txt | 32 ++- .../reference/covariantCallbacks.errors.txt | 10 +- .../reference/decoratorCallGeneric.errors.txt | 10 +- ...heckingWhenTargetIsIntersection.errors.txt | 16 +- ...stedAssignabilityErrorsCombined.errors.txt | 32 +++ ...deeplyNestedAssignabilityErrorsCombined.js | 36 +++ ...yNestedAssignabilityErrorsCombined.symbols | 63 +++++ ...plyNestedAssignabilityErrorsCombined.types | 95 ++++++++ ...oratedErrorsOnNullableTargets01.errors.txt | 16 +- ...AnnotationAndInvalidInitializer.errors.txt | 10 +- ...endAndImplementTheSameBaseType2.errors.txt | 10 +- tests/baselines/reference/for-of39.errors.txt | 40 ++-- .../reference/generatorTypeCheck25.errors.txt | 36 ++- .../reference/generatorTypeCheck63.errors.txt | 26 +- .../reference/generatorTypeCheck8.errors.txt | 22 +- .../baselines/reference/generics4.errors.txt | 10 +- .../reference/incompatibleTypes.errors.txt | 20 +- ...nheritedModuleMembersForClodule.errors.txt | 10 +- ...interfaceThatHidesBaseProperty2.errors.txt | 12 +- .../interfaceWithMultipleBaseTypes.errors.txt | 36 +-- ...interfaceWithMultipleBaseTypes2.errors.txt | 12 +- ...nvariantGenericErrorElaboration.errors.txt | 25 +- .../iterableArrayPattern28.errors.txt | 40 ++-- .../iteratorSpreadInArray6.errors.txt | 14 +- .../reference/mergedDeclarations7.errors.txt | 10 +- .../reference/multiLineErrors.errors.txt | 12 +- .../mutuallyRecursiveCallbacks.errors.txt | 10 +- ...nestedCallbackErrorNotFlattened.errors.txt | 20 ++ .../nestedCallbackErrorNotFlattened.js | 11 + .../nestedCallbackErrorNotFlattened.symbols | 27 +++ .../nestedCallbackErrorNotFlattened.types | 18 ++ ...RecursiveArraysOrObjectsError01.errors.txt | 42 ++-- ...MembersOfObjectAssignmentCompat.errors.txt | 30 +-- ...embersOfObjectAssignmentCompat2.errors.txt | 62 ++--- .../reference/promisePermutations.errors.txt | 8 +- .../reference/promisePermutations2.errors.txt | 8 +- .../reference/promisePermutations3.errors.txt | 8 +- .../reference/promiseTypeInference.errors.txt | 14 +- .../strictFunctionTypesErrors.errors.txt | 10 +- ...aturesWithSpecializedSignatures.errors.txt | 24 +- ...aturesWithSpecializedSignatures.errors.txt | 24 +- ...ignaturesWithOptionalParameters.errors.txt | 84 +++---- ...ignaturesWithOptionalParameters.errors.txt | 84 +++---- ...peParameterArgumentEquivalence5.errors.txt | 8 +- .../types.asyncGenerators.es2018.2.errors.txt | 98 +++----- ...deeplyNestedAssignabilityErrorsCombined.ts | 15 ++ .../nestedCallbackErrorNotFlattened.ts | 7 + 62 files changed, 1023 insertions(+), 735 deletions(-) create mode 100644 tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.errors.txt create mode 100644 tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.js create mode 100644 tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.symbols create mode 100644 tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.types create mode 100644 tests/baselines/reference/nestedCallbackErrorNotFlattened.errors.txt create mode 100644 tests/baselines/reference/nestedCallbackErrorNotFlattened.js create mode 100644 tests/baselines/reference/nestedCallbackErrorNotFlattened.symbols create mode 100644 tests/baselines/reference/nestedCallbackErrorNotFlattened.types create mode 100644 tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts create mode 100644 tests/cases/compiler/nestedCallbackErrorNotFlattened.ts diff --git a/scripts/processDiagnosticMessages.ts b/scripts/processDiagnosticMessages.ts index 4bdf3ca0178..7577707340a 100644 --- a/scripts/processDiagnosticMessages.ts +++ b/scripts/processDiagnosticMessages.ts @@ -6,6 +6,7 @@ interface DiagnosticDetails { code: number; reportsUnnecessary?: {}; isEarly?: boolean; + elidedInCompatabilityPyramid?: boolean; } type InputDiagnosticMessageTable = Map; @@ -63,14 +64,15 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, inputFil "// generated from '" + inputFilePathRel + "' by '" + thisFilePathRel.replace(/\\/g, "/") + "'\r\n" + "/* @internal */\r\n" + "namespace ts {\r\n" + - " function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}): DiagnosticMessage {\r\n" + - " return { code, category, key, message, reportsUnnecessary };\r\n" + + " function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}, elidedInCompatabilityPyramid?: boolean): DiagnosticMessage {\r\n" + + " return { code, category, key, message, reportsUnnecessary, elidedInCompatabilityPyramid };\r\n" + " }\r\n" + " export const Diagnostics = {\r\n"; - messageTable.forEach(({ code, category, reportsUnnecessary }, name) => { + messageTable.forEach(({ code, category, reportsUnnecessary, elidedInCompatabilityPyramid }, name) => { const propName = convertPropertyName(name); const argReportsUnnecessary = reportsUnnecessary ? `, /*reportsUnnecessary*/ ${reportsUnnecessary}` : ""; - result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}),\r\n`; + const argElidedInCompatabilityPyramid = elidedInCompatabilityPyramid ? `${!reportsUnnecessary ? ", /*reportsUnnecessary*/ undefined" : ""}, /*elidedInCompatabilityPyramid*/ ${elidedInCompatabilityPyramid}` : ""; + result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}${argElidedInCompatabilityPyramid}),\r\n`; }); result += " };\r\n}"; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e29f46f2dec..de5c3b5b358 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12329,7 +12329,7 @@ namespace ts { target: Signature, ignoreReturnTypes: boolean): boolean { return compareSignaturesRelated(source, target, CallbackCheck.None, ignoreReturnTypes, /*reportErrors*/ false, - /*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False; + /*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False; } type ErrorReporter = (message: DiagnosticMessage, arg0?: string, arg1?: string) => void; @@ -12352,6 +12352,7 @@ namespace ts { ignoreReturnTypes: boolean, reportErrors: boolean, errorReporter: ErrorReporter | undefined, + incompatibleErrorReporter: ((source: Type, target: Type) => void) | undefined, compareTypes: TypeComparer): Ternary { // TODO (drosen): De-duplicate code between related functions. if (source === target) { @@ -12422,7 +12423,7 @@ namespace ts { (getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable); const related = callbacks ? // TODO: GH#18217 It will work if they're both `undefined`, but not if only one is - compareSignaturesRelated(targetSig!, sourceSig!, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) : + compareSignaturesRelated(targetSig!, sourceSig!, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, incompatibleErrorReporter, compareTypes) : !callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors); if (!related) { if (reportErrors) { @@ -12468,6 +12469,9 @@ namespace ts { // wouldn't be co-variant for T without this rule. result &= callbackCheck === CallbackCheck.Bivariant && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) || compareTypes(sourceReturnType, targetReturnType, reportErrors); + if (!result && reportErrors && incompatibleErrorReporter) { + incompatibleErrorReporter(sourceReturnType, targetReturnType); + } } } @@ -12677,11 +12681,16 @@ namespace ts { let depth = 0; let expandingFlags = ExpandingFlags.None; let overflow = false; - let overrideNextErrorInfo: DiagnosticMessageChain | undefined; + let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid + let lastSkippedInfo: [Type, Type] | undefined; + let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] = []; Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); const result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage); + if (incompatibleStack.length) { + reportIncompatibleStack(); + } if (overflow) { const diag = error(errorNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target)); if (errorOutputContainer) { @@ -12726,8 +12735,134 @@ namespace ts { } return result !== Ternary.False; + function resetErrorInfo(saved: ReturnType) { + errorInfo = saved.errorInfo; + lastSkippedInfo = saved.lastSkippedInfo; + incompatibleStack = saved.incompatibleStack; + overrideNextErrorInfo = saved.overrideNextErrorInfo; + relatedInfo = saved.relatedInfo; + } + + function captureErrorCalculationState() { + return { + errorInfo, + lastSkippedInfo, + incompatibleStack: incompatibleStack.slice(), + overrideNextErrorInfo, + relatedInfo: !relatedInfo ? undefined : relatedInfo.slice() as ([DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined) + }; + } + + function reportIncompatibleError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) { + overrideNextErrorInfo++; // Suppress the next relation error + lastSkippedInfo = undefined; // Reset skipped info cache + incompatibleStack.push([message, arg0, arg1, arg2, arg3]); + } + + function reportIncompatibleStack() { + const stack = incompatibleStack; + incompatibleStack = []; + const info = lastSkippedInfo; + lastSkippedInfo = undefined; + if (stack.length === 1) { + reportError(...stack[0]); + if (info) { + // Actually do the last relation error + reportRelationError(/*headMessage*/ undefined, ...info); + } + return; + } + // The first error will be the innermost, while the last will be the outermost - so by popping off the end, + // we can build from left to right + let path = ""; + const secondaryRootErrors: typeof incompatibleStack = []; + while (stack.length) { + const [msg, ...args] = stack.pop()!; + switch (msg.code) { + case Diagnostics.Types_of_property_0_are_incompatible.code: { + // Parenthesize a `new` if there is one + if (path.indexOf("new ") === 0) { + path = `(${path})`; + } + const str = "" + args[0]; + // If leading, just print back the arg (irrespective of if it's a valid identifier) + if (path.length === 0) { + path = `${str}`; + } + // Otherwise write a dotted name if possible + else if (isIdentifierText(str, compilerOptions.target)) { + path = `${path}.${str}`; + } + // Failing that, check if the name is already a computed name + else if (str[0] === "[" && str[str.length - 1] === "]") { + path = `${path}${str}`; + } + // And finally write out a computed name as a last resort + else { + path = `${path}[${str}]`; + } + break; + } + case Diagnostics.Call_signature_return_types_0_and_1_are_incompatible.code: + case Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code: + case Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code: + case Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code: { + if (path.length === 0) { + // Don't flatten signature compatability errors at the start of a chain - instead prefer + // to unify (the with no arguments bit is excessive for printback) and print them back + let mappedMsg = msg; + if (msg.code === Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) { + mappedMsg = Diagnostics.Call_signature_return_types_0_and_1_are_incompatible; + } + else if (msg.code === Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) { + mappedMsg = Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible; + } + secondaryRootErrors.unshift([mappedMsg, args[0], args[1]]); + } + else { + const prefix = (msg.code === Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code || + msg.code === Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) + ? "new " + : ""; + const params = (msg.code === Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code || + msg.code === Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) + ? "" + : "..."; + path = `${prefix}${path}(${params})`; + } + break; + } + default: + return Debug.fail(`Unhandled Diagnostic: ${msg.code}`); + } + } + if (path) { + reportError(path[path.length - 1] === ")" + ? Diagnostics.The_types_returned_by_0_are_incompatible_between_these_types + : Diagnostics.The_types_of_0_are_incompatible_between_these_types, + path + ); + } + else { + // Remove the innermost secondary error as it will duplicate the error already reported by `reportRelationError` on entry + secondaryRootErrors.shift(); + } + for (const [msg, ...args] of secondaryRootErrors) { + const originalValue = msg.elidedInCompatabilityPyramid; + msg.elidedInCompatabilityPyramid = false; // Teporarily override elision to ensure error is reported + reportError(msg, ...args); + msg.elidedInCompatabilityPyramid = originalValue; + } + if (info) { + // Actually do the last relation error + reportRelationError(/*headMessage*/ undefined, ...info); + } + } + function reportError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { Debug.assert(!!errorNode); + if (incompatibleStack.length) reportIncompatibleStack(); + if (message.elidedInCompatabilityPyramid) return; errorInfo = chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2, arg3); } @@ -12742,6 +12877,7 @@ namespace ts { } function reportRelationError(message: DiagnosticMessage | undefined, source: Type, target: Type) { + if (incompatibleStack.length) reportIncompatibleStack(); const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target); if (target.flags & TypeFlags.TypeParameter && target.immediateBaseConstraint !== undefined && isTypeAssignableTo(source, target.immediateBaseConstraint)) { @@ -12899,7 +13035,7 @@ namespace ts { } let result = Ternary.False; - const saveErrorInfo = errorInfo; + const saveErrorInfo = captureErrorCalculationState(); let isIntersectionConstituent = !!isApparentIntersectionConstituent; // Note that these checks are specifically ordered to produce correct results. In particular, @@ -12949,7 +13085,7 @@ namespace ts { } if (!result && (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable)) { if (result = recursiveTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent)) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); } } } @@ -12966,19 +13102,21 @@ namespace ts { const constraint = getUnionConstraintOfIntersection(source, !!(target.flags & TypeFlags.Union)); if (constraint) { if (result = isRelatedTo(constraint, target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); } } } if (!result && reportErrors) { - let maybeSuppress = overrideNextErrorInfo; - overrideNextErrorInfo = undefined; + let maybeSuppress = overrideNextErrorInfo > 0; + if (maybeSuppress) { + overrideNextErrorInfo--; + } if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { const currentError = errorInfo; tryElaborateArrayLikeErrors(source, target, reportErrors); if (errorInfo !== currentError) { - maybeSuppress = errorInfo; + maybeSuppress = !!errorInfo; } } if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Primitive) { @@ -12998,6 +13136,7 @@ namespace ts { } } if (!headMessage && maybeSuppress) { + lastSkippedInfo = [source, target]; // Used by, eg, missing property checking to replace the top-level message with a more informative one return result; } @@ -13439,7 +13578,7 @@ namespace ts { let result: Ternary; let originalErrorInfo: DiagnosticMessageChain | undefined; let varianceCheckFailed = false; - const saveErrorInfo = errorInfo; + const saveErrorInfo = captureErrorCalculationState(); // We limit alias variance probing to only object and conditional types since their alias behavior // is more predictable than other, interned types, which may or may not have an alias depending on @@ -13531,7 +13670,7 @@ namespace ts { } } originalErrorInfo = errorInfo; - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); } } } @@ -13543,7 +13682,7 @@ namespace ts { result &= isRelatedTo((source).indexType, (target).indexType, reportErrors); } if (result) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } } @@ -13552,25 +13691,25 @@ namespace ts { if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) { // A type variable with no constraint is not related to the non-primitive object type. if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } } // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } } } else if (source.flags & TypeFlags.Index) { if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } } @@ -13595,7 +13734,7 @@ namespace ts { result &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), reportErrors); } if (result) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } } @@ -13604,14 +13743,14 @@ namespace ts { const distributiveConstraint = getConstraintOfDistributiveConditionalType(source); if (distributiveConstraint) { if (result = isRelatedTo(distributiveConstraint, target, reportErrors)) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } } const defaultConstraint = getDefaultConstraintOfConditionalType(source); if (defaultConstraint) { if (result = isRelatedTo(defaultConstraint, target, reportErrors)) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } } @@ -13625,7 +13764,7 @@ namespace ts { if (isGenericMappedType(target)) { if (isGenericMappedType(source)) { if (result = mappedTypeRelatedTo(source, target, reportErrors)) { - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return result; } } @@ -13671,7 +13810,7 @@ namespace ts { // relates to X. Thus, we include intersection types on the source side here. if (source.flags & (TypeFlags.Object | TypeFlags.Intersection) && target.flags & TypeFlags.Object) { // Report structural errors only if we haven't reported any errors yet - const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !sourceIsPrimitive; + const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo.errorInfo && !sourceIsPrimitive; result = propertiesRelatedTo(source, target, reportStructuralErrors, /*excludedProperties*/ undefined, isIntersectionConstituent); if (result) { result &= signaturesRelatedTo(source, target, SignatureKind.Call, reportStructuralErrors); @@ -13686,7 +13825,7 @@ namespace ts { } } if (varianceCheckFailed && result) { - errorInfo = originalErrorInfo || errorInfo || saveErrorInfo; // Use variance error (there is no structural one) and return false + errorInfo = originalErrorInfo || errorInfo || saveErrorInfo.errorInfo; // Use variance error (there is no structural one) and return false } else if (result) { return result; @@ -13718,7 +13857,7 @@ namespace ts { // We elide the variance-based error elaborations, since those might not be too helpful, since we'll potentially // be assuming identity of the type parameter. originalErrorInfo = undefined; - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); return undefined; } const allowStructuralFallback = targetTypeArguments && hasCovariantVoidArgument(targetTypeArguments, variances); @@ -13746,7 +13885,7 @@ namespace ts { // comparison unexpectedly succeeds. This can happen when the structural comparison result // is a Ternary.Maybe for example caused by the recursion depth limiter. originalErrorInfo = errorInfo; - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); } } } @@ -13980,7 +14119,7 @@ namespace ts { const related = isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, isIntersectionConstituent); if (!related) { if (reportErrors) { - reportError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp)); + reportIncompatibleError(Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp)); } return Ternary.False; } @@ -14022,8 +14161,8 @@ namespace ts { if (length(unmatchedProperty.declarations)) { associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations[0], Diagnostics._0_is_declared_here, propName)); } - if (shouldSkipElaboration) { - overrideNextErrorInfo = errorInfo; + if (shouldSkipElaboration && errorInfo) { + overrideNextErrorInfo++; } } else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) { @@ -14033,8 +14172,8 @@ namespace ts { else { reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", ")); } - if (shouldSkipElaboration) { - overrideNextErrorInfo = errorInfo; + if (shouldSkipElaboration && errorInfo) { + overrideNextErrorInfo++; } } // ELSE: No array like or unmatched property error - just issue top level error (errorInfo = undefined) @@ -14157,7 +14296,8 @@ namespace ts { } let result = Ternary.True; - const saveErrorInfo = errorInfo; + const saveErrorInfo = captureErrorCalculationState(); + const incompatibleReporter = kind === SignatureKind.Construct ? reportIncompatibleConstructSignatureReturn : reportIncompatibleCallSignatureReturn; if (getObjectFlags(source) & ObjectFlags.Instantiated && getObjectFlags(target) & ObjectFlags.Instantiated && source.symbol === target.symbol) { // We have instantiations of the same anonymous type (which typically will be the type of a @@ -14165,7 +14305,7 @@ namespace ts { // of the much more expensive N * M comparison matrix we explore below. We erase type parameters // as they are known to always be the same. for (let i = 0; i < targetSignatures.length; i++) { - const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors); + const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors, incompatibleReporter(sourceSignatures[i], targetSignatures[i])); if (!related) { return Ternary.False; } @@ -14179,17 +14319,17 @@ namespace ts { // this regardless of the number of signatures, but the potential costs are prohibitive due // to the quadratic nature of the logic below. const eraseGenerics = relation === comparableRelation || !!compilerOptions.noStrictGenericChecks; - result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors); + result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors, incompatibleReporter(sourceSignatures[0], targetSignatures[0])); } else { outer: for (const t of targetSignatures) { // Only elaborate errors from the first failure let shouldElaborateErrors = reportErrors; for (const s of sourceSignatures) { - const related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors); + const related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors, incompatibleReporter(s, t)); if (related) { result &= related; - errorInfo = saveErrorInfo; + resetErrorInfo(saveErrorInfo); continue outer; } shouldElaborateErrors = false; @@ -14206,12 +14346,26 @@ namespace ts { return result; } + function reportIncompatibleCallSignatureReturn(siga: Signature, sigb: Signature) { + if (siga.parameters.length === 0 && sigb.parameters.length === 0) { + return (source: Type, target: Type) => reportIncompatibleError(Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); + } + return (source: Type, target: Type) => reportIncompatibleError(Diagnostics.Call_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); + } + + function reportIncompatibleConstructSignatureReturn(siga: Signature, sigb: Signature) { + if (siga.parameters.length === 0 && sigb.parameters.length === 0) { + return (source: Type, target: Type) => reportIncompatibleError(Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); + } + return (source: Type, target: Type) => reportIncompatibleError(Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); + } + /** * See signatureAssignableTo, compareSignaturesIdentical */ - function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean): Ternary { + function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean, incompatibleReporter: (source: Type, target: Type) => void): Ternary { return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, - CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo); + CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, incompatibleReporter, isRelatedTo); } function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 44bba361bbc..3b219b37de4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1040,6 +1040,35 @@ "code": 1357 }, + "The types of '{0}' are incompatible between these types.": { + "category": "Error", + "code": 2200 + }, + "The types returned by '{0}' are incompatible between these types.": { + "category": "Error", + "code": 2201 + }, + "Call signature return types '{0}' and '{1}' are incompatible.": { + "category": "Error", + "code": 2202, + "elidedInCompatabilityPyramid": true + }, + "Construct signature return types '{0}' and '{1}' are incompatible.": { + "category": "Error", + "code": 2203, + "elidedInCompatabilityPyramid": true + }, + "Call signatures with no arguments have incompatible return types '{0}' and '{1}'.": { + "category": "Error", + "code": 2204, + "elidedInCompatabilityPyramid": true + }, + "Construct signatures with no arguments have incompatible return types '{0}' and '{1}'.": { + "category": "Error", + "code": 2205, + "elidedInCompatabilityPyramid": true + }, + "Duplicate identifier '{0}'.": { "category": "Error", "code": 2300 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e20518ed119..eb568ed5cff 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4631,6 +4631,8 @@ namespace ts { code: number; message: string; reportsUnnecessary?: {}; + /* @internal */ + elidedInCompatabilityPyramid?: boolean; } /** diff --git a/tests/baselines/reference/arrayLiterals3.errors.txt b/tests/baselines/reference/arrayLiterals3.errors.txt index 4d398978c96..5f592b74f3e 100644 --- a/tests/baselines/reference/arrayLiterals3.errors.txt +++ b/tests/baselines/reference/arrayLiterals3.errors.txt @@ -8,10 +8,9 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(17,5): error tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(32,5): error TS2739: Type '(number[] | string[])[]' is missing the following properties from type 'tup': 0, 1 tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(33,5): error TS2739: Type 'number[]' is missing the following properties from type '[number, number, number]': 0, 1, 2 tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error TS2322: Type '(string | number)[]' is not assignable to type 'myArray'. - Types of property 'pop' are incompatible. - Type '() => string | number' is not assignable to type '() => Number'. - Type 'string | number' is not assignable to type 'Number'. - Type 'string' is not assignable to type 'Number'. + The types returned by 'pop()' are incompatible between these types. + Type 'string | number' is not assignable to type 'Number'. + Type 'string' is not assignable to type 'Number'. ==== tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts (8 errors) ==== @@ -67,8 +66,7 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error var c2: myArray = [...temp1, ...temp]; // Error cannot assign (number|string)[] to number[] ~~ !!! error TS2322: Type '(string | number)[]' is not assignable to type 'myArray'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => string | number' is not assignable to type '() => Number'. -!!! error TS2322: Type 'string | number' is not assignable to type 'Number'. -!!! error TS2322: Type 'string' is not assignable to type 'Number'. +!!! error TS2322: The types returned by 'pop()' are incompatible between these types. +!!! error TS2322: Type 'string | number' is not assignable to type 'Number'. +!!! error TS2322: Type 'string' is not assignable to type 'Number'. \ No newline at end of file diff --git a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt index 63d3a6f7b64..66b3c2c8691 100644 --- a/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt +++ b/tests/baselines/reference/arrayOfSubtypeIsAssignableToReadonlyArray.errors.txt @@ -1,10 +1,9 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'readonly B[]'. Property 'b' is missing in type 'A' but required in type 'B'. tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C' is not assignable to type 'readonly B[]'. - Types of property 'concat' are incompatible. - Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. - Type 'A[]' is not assignable to type 'B[]'. - Type 'A' is not assignable to type 'B'. + The types returned by 'concat(...)' are incompatible between these types. + Type 'A[]' is not assignable to type 'B[]'. + Type 'A' is not assignable to type 'B'. ==== tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts (2 errors) ==== @@ -32,8 +31,7 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T rrb = cra; // error: 'A' is not assignable to 'B' ~~~ !!! error TS2322: Type 'C' is not assignable to type 'readonly B[]'. -!!! error TS2322: Types of property 'concat' are incompatible. -!!! error TS2322: Type '{ (...items: ConcatArray[]): A[]; (...items: (A | ConcatArray)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray[]): B[]; (...items: (B | ConcatArray)[]): B[]; }'. -!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. -!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: The types returned by 'concat(...)' are incompatible between these types. +!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. \ No newline at end of file diff --git a/tests/baselines/reference/assignFromBooleanInterface2.errors.txt b/tests/baselines/reference/assignFromBooleanInterface2.errors.txt index 6c7ebbe5ee8..ba8b2f5a9c9 100644 --- a/tests/baselines/reference/assignFromBooleanInterface2.errors.txt +++ b/tests/baselines/reference/assignFromBooleanInterface2.errors.txt @@ -1,7 +1,6 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(14,1): error TS2322: Type 'NotBoolean' is not assignable to type 'Boolean'. - Types of property 'valueOf' are incompatible. - Type '() => Object' is not assignable to type '() => boolean'. - Type 'Object' is not assignable to type 'boolean'. + The types returned by 'valueOf()' are incompatible between these types. + Type 'Object' is not assignable to type 'boolean'. tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(19,1): error TS2322: Type 'Boolean' is not assignable to type 'boolean'. 'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible. tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts(20,1): error TS2322: Type 'NotBoolean' is not assignable to type 'boolean'. @@ -24,9 +23,8 @@ tests/cases/conformance/types/primitives/boolean/assignFromBooleanInterface2.ts( a = b; ~ !!! error TS2322: Type 'NotBoolean' is not assignable to type 'Boolean'. -!!! error TS2322: Types of property 'valueOf' are incompatible. -!!! error TS2322: Type '() => Object' is not assignable to type '() => boolean'. -!!! error TS2322: Type 'Object' is not assignable to type 'boolean'. +!!! error TS2322: The types returned by 'valueOf()' are incompatible between these types. +!!! error TS2322: Type 'Object' is not assignable to type 'boolean'. b = a; b = x; diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt index 6b4b0a71c6f..7e3595ec6f4 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt @@ -5,10 +5,9 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(8,23): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(9,23): error TS1055: Type 'PromiseLike' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. - Type 'Thenable' is not assignable to type 'PromiseLike'. - Types of property 'then' are incompatible. - Type '() => void' is not assignable to type '(onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. - Type 'void' is not assignable to type 'PromiseLike'. + Construct signature return types 'Thenable' and 'PromiseLike' are incompatible. + The types returned by 'then(...)' are incompatible between these types. + Type 'void' is not assignable to type 'PromiseLike'. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(17,16): error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(23,25): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member. @@ -38,10 +37,9 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 async function fn6(): Thenable { } // error ~~~~~~~~ !!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. -!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike'. -!!! error TS1055: Types of property 'then' are incompatible. -!!! error TS1055: Type '() => void' is not assignable to type '(onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. -!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike'. +!!! error TS1055: Construct signature return types 'Thenable' and 'PromiseLike' are incompatible. +!!! error TS1055: The types returned by 'then(...)' are incompatible between these types. +!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike'. async function fn7() { return; } // valid: Promise async function fn8() { return 1; } // valid: Promise async function fn9() { return null; } // valid: Promise diff --git a/tests/baselines/reference/bigintWithLib.errors.txt b/tests/baselines/reference/bigintWithLib.errors.txt index b4c9f65cf9c..fb54c2a530b 100644 --- a/tests/baselines/reference/bigintWithLib.errors.txt +++ b/tests/baselines/reference/bigintWithLib.errors.txt @@ -4,15 +4,11 @@ tests/cases/compiler/bigintWithLib.ts(16,33): error TS2769: No overload matches Argument of type 'number[]' is not assignable to parameter of type 'number'. Overload 2 of 3, '(array: Iterable): BigInt64Array', gave the following error. Argument of type 'number[]' is not assignable to parameter of type 'Iterable'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator' is not assignable to type '() => Iterator'. - Type 'IterableIterator' is not assignable to type 'Iterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. - Type 'IteratorResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. - Type 'number' is not assignable to type 'bigint'. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. + Type 'number' is not assignable to type 'bigint'. Overload 3 of 3, '(buffer: ArrayBuffer | SharedArrayBuffer, byteOffset?: number, length?: number): BigInt64Array', gave the following error. Argument of type 'number[]' is not assignable to parameter of type 'ArrayBuffer | SharedArrayBuffer'. Type 'number[]' is missing the following properties from type 'SharedArrayBuffer': byteLength, [Symbol.species], [Symbol.toStringTag] @@ -55,15 +51,11 @@ tests/cases/compiler/bigintWithLib.ts(43,26): error TS2345: Argument of type '12 !!! error TS2769: Argument of type 'number[]' is not assignable to parameter of type 'number'. !!! error TS2769: Overload 2 of 3, '(array: Iterable): BigInt64Array', gave the following error. !!! error TS2769: Argument of type 'number[]' is not assignable to parameter of type 'Iterable'. -!!! error TS2769: Types of property '[Symbol.iterator]' are incompatible. -!!! error TS2769: Type '() => IterableIterator' is not assignable to type '() => Iterator'. -!!! error TS2769: Type 'IterableIterator' is not assignable to type 'Iterator'. -!!! error TS2769: Types of property 'next' are incompatible. -!!! error TS2769: Type '(...args: [] | [undefined]) => IteratorResult' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. -!!! error TS2769: Type 'IteratorResult' is not assignable to type 'IteratorResult'. -!!! error TS2769: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -!!! error TS2769: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -!!! error TS2769: Type 'number' is not assignable to type 'bigint'. +!!! error TS2769: The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. +!!! error TS2769: Type 'IteratorResult' is not assignable to type 'IteratorResult'. +!!! error TS2769: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. +!!! error TS2769: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. +!!! error TS2769: Type 'number' is not assignable to type 'bigint'. !!! error TS2769: Overload 3 of 3, '(buffer: ArrayBuffer | SharedArrayBuffer, byteOffset?: number, length?: number): BigInt64Array', gave the following error. !!! error TS2769: Argument of type 'number[]' is not assignable to parameter of type 'ArrayBuffer | SharedArrayBuffer'. !!! error TS2769: Type 'number[]' is missing the following properties from type 'SharedArrayBuffer': byteLength, [Symbol.species], [Symbol.toStringTag] diff --git a/tests/baselines/reference/booleanAssignment.errors.txt b/tests/baselines/reference/booleanAssignment.errors.txt index fc25fd4007f..8a928c57404 100644 --- a/tests/baselines/reference/booleanAssignment.errors.txt +++ b/tests/baselines/reference/booleanAssignment.errors.txt @@ -1,9 +1,8 @@ tests/cases/compiler/booleanAssignment.ts(2,1): error TS2322: Type '1' is not assignable to type 'Boolean'. tests/cases/compiler/booleanAssignment.ts(3,1): error TS2322: Type '"a"' is not assignable to type 'Boolean'. tests/cases/compiler/booleanAssignment.ts(4,1): error TS2322: Type '{}' is not assignable to type 'Boolean'. - Types of property 'valueOf' are incompatible. - Type '() => Object' is not assignable to type '() => boolean'. - Type 'Object' is not assignable to type 'boolean'. + The types returned by 'valueOf()' are incompatible between these types. + Type 'Object' is not assignable to type 'boolean'. ==== tests/cases/compiler/booleanAssignment.ts (3 errors) ==== @@ -17,9 +16,8 @@ tests/cases/compiler/booleanAssignment.ts(4,1): error TS2322: Type '{}' is not a b = {}; // Error ~ !!! error TS2322: Type '{}' is not assignable to type 'Boolean'. -!!! error TS2322: Types of property 'valueOf' are incompatible. -!!! error TS2322: Type '() => Object' is not assignable to type '() => boolean'. -!!! error TS2322: Type 'Object' is not assignable to type 'boolean'. +!!! error TS2322: The types returned by 'valueOf()' are incompatible between these types. +!!! error TS2322: Type 'Object' is not assignable to type 'boolean'. var o = {}; o = b; // OK diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt index 2ca3bb1aaf0..43589e94370 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt @@ -1,12 +1,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts(57,15): error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. - Types of property 'a' are incompatible. - Type '(x: number) => string' is not assignable to type '(x: number) => number'. - Type 'string' is not assignable to type 'number'. + The types returned by 'a(...)' are incompatible between these types. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts(63,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. - Types of property 'a2' are incompatible. - Type '(x: T) => string' is not assignable to type '(x: T) => T'. - Type 'string' is not assignable to type 'T'. - 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a2(...)' are incompatible between these types. + Type 'string' is not assignable to type 'T'. + 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts (2 errors) ==== @@ -69,9 +67,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign interface I2 extends Base2 { ~~ !!! error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type '(x: number) => string' is not assignable to type '(x: number) => number'. -!!! error TS2430: Type 'string' is not assignable to type 'number'. +!!! error TS2430: The types returned by 'a(...)' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'number'. // N's a: (x: number) => string; // error because base returns non-void; } @@ -80,10 +77,9 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign interface I3 extends Base2 { ~~ !!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type '(x: T) => string' is not assignable to type '(x: T) => T'. -!!! error TS2430: Type 'string' is not assignable to type 'T'. -!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a2(...)' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'T'. +!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. // N's a2: (x: T) => string; // error because base returns non-void; } diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt index 671c09b3d79..287875d44da 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt @@ -27,16 +27,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign Types of property 'a' are incompatible. Type 'string' is not assignable to type 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(100,19): error TS2430: Interface 'I6' incorrectly extends interface 'B'. - Types of property 'a2' are incompatible. - Type '(x: T) => string[]' is not assignable to type '(x: T) => T[]'. - Type 'string[]' is not assignable to type 'T[]'. - Type 'string' is not assignable to type 'T'. - 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a2(...)' are incompatible between these types. + Type 'string[]' is not assignable to type 'T[]'. + Type 'string' is not assignable to type 'T'. + 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(109,19): error TS2430: Interface 'I7' incorrectly extends interface 'C'. - Types of property 'a2' are incompatible. - Type '(x: T) => T[]' is not assignable to type '(x: T) => string[]'. - Type 'T[]' is not assignable to type 'string[]'. - Type 'T' is not assignable to type 'string'. + The types returned by 'a2(...)' are incompatible between these types. + Type 'T[]' is not assignable to type 'string[]'. + Type 'T' is not assignable to type 'string'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts (6 errors) ==== @@ -174,11 +172,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign interface I6 extends B { ~~ !!! error TS2430: Interface 'I6' incorrectly extends interface 'B'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type '(x: T) => string[]' is not assignable to type '(x: T) => T[]'. -!!! error TS2430: Type 'string[]' is not assignable to type 'T[]'. -!!! error TS2430: Type 'string' is not assignable to type 'T'. -!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a2(...)' are incompatible between these types. +!!! error TS2430: Type 'string[]' is not assignable to type 'T[]'. +!!! error TS2430: Type 'string' is not assignable to type 'T'. +!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a2: (x: T) => string[]; // error } @@ -190,10 +187,9 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign interface I7 extends C { ~~ !!! error TS2430: Interface 'I7' incorrectly extends interface 'C'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type '(x: T) => T[]' is not assignable to type '(x: T) => string[]'. -!!! error TS2430: Type 'T[]' is not assignable to type 'string[]'. -!!! error TS2430: Type 'T' is not assignable to type 'string'. +!!! error TS2430: The types returned by 'a2(...)' are incompatible between these types. +!!! error TS2430: Type 'T[]' is not assignable to type 'string[]'. +!!! error TS2430: Type 'T' is not assignable to type 'string'. a2: (x: T) => T[]; // error } } diff --git a/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt b/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt index aeaeb56ea75..0780f4e92c1 100644 --- a/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt @@ -1,10 +1,8 @@ tests/cases/conformance/jsx/checkJsxChildrenCanBeTupleType.tsx(17,18): error TS2769: No overload matches this call. Overload 1 of 2, '(props: Readonly): ResizablePanel', gave the following error. Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. - Types of property 'children' are incompatible. - Type '[Element, Element, Element]' is not assignable to type '[ReactNode, ReactNode]'. - Types of property 'length' are incompatible. - Type '3' is not assignable to type '2'. + The types of 'children.length' are incompatible between these types. + Type '3' is not assignable to type '2'. Overload 2 of 2, '(props: ResizablePanelProps, context?: any): ResizablePanel', gave the following error. Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. Types of property 'children' are incompatible. @@ -33,10 +31,8 @@ tests/cases/conformance/jsx/checkJsxChildrenCanBeTupleType.tsx(17,18): error TS2 !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(props: Readonly): ResizablePanel', gave the following error. !!! error TS2769: Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. -!!! error TS2769: Types of property 'children' are incompatible. -!!! error TS2769: Type '[Element, Element, Element]' is not assignable to type '[ReactNode, ReactNode]'. -!!! error TS2769: Types of property 'length' are incompatible. -!!! error TS2769: Type '3' is not assignable to type '2'. +!!! error TS2769: The types of 'children.length' are incompatible between these types. +!!! error TS2769: Type '3' is not assignable to type '2'. !!! error TS2769: Overload 2 of 2, '(props: ResizablePanelProps, context?: any): ResizablePanel', gave the following error. !!! error TS2769: Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. !!! error TS2769: Types of property 'children' are incompatible. diff --git a/tests/baselines/reference/complexRecursiveCollections.errors.txt b/tests/baselines/reference/complexRecursiveCollections.errors.txt index 27bb24bc5cc..cd88e596fd1 100644 --- a/tests/baselines/reference/complexRecursiveCollections.errors.txt +++ b/tests/baselines/reference/complexRecursiveCollections.errors.txt @@ -1,18 +1,15 @@ tests/cases/compiler/immutable.ts(341,22): error TS2430: Interface 'Keyed' incorrectly extends interface 'Collection'. - Types of property 'toSeq' are incompatible. - Type '() => Keyed' is not assignable to type '() => this'. - Type 'Keyed' is not assignable to type 'this'. - 'Keyed' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Keyed'. + The types returned by 'toSeq()' are incompatible between these types. + Type 'Keyed' is not assignable to type 'this'. + 'Keyed' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Keyed'. tests/cases/compiler/immutable.ts(359,22): error TS2430: Interface 'Indexed' incorrectly extends interface 'Collection'. - Types of property 'toSeq' are incompatible. - Type '() => Indexed' is not assignable to type '() => this'. - Type 'Indexed' is not assignable to type 'this'. - 'Indexed' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Indexed'. + The types returned by 'toSeq()' are incompatible between these types. + Type 'Indexed' is not assignable to type 'this'. + 'Indexed' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Indexed'. tests/cases/compiler/immutable.ts(391,22): error TS2430: Interface 'Set' incorrectly extends interface 'Collection'. - Types of property 'toSeq' are incompatible. - Type '() => Set' is not assignable to type '() => this'. - Type 'Set' is not assignable to type 'this'. - 'Set' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Set'. + The types returned by 'toSeq()' are incompatible between these types. + Type 'Set' is not assignable to type 'this'. + 'Set' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Set'. ==== tests/cases/compiler/complex.ts (0 errors) ==== @@ -380,10 +377,9 @@ tests/cases/compiler/immutable.ts(391,22): error TS2430: Interface 'Set' inco export interface Keyed extends Collection { ~~~~~ !!! error TS2430: Interface 'Keyed' incorrectly extends interface 'Collection'. -!!! error TS2430: Types of property 'toSeq' are incompatible. -!!! error TS2430: Type '() => Keyed' is not assignable to type '() => this'. -!!! error TS2430: Type 'Keyed' is not assignable to type 'this'. -!!! error TS2430: 'Keyed' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Keyed'. +!!! error TS2430: The types returned by 'toSeq()' are incompatible between these types. +!!! error TS2430: Type 'Keyed' is not assignable to type 'this'. +!!! error TS2430: 'Keyed' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Keyed'. toJS(): Object; toJSON(): { [key: string]: V }; toSeq(): Seq.Keyed; @@ -404,10 +400,9 @@ tests/cases/compiler/immutable.ts(391,22): error TS2430: Interface 'Set' inco export interface Indexed extends Collection { ~~~~~~~ !!! error TS2430: Interface 'Indexed' incorrectly extends interface 'Collection'. -!!! error TS2430: Types of property 'toSeq' are incompatible. -!!! error TS2430: Type '() => Indexed' is not assignable to type '() => this'. -!!! error TS2430: Type 'Indexed' is not assignable to type 'this'. -!!! error TS2430: 'Indexed' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Indexed'. +!!! error TS2430: The types returned by 'toSeq()' are incompatible between these types. +!!! error TS2430: Type 'Indexed' is not assignable to type 'this'. +!!! error TS2430: 'Indexed' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Indexed'. toJS(): Array; toJSON(): Array; // Reading values @@ -442,10 +437,9 @@ tests/cases/compiler/immutable.ts(391,22): error TS2430: Interface 'Set' inco export interface Set extends Collection { ~~~ !!! error TS2430: Interface 'Set' incorrectly extends interface 'Collection'. -!!! error TS2430: Types of property 'toSeq' are incompatible. -!!! error TS2430: Type '() => Set' is not assignable to type '() => this'. -!!! error TS2430: Type 'Set' is not assignable to type 'this'. -!!! error TS2430: 'Set' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Set'. +!!! error TS2430: The types returned by 'toSeq()' are incompatible between these types. +!!! error TS2430: Type 'Set' is not assignable to type 'this'. +!!! error TS2430: 'Set' is assignable to the constraint of type 'this', but 'this' could be instantiated with a different subtype of constraint 'Set'. toJS(): Array; toJSON(): Array; toSeq(): Seq.Set; diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt index e326d163c8c..1cc019746ba 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt @@ -1,12 +1,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts(61,15): error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. - Types of property 'a' are incompatible. - Type 'new (x: number) => string' is not assignable to type 'new (x: number) => number'. - Type 'string' is not assignable to type 'number'. + The types returned by 'new a(...)' are incompatible between these types. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts(67,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. - Types of property 'a2' are incompatible. - Type 'new (x: T) => string' is not assignable to type 'new (x: T) => T'. - Type 'string' is not assignable to type 'T'. - 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a2(...)' are incompatible between these types. + Type 'string' is not assignable to type 'T'. + 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts (2 errors) ==== @@ -73,9 +71,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc interface I2 extends Base2 { ~~ !!! error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type 'new (x: number) => string' is not assignable to type 'new (x: number) => number'. -!!! error TS2430: Type 'string' is not assignable to type 'number'. +!!! error TS2430: The types returned by 'new a(...)' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'number'. // N's a: new (x: number) => string; // error because base returns non-void; } @@ -84,10 +81,9 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc interface I3 extends Base2 { ~~ !!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type 'new (x: T) => string' is not assignable to type 'new (x: T) => T'. -!!! error TS2430: Type 'string' is not assignable to type 'T'. -!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a2(...)' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'T'. +!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. // N's a2: new (x: T) => string; // error because base returns non-void; } diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt index 59d8105c59c..d4c9e808200 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt @@ -27,16 +27,14 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc Types of property 'a' are incompatible. Type 'string' is not assignable to type 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(86,19): error TS2430: Interface 'I6' incorrectly extends interface 'B'. - Types of property 'a2' are incompatible. - Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => T[]'. - Type 'string[]' is not assignable to type 'T[]'. - Type 'string' is not assignable to type 'T'. - 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a2(...)' are incompatible between these types. + Type 'string[]' is not assignable to type 'T[]'. + Type 'string' is not assignable to type 'T'. + 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(95,19): error TS2430: Interface 'I7' incorrectly extends interface 'C'. - Types of property 'a2' are incompatible. - Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => string[]'. - Type 'T[]' is not assignable to type 'string[]'. - Type 'T' is not assignable to type 'string'. + The types returned by 'new a2(...)' are incompatible between these types. + Type 'T[]' is not assignable to type 'string[]'. + Type 'T' is not assignable to type 'string'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts (6 errors) ==== @@ -160,11 +158,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc interface I6 extends B { ~~ !!! error TS2430: Interface 'I6' incorrectly extends interface 'B'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => T[]'. -!!! error TS2430: Type 'string[]' is not assignable to type 'T[]'. -!!! error TS2430: Type 'string' is not assignable to type 'T'. -!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a2(...)' are incompatible between these types. +!!! error TS2430: Type 'string[]' is not assignable to type 'T[]'. +!!! error TS2430: Type 'string' is not assignable to type 'T'. +!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a2: new (x: T) => string[]; // error } @@ -176,10 +173,9 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc interface I7 extends C { ~~ !!! error TS2430: Interface 'I7' incorrectly extends interface 'C'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => string[]'. -!!! error TS2430: Type 'T[]' is not assignable to type 'string[]'. -!!! error TS2430: Type 'T' is not assignable to type 'string'. +!!! error TS2430: The types returned by 'new a2(...)' are incompatible between these types. +!!! error TS2430: Type 'T[]' is not assignable to type 'string[]'. +!!! error TS2430: Type 'T' is not assignable to type 'string'. a2: new (x: T) => T[]; // error } diff --git a/tests/baselines/reference/covariantCallbacks.errors.txt b/tests/baselines/reference/covariantCallbacks.errors.txt index 9ee5a9e2fed..401bf454baa 100644 --- a/tests/baselines/reference/covariantCallbacks.errors.txt +++ b/tests/baselines/reference/covariantCallbacks.errors.txt @@ -10,9 +10,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/covarian Type 'A' is not assignable to type 'B'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/covariantCallbacks.ts(43,5): error TS2322: Type 'AList2' is not assignable to type 'BList2'. Types of property 'forEach' are incompatible. - Type '(cb: (item: A) => boolean) => void' is not assignable to type '(cb: (item: A) => void) => void'. - Types of parameters 'cb' and 'cb' are incompatible. - Type 'void' is not assignable to type 'boolean'. + Types of parameters 'cb' and 'cb' are incompatible. + Type 'void' is not assignable to type 'boolean'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/covariantCallbacks.ts(56,5): error TS2322: Type 'AList3' is not assignable to type 'BList3'. Types of property 'forEach' are incompatible. Type '(cb: (item: A) => void) => void' is not assignable to type '(cb: (item: A, context: any) => void) => void'. @@ -86,9 +85,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/covarian ~ !!! error TS2322: Type 'AList2' is not assignable to type 'BList2'. !!! error TS2322: Types of property 'forEach' are incompatible. -!!! error TS2322: Type '(cb: (item: A) => boolean) => void' is not assignable to type '(cb: (item: A) => void) => void'. -!!! error TS2322: Types of parameters 'cb' and 'cb' are incompatible. -!!! error TS2322: Type 'void' is not assignable to type 'boolean'. +!!! error TS2322: Types of parameters 'cb' and 'cb' are incompatible. +!!! error TS2322: Type 'void' is not assignable to type 'boolean'. } interface AList3 { diff --git a/tests/baselines/reference/decoratorCallGeneric.errors.txt b/tests/baselines/reference/decoratorCallGeneric.errors.txt index c2e4042743e..495160a191b 100644 --- a/tests/baselines/reference/decoratorCallGeneric.errors.txt +++ b/tests/baselines/reference/decoratorCallGeneric.errors.txt @@ -1,7 +1,6 @@ tests/cases/conformance/decorators/decoratorCallGeneric.ts(7,2): error TS2345: Argument of type 'typeof C' is not assignable to parameter of type 'I'. - Types of property 'm' are incompatible. - Type '() => void' is not assignable to type '() => C'. - Type 'void' is not assignable to type 'C'. + The types returned by 'm()' are incompatible between these types. + Type 'void' is not assignable to type 'C'. ==== tests/cases/conformance/decorators/decoratorCallGeneric.ts (1 errors) ==== @@ -14,9 +13,8 @@ tests/cases/conformance/decorators/decoratorCallGeneric.ts(7,2): error TS2345: A @dec ~~~ !!! error TS2345: Argument of type 'typeof C' is not assignable to parameter of type 'I'. -!!! error TS2345: Types of property 'm' are incompatible. -!!! error TS2345: Type '() => void' is not assignable to type '() => C'. -!!! error TS2345: Type 'void' is not assignable to type 'C'. +!!! error TS2345: The types returned by 'm()' are incompatible between these types. +!!! error TS2345: Type 'void' is not assignable to type 'C'. class C { _brand: any; static m() {} diff --git a/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.errors.txt b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.errors.txt index 6a83638ba90..1f2552d47f2 100644 --- a/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.errors.txt +++ b/tests/baselines/reference/deepExcessPropertyCheckingWhenTargetIsIntersection.errors.txt @@ -1,10 +1,8 @@ tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts(21,33): error TS2322: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. -tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts(27,34): error TS2326: Types of property 'icon' are incompatible. - Type '{ props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }' is not assignable to type 'NestedProp'. - Types of property 'props' are incompatible. - Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. - Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. +tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts(27,34): error TS2200: The types of 'icon.props' are incompatible between these types. + Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. + Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. ==== tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts (2 errors) ==== @@ -40,9 +38,7 @@ tests/cases/compiler/deepExcessPropertyCheckingWhenTargetIsIntersection.ts(27,34 TestComponent2({icon: { props: { INVALID_PROP_NAME: 'share', ariaLabel: 'test label' } }}); ~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2326: Types of property 'icon' are incompatible. -!!! error TS2326: Type '{ props: { INVALID_PROP_NAME: string; ariaLabel: string; }; }' is not assignable to type 'NestedProp'. -!!! error TS2326: Types of property 'props' are incompatible. -!!! error TS2326: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. -!!! error TS2326: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. +!!! error TS2200: The types of 'icon.props' are incompatible between these types. +!!! error TS2200: Type '{ INVALID_PROP_NAME: string; ariaLabel: string; }' is not assignable to type 'ITestProps'. +!!! error TS2200: Object literal may only specify known properties, and 'INVALID_PROP_NAME' does not exist in type 'ITestProps'. \ No newline at end of file diff --git a/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.errors.txt b/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.errors.txt new file mode 100644 index 00000000000..6245d06d2b7 --- /dev/null +++ b/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts(3,1): error TS2322: Type '{ a: { b: { c: { d: { e: { f(): { g: number; }; }; }; }; }; }; }' is not assignable to type '{ a: { b: { c: { d: { e: { f(): { g: string; }; }; }; }; }; }; }'. + The types of 'a.b.c.d.e.f().g' are incompatible between these types. + Type 'number' is not assignable to type 'string'. +tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts(15,1): error TS2322: Type '{ a: { b: { c: { d: { e: { f: typeof Ctor2; }; }; }; }; }; }' is not assignable to type '{ a: { b: { c: { d: { e: { f: typeof Ctor1; }; }; }; }; }; }'. + The types of '(new a.b.c.d.e.f()).g' are incompatible between these types. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts (2 errors) ==== + let x = { a: { b: { c: { d: { e: { f() { return { g: "hello" }; } } } } } } }; + let y = { a: { b: { c: { d: { e: { f() { return { g: 12345 }; } } } } } } }; + x = y; + ~ +!!! error TS2322: Type '{ a: { b: { c: { d: { e: { f(): { g: number; }; }; }; }; }; }; }' is not assignable to type '{ a: { b: { c: { d: { e: { f(): { g: string; }; }; }; }; }; }; }'. +!!! error TS2322: The types of 'a.b.c.d.e.f().g' are incompatible between these types. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + + class Ctor1 { + g = "ok" + } + + class Ctor2 { + g = 12; + } + + let x2 = { a: { b: { c: { d: { e: { f: Ctor1 } } } } } }; + let y2 = { a: { b: { c: { d: { e: { f: Ctor2 } } } } } }; + x2 = y2; + ~~ +!!! error TS2322: Type '{ a: { b: { c: { d: { e: { f: typeof Ctor2; }; }; }; }; }; }' is not assignable to type '{ a: { b: { c: { d: { e: { f: typeof Ctor1; }; }; }; }; }; }'. +!!! error TS2322: The types of '(new a.b.c.d.e.f()).g' are incompatible between these types. +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.js b/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.js new file mode 100644 index 00000000000..01bdcc7f253 --- /dev/null +++ b/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.js @@ -0,0 +1,36 @@ +//// [deeplyNestedAssignabilityErrorsCombined.ts] +let x = { a: { b: { c: { d: { e: { f() { return { g: "hello" }; } } } } } } }; +let y = { a: { b: { c: { d: { e: { f() { return { g: 12345 }; } } } } } } }; +x = y; + +class Ctor1 { + g = "ok" +} + +class Ctor2 { + g = 12; +} + +let x2 = { a: { b: { c: { d: { e: { f: Ctor1 } } } } } }; +let y2 = { a: { b: { c: { d: { e: { f: Ctor2 } } } } } }; +x2 = y2; + +//// [deeplyNestedAssignabilityErrorsCombined.js] +var x = { a: { b: { c: { d: { e: { f: function () { return { g: "hello" }; } } } } } } }; +var y = { a: { b: { c: { d: { e: { f: function () { return { g: 12345 }; } } } } } } }; +x = y; +var Ctor1 = /** @class */ (function () { + function Ctor1() { + this.g = "ok"; + } + return Ctor1; +}()); +var Ctor2 = /** @class */ (function () { + function Ctor2() { + this.g = 12; + } + return Ctor2; +}()); +var x2 = { a: { b: { c: { d: { e: { f: Ctor1 } } } } } }; +var y2 = { a: { b: { c: { d: { e: { f: Ctor2 } } } } } }; +x2 = y2; diff --git a/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.symbols b/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.symbols new file mode 100644 index 00000000000..12333869923 --- /dev/null +++ b/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.symbols @@ -0,0 +1,63 @@ +=== tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts === +let x = { a: { b: { c: { d: { e: { f() { return { g: "hello" }; } } } } } } }; +>x : Symbol(x, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 3)) +>a : Symbol(a, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 9)) +>b : Symbol(b, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 14)) +>c : Symbol(c, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 19)) +>d : Symbol(d, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 24)) +>e : Symbol(e, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 29)) +>f : Symbol(f, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 34)) +>g : Symbol(g, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 49)) + +let y = { a: { b: { c: { d: { e: { f() { return { g: 12345 }; } } } } } } }; +>y : Symbol(y, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 3)) +>a : Symbol(a, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 9)) +>b : Symbol(b, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 14)) +>c : Symbol(c, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 19)) +>d : Symbol(d, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 24)) +>e : Symbol(e, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 29)) +>f : Symbol(f, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 34)) +>g : Symbol(g, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 49)) + +x = y; +>x : Symbol(x, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 0, 3)) +>y : Symbol(y, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 1, 3)) + +class Ctor1 { +>Ctor1 : Symbol(Ctor1, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 2, 6)) + + g = "ok" +>g : Symbol(Ctor1.g, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 4, 13)) +} + +class Ctor2 { +>Ctor2 : Symbol(Ctor2, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 6, 1)) + + g = 12; +>g : Symbol(Ctor2.g, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 8, 13)) +} + +let x2 = { a: { b: { c: { d: { e: { f: Ctor1 } } } } } }; +>x2 : Symbol(x2, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 12, 3)) +>a : Symbol(a, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 12, 10)) +>b : Symbol(b, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 12, 15)) +>c : Symbol(c, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 12, 20)) +>d : Symbol(d, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 12, 25)) +>e : Symbol(e, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 12, 30)) +>f : Symbol(f, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 12, 35)) +>Ctor1 : Symbol(Ctor1, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 2, 6)) + +let y2 = { a: { b: { c: { d: { e: { f: Ctor2 } } } } } }; +>y2 : Symbol(y2, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 13, 3)) +>a : Symbol(a, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 13, 10)) +>b : Symbol(b, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 13, 15)) +>c : Symbol(c, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 13, 20)) +>d : Symbol(d, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 13, 25)) +>e : Symbol(e, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 13, 30)) +>f : Symbol(f, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 13, 35)) +>Ctor2 : Symbol(Ctor2, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 6, 1)) + +x2 = y2; +>x2 : Symbol(x2, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 12, 3)) +>y2 : Symbol(y2, Decl(deeplyNestedAssignabilityErrorsCombined.ts, 13, 3)) + diff --git a/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.types b/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.types new file mode 100644 index 00000000000..565de61ef08 --- /dev/null +++ b/tests/baselines/reference/deeplyNestedAssignabilityErrorsCombined.types @@ -0,0 +1,95 @@ +=== tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts === +let x = { a: { b: { c: { d: { e: { f() { return { g: "hello" }; } } } } } } }; +>x : { a: { b: { c: { d: { e: { f(): { g: string; }; }; }; }; }; }; } +>{ a: { b: { c: { d: { e: { f() { return { g: "hello" }; } } } } } } } : { a: { b: { c: { d: { e: { f(): { g: string; }; }; }; }; }; }; } +>a : { b: { c: { d: { e: { f(): { g: string; }; }; }; }; }; } +>{ b: { c: { d: { e: { f() { return { g: "hello" }; } } } } } } : { b: { c: { d: { e: { f(): { g: string; }; }; }; }; }; } +>b : { c: { d: { e: { f(): { g: string; }; }; }; }; } +>{ c: { d: { e: { f() { return { g: "hello" }; } } } } } : { c: { d: { e: { f(): { g: string; }; }; }; }; } +>c : { d: { e: { f(): { g: string; }; }; }; } +>{ d: { e: { f() { return { g: "hello" }; } } } } : { d: { e: { f(): { g: string; }; }; }; } +>d : { e: { f(): { g: string; }; }; } +>{ e: { f() { return { g: "hello" }; } } } : { e: { f(): { g: string; }; }; } +>e : { f(): { g: string; }; } +>{ f() { return { g: "hello" }; } } : { f(): { g: string; }; } +>f : () => { g: string; } +>{ g: "hello" } : { g: string; } +>g : string +>"hello" : "hello" + +let y = { a: { b: { c: { d: { e: { f() { return { g: 12345 }; } } } } } } }; +>y : { a: { b: { c: { d: { e: { f(): { g: number; }; }; }; }; }; }; } +>{ a: { b: { c: { d: { e: { f() { return { g: 12345 }; } } } } } } } : { a: { b: { c: { d: { e: { f(): { g: number; }; }; }; }; }; }; } +>a : { b: { c: { d: { e: { f(): { g: number; }; }; }; }; }; } +>{ b: { c: { d: { e: { f() { return { g: 12345 }; } } } } } } : { b: { c: { d: { e: { f(): { g: number; }; }; }; }; }; } +>b : { c: { d: { e: { f(): { g: number; }; }; }; }; } +>{ c: { d: { e: { f() { return { g: 12345 }; } } } } } : { c: { d: { e: { f(): { g: number; }; }; }; }; } +>c : { d: { e: { f(): { g: number; }; }; }; } +>{ d: { e: { f() { return { g: 12345 }; } } } } : { d: { e: { f(): { g: number; }; }; }; } +>d : { e: { f(): { g: number; }; }; } +>{ e: { f() { return { g: 12345 }; } } } : { e: { f(): { g: number; }; }; } +>e : { f(): { g: number; }; } +>{ f() { return { g: 12345 }; } } : { f(): { g: number; }; } +>f : () => { g: number; } +>{ g: 12345 } : { g: number; } +>g : number +>12345 : 12345 + +x = y; +>x = y : { a: { b: { c: { d: { e: { f(): { g: number; }; }; }; }; }; }; } +>x : { a: { b: { c: { d: { e: { f(): { g: string; }; }; }; }; }; }; } +>y : { a: { b: { c: { d: { e: { f(): { g: number; }; }; }; }; }; }; } + +class Ctor1 { +>Ctor1 : Ctor1 + + g = "ok" +>g : string +>"ok" : "ok" +} + +class Ctor2 { +>Ctor2 : Ctor2 + + g = 12; +>g : number +>12 : 12 +} + +let x2 = { a: { b: { c: { d: { e: { f: Ctor1 } } } } } }; +>x2 : { a: { b: { c: { d: { e: { f: typeof Ctor1; }; }; }; }; }; } +>{ a: { b: { c: { d: { e: { f: Ctor1 } } } } } } : { a: { b: { c: { d: { e: { f: typeof Ctor1; }; }; }; }; }; } +>a : { b: { c: { d: { e: { f: typeof Ctor1; }; }; }; }; } +>{ b: { c: { d: { e: { f: Ctor1 } } } } } : { b: { c: { d: { e: { f: typeof Ctor1; }; }; }; }; } +>b : { c: { d: { e: { f: typeof Ctor1; }; }; }; } +>{ c: { d: { e: { f: Ctor1 } } } } : { c: { d: { e: { f: typeof Ctor1; }; }; }; } +>c : { d: { e: { f: typeof Ctor1; }; }; } +>{ d: { e: { f: Ctor1 } } } : { d: { e: { f: typeof Ctor1; }; }; } +>d : { e: { f: typeof Ctor1; }; } +>{ e: { f: Ctor1 } } : { e: { f: typeof Ctor1; }; } +>e : { f: typeof Ctor1; } +>{ f: Ctor1 } : { f: typeof Ctor1; } +>f : typeof Ctor1 +>Ctor1 : typeof Ctor1 + +let y2 = { a: { b: { c: { d: { e: { f: Ctor2 } } } } } }; +>y2 : { a: { b: { c: { d: { e: { f: typeof Ctor2; }; }; }; }; }; } +>{ a: { b: { c: { d: { e: { f: Ctor2 } } } } } } : { a: { b: { c: { d: { e: { f: typeof Ctor2; }; }; }; }; }; } +>a : { b: { c: { d: { e: { f: typeof Ctor2; }; }; }; }; } +>{ b: { c: { d: { e: { f: Ctor2 } } } } } : { b: { c: { d: { e: { f: typeof Ctor2; }; }; }; }; } +>b : { c: { d: { e: { f: typeof Ctor2; }; }; }; } +>{ c: { d: { e: { f: Ctor2 } } } } : { c: { d: { e: { f: typeof Ctor2; }; }; }; } +>c : { d: { e: { f: typeof Ctor2; }; }; } +>{ d: { e: { f: Ctor2 } } } : { d: { e: { f: typeof Ctor2; }; }; } +>d : { e: { f: typeof Ctor2; }; } +>{ e: { f: Ctor2 } } : { e: { f: typeof Ctor2; }; } +>e : { f: typeof Ctor2; } +>{ f: Ctor2 } : { f: typeof Ctor2; } +>f : typeof Ctor2 +>Ctor2 : typeof Ctor2 + +x2 = y2; +>x2 = y2 : { a: { b: { c: { d: { e: { f: typeof Ctor2; }; }; }; }; }; } +>x2 : { a: { b: { c: { d: { e: { f: typeof Ctor1; }; }; }; }; }; } +>y2 : { a: { b: { c: { d: { e: { f: typeof Ctor2; }; }; }; }; }; } + diff --git a/tests/baselines/reference/elaboratedErrorsOnNullableTargets01.errors.txt b/tests/baselines/reference/elaboratedErrorsOnNullableTargets01.errors.txt index dc7e3f10bd1..b84fb863ad8 100644 --- a/tests/baselines/reference/elaboratedErrorsOnNullableTargets01.errors.txt +++ b/tests/baselines/reference/elaboratedErrorsOnNullableTargets01.errors.txt @@ -1,9 +1,7 @@ tests/cases/compiler/elaboratedErrorsOnNullableTargets01.ts(4,1): error TS2322: Type '{ foo: { bar: number | undefined; }; }' is not assignable to type '{ foo: { bar: string | null; } | undefined; }'. - Types of property 'foo' are incompatible. - Type '{ bar: number | undefined; }' is not assignable to type '{ bar: string | null; }'. - Types of property 'bar' are incompatible. - Type 'number | undefined' is not assignable to type 'string | null'. - Type 'undefined' is not assignable to type 'string | null'. + The types of 'foo.bar' are incompatible between these types. + Type 'number | undefined' is not assignable to type 'string | null'. + Type 'undefined' is not assignable to type 'string | null'. tests/cases/compiler/elaboratedErrorsOnNullableTargets01.ts(6,1): error TS2322: Type '{ foo: { bar: string | null; } | undefined; } | null | undefined' is not assignable to type '{ foo: { bar: number | undefined; }; }'. Type 'undefined' is not assignable to type '{ foo: { bar: number | undefined; }; }'. @@ -15,11 +13,9 @@ tests/cases/compiler/elaboratedErrorsOnNullableTargets01.ts(6,1): error TS2322: x = y; ~ !!! error TS2322: Type '{ foo: { bar: number | undefined; }; }' is not assignable to type '{ foo: { bar: string | null; } | undefined; }'. -!!! error TS2322: Types of property 'foo' are incompatible. -!!! error TS2322: Type '{ bar: number | undefined; }' is not assignable to type '{ bar: string | null; }'. -!!! error TS2322: Types of property 'bar' are incompatible. -!!! error TS2322: Type 'number | undefined' is not assignable to type 'string | null'. -!!! error TS2322: Type 'undefined' is not assignable to type 'string | null'. +!!! error TS2322: The types of 'foo.bar' are incompatible between these types. +!!! error TS2322: Type 'number | undefined' is not assignable to type 'string | null'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string | null'. y = x; ~ diff --git a/tests/baselines/reference/everyTypeWithAnnotationAndInvalidInitializer.errors.txt b/tests/baselines/reference/everyTypeWithAnnotationAndInvalidInitializer.errors.txt index 31848458a87..f552bb35ca4 100644 --- a/tests/baselines/reference/everyTypeWithAnnotationAndInvalidInitializer.errors.txt +++ b/tests/baselines/reference/everyTypeWithAnnotationAndInvalidInitializer.errors.txt @@ -17,9 +17,8 @@ tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAnd Type 'string' is not assignable to type 'number'. tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(48,32): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(50,5): error TS2322: Type 'typeof N' is not assignable to type 'typeof M'. - Types of property 'A' are incompatible. - Type 'typeof N.A' is not assignable to type 'typeof M.A'. - Property 'name' is missing in type 'N.A' but required in type 'M.A'. + The types returned by 'new A()' are incompatible between these types. + Property 'name' is missing in type 'N.A' but required in type 'M.A'. tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(51,5): error TS2322: Type 'N.A' is not assignable to type 'M.A'. tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts(52,5): error TS2322: Type '(x: number) => boolean' is not assignable to type '(x: number) => string'. Type 'boolean' is not assignable to type 'string'. @@ -112,9 +111,8 @@ tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAnd var aModule: typeof M = N; ~~~~~~~ !!! error TS2322: Type 'typeof N' is not assignable to type 'typeof M'. -!!! error TS2322: Types of property 'A' are incompatible. -!!! error TS2322: Type 'typeof N.A' is not assignable to type 'typeof M.A'. -!!! error TS2322: Property 'name' is missing in type 'N.A' but required in type 'M.A'. +!!! error TS2322: The types returned by 'new A()' are incompatible between these types. +!!! error TS2322: Property 'name' is missing in type 'N.A' but required in type 'M.A'. !!! related TS2728 tests/cases/conformance/statements/VariableStatements/everyTypeWithAnnotationAndInvalidInitializer.ts:20:9: 'name' is declared here. var aClassInModule: M.A = new N.A(); ~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/extendAndImplementTheSameBaseType2.errors.txt b/tests/baselines/reference/extendAndImplementTheSameBaseType2.errors.txt index 799fc7bb8b0..e23d9ebd282 100644 --- a/tests/baselines/reference/extendAndImplementTheSameBaseType2.errors.txt +++ b/tests/baselines/reference/extendAndImplementTheSameBaseType2.errors.txt @@ -1,7 +1,6 @@ tests/cases/compiler/extendAndImplementTheSameBaseType2.ts(7,7): error TS2720: Class 'D' incorrectly implements class 'C'. Did you mean to extend 'C' and inherit its members as a subclass? - Types of property 'bar' are incompatible. - Type '() => string' is not assignable to type '() => number'. - Type 'string' is not assignable to type 'number'. + The types returned by 'bar()' are incompatible between these types. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/extendAndImplementTheSameBaseType2.ts(12,5): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/compiler/extendAndImplementTheSameBaseType2.ts(16,5): error TS2322: Type 'string' is not assignable to type 'number'. @@ -16,9 +15,8 @@ tests/cases/compiler/extendAndImplementTheSameBaseType2.ts(16,5): error TS2322: class D extends C implements C { ~ !!! error TS2720: Class 'D' incorrectly implements class 'C'. Did you mean to extend 'C' and inherit its members as a subclass? -!!! error TS2720: Types of property 'bar' are incompatible. -!!! error TS2720: Type '() => string' is not assignable to type '() => number'. -!!! error TS2720: Type 'string' is not assignable to type 'number'. +!!! error TS2720: The types returned by 'bar()' are incompatible between these types. +!!! error TS2720: Type 'string' is not assignable to type 'number'. baz() { } } diff --git a/tests/baselines/reference/for-of39.errors.txt b/tests/baselines/reference/for-of39.errors.txt index a36c1c28a8c..3ecdc46bcfc 100644 --- a/tests/baselines/reference/for-of39.errors.txt +++ b/tests/baselines/reference/for-of39.errors.txt @@ -1,18 +1,14 @@ tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,11): error TS2769: No overload matches this call. Overload 1 of 3, '(iterable: Iterable): Map', gave the following error. Argument of type '([string, number] | [string, true])[]' is not assignable to parameter of type 'Iterable'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator<[string, number] | [string, true]>' is not assignable to type '() => Iterator'. - Type 'IterableIterator<[string, number] | [string, true]>' is not assignable to type 'Iterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult<[string, number] | [string, true], any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. - Type 'IteratorResult<[string, number] | [string, true], any>' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorYieldResult'. - Type '[string, number] | [string, true]' is not assignable to type 'readonly [string, boolean]'. - Type '[string, number]' is not assignable to type 'readonly [string, boolean]'. - Types of property '1' are incompatible. - Type 'number' is not assignable to type 'boolean'. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult<[string, number] | [string, true], any>' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorYieldResult'. + Type '[string, number] | [string, true]' is not assignable to type 'readonly [string, boolean]'. + Type '[string, number]' is not assignable to type 'readonly [string, boolean]'. + Types of property '1' are incompatible. + Type 'number' is not assignable to type 'boolean'. Overload 2 of 3, '(entries?: readonly (readonly [string, boolean])[]): Map', gave the following error. Type 'number' is not assignable to type 'boolean'. @@ -23,18 +19,14 @@ tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,11): error TS2769: No !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 3, '(iterable: Iterable): Map', gave the following error. !!! error TS2769: Argument of type '([string, number] | [string, true])[]' is not assignable to parameter of type 'Iterable'. -!!! error TS2769: Types of property '[Symbol.iterator]' are incompatible. -!!! error TS2769: Type '() => IterableIterator<[string, number] | [string, true]>' is not assignable to type '() => Iterator'. -!!! error TS2769: Type 'IterableIterator<[string, number] | [string, true]>' is not assignable to type 'Iterator'. -!!! error TS2769: Types of property 'next' are incompatible. -!!! error TS2769: Type '(...args: [] | [undefined]) => IteratorResult<[string, number] | [string, true], any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. -!!! error TS2769: Type 'IteratorResult<[string, number] | [string, true], any>' is not assignable to type 'IteratorResult'. -!!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorResult'. -!!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorYieldResult'. -!!! error TS2769: Type '[string, number] | [string, true]' is not assignable to type 'readonly [string, boolean]'. -!!! error TS2769: Type '[string, number]' is not assignable to type 'readonly [string, boolean]'. -!!! error TS2769: Types of property '1' are incompatible. -!!! error TS2769: Type 'number' is not assignable to type 'boolean'. +!!! error TS2769: The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. +!!! error TS2769: Type 'IteratorResult<[string, number] | [string, true], any>' is not assignable to type 'IteratorResult'. +!!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorResult'. +!!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, true]>' is not assignable to type 'IteratorYieldResult'. +!!! error TS2769: Type '[string, number] | [string, true]' is not assignable to type 'readonly [string, boolean]'. +!!! error TS2769: Type '[string, number]' is not assignable to type 'readonly [string, boolean]'. +!!! error TS2769: Types of property '1' are incompatible. +!!! error TS2769: Type 'number' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 3, '(entries?: readonly (readonly [string, boolean])[]): Map', gave the following error. !!! error TS2769: Type 'number' is not assignable to type 'boolean'. for (var [k, v] of map) { diff --git a/tests/baselines/reference/generatorTypeCheck25.errors.txt b/tests/baselines/reference/generatorTypeCheck25.errors.txt index 365a19dfdd7..e37f1304963 100644 --- a/tests/baselines/reference/generatorTypeCheck25.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck25.errors.txt @@ -1,15 +1,11 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck25.ts(4,5): error TS2322: Type '() => Generator' is not assignable to type '() => Iterable'. - Type 'Generator' is not assignable to type 'Iterable'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => Generator' is not assignable to type '() => Iterator'. - Type 'Generator' is not assignable to type 'Iterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. - Type 'IteratorResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. - Type 'Bar | Baz' is not assignable to type 'Foo'. - Property 'x' is missing in type 'Baz' but required in type 'Foo'. + Call signature return types 'Generator' and 'Iterable' are incompatible. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. + Type 'Bar | Baz' is not assignable to type 'Foo'. + Property 'x' is missing in type 'Baz' but required in type 'Foo'. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck25.ts (1 errors) ==== @@ -19,17 +15,13 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck25.ts(4,5): error var g3: () => Iterable = function* () { ~~ !!! error TS2322: Type '() => Generator' is not assignable to type '() => Iterable'. -!!! error TS2322: Type 'Generator' is not assignable to type 'Iterable'. -!!! error TS2322: Types of property '[Symbol.iterator]' are incompatible. -!!! error TS2322: Type '() => Generator' is not assignable to type '() => Iterator'. -!!! error TS2322: Type 'Generator' is not assignable to type 'Iterator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [undefined]) => IteratorResult' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. -!!! error TS2322: Type 'IteratorResult' is not assignable to type 'IteratorResult'. -!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -!!! error TS2322: Type 'Bar | Baz' is not assignable to type 'Foo'. -!!! error TS2322: Property 'x' is missing in type 'Baz' but required in type 'Foo'. +!!! error TS2322: Call signature return types 'Generator' and 'Iterable' are incompatible. +!!! error TS2322: The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. +!!! error TS2322: Type 'IteratorResult' is not assignable to type 'IteratorResult'. +!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. +!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. +!!! error TS2322: Type 'Bar | Baz' is not assignable to type 'Foo'. +!!! error TS2322: Property 'x' is missing in type 'Baz' but required in type 'Foo'. !!! related TS2728 tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck25.ts:1:13: 'x' is declared here. yield; yield new Bar; diff --git a/tests/baselines/reference/generatorTypeCheck63.errors.txt b/tests/baselines/reference/generatorTypeCheck63.errors.txt index 60dfb089822..10cafbe0ced 100644 --- a/tests/baselines/reference/generatorTypeCheck63.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck63.errors.txt @@ -1,11 +1,10 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(24,61): error TS2345: Argument of type '(state: State) => Generator' is not assignable to parameter of type '(a: State) => IterableIterator'. - Type 'Generator' is not assignable to type 'IterableIterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. - Type 'IteratorResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. - Type 'number' is not assignable to type 'State'. + Call signature return types 'Generator' and 'IterableIterator' are incompatible. + The types returned by 'next(...)' are incompatible between these types. + Type 'IteratorResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. + Type 'number' is not assignable to type 'State'. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts (1 errors) ==== @@ -35,13 +34,12 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(24,61): err export const Nothing: Strategy = strategy("Nothing", function* (state: State) { ~~~~~~~~ !!! error TS2345: Argument of type '(state: State) => Generator' is not assignable to parameter of type '(a: State) => IterableIterator'. -!!! error TS2345: Type 'Generator' is not assignable to type 'IterableIterator'. -!!! error TS2345: Types of property 'next' are incompatible. -!!! error TS2345: Type '(...args: [] | [undefined]) => IteratorResult' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. -!!! error TS2345: Type 'IteratorResult' is not assignable to type 'IteratorResult'. -!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -!!! error TS2345: Type 'number' is not assignable to type 'State'. +!!! error TS2345: Call signature return types 'Generator' and 'IterableIterator' are incompatible. +!!! error TS2345: The types returned by 'next(...)' are incompatible between these types. +!!! error TS2345: Type 'IteratorResult' is not assignable to type 'IteratorResult'. +!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. +!!! error TS2345: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. +!!! error TS2345: Type 'number' is not assignable to type 'State'. yield 1; return state; }); diff --git a/tests/baselines/reference/generatorTypeCheck8.errors.txt b/tests/baselines/reference/generatorTypeCheck8.errors.txt index 6261d419ddd..ca0b1e30366 100644 --- a/tests/baselines/reference/generatorTypeCheck8.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck8.errors.txt @@ -1,10 +1,9 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck8.ts(2,17): error TS2322: Type 'Generator' is not assignable to type 'BadGenerator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. - Type 'IteratorResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. - Type 'string' is not assignable to type 'number'. + The types returned by 'next(...)' are incompatible between these types. + Type 'IteratorResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. + Type 'string' is not assignable to type 'number'. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck8.ts (1 errors) ==== @@ -12,9 +11,8 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck8.ts(2,17): error function* g3(): BadGenerator { } ~~~~~~~~~~~~ !!! error TS2322: Type 'Generator' is not assignable to type 'BadGenerator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [undefined]) => IteratorResult' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. -!!! error TS2322: Type 'IteratorResult' is not assignable to type 'IteratorResult'. -!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. \ No newline at end of file +!!! error TS2322: The types returned by 'next(...)' are incompatible between these types. +!!! error TS2322: Type 'IteratorResult' is not assignable to type 'IteratorResult'. +!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. +!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/generics4.errors.txt b/tests/baselines/reference/generics4.errors.txt index 06bfa122901..6181685983e 100644 --- a/tests/baselines/reference/generics4.errors.txt +++ b/tests/baselines/reference/generics4.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/generics4.ts(7,1): error TS2322: Type 'C' is not assignable to type 'C'. Type 'Y' is not assignable to type 'X'. - Types of property 'f' are incompatible. - Type '() => boolean' is not assignable to type '() => string'. - Type 'boolean' is not assignable to type 'string'. + The types returned by 'f()' are incompatible between these types. + Type 'boolean' is not assignable to type 'string'. ==== tests/cases/compiler/generics4.ts (1 errors) ==== @@ -16,6 +15,5 @@ tests/cases/compiler/generics4.ts(7,1): error TS2322: Type 'C' is not assigna ~ !!! error TS2322: Type 'C' is not assignable to type 'C'. !!! error TS2322: Type 'Y' is not assignable to type 'X'. -!!! error TS2322: Types of property 'f' are incompatible. -!!! error TS2322: Type '() => boolean' is not assignable to type '() => string'. -!!! error TS2322: Type 'boolean' is not assignable to type 'string'. \ No newline at end of file +!!! error TS2322: The types returned by 'f()' are incompatible between these types. +!!! error TS2322: Type 'boolean' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/incompatibleTypes.errors.txt b/tests/baselines/reference/incompatibleTypes.errors.txt index 0b5e587ad53..66d94bea79c 100644 --- a/tests/baselines/reference/incompatibleTypes.errors.txt +++ b/tests/baselines/reference/incompatibleTypes.errors.txt @@ -12,14 +12,12 @@ tests/cases/compiler/incompatibleTypes.ts(34,12): error TS2416: Property 'p1' in tests/cases/compiler/incompatibleTypes.ts(42,5): error TS2769: No overload matches this call. Overload 1 of 2, '(i: IFoo1): void', gave the following error. Argument of type 'C1' is not assignable to parameter of type 'IFoo1'. - Types of property 'p1' are incompatible. - Type '() => string' is not assignable to type '() => number'. - Type 'string' is not assignable to type 'number'. + The types returned by 'p1()' are incompatible between these types. + Type 'string' is not assignable to type 'number'. Overload 2 of 2, '(i: IFoo2): void', gave the following error. Argument of type 'C1' is not assignable to parameter of type 'IFoo2'. - Types of property 'p1' are incompatible. - Type '() => string' is not assignable to type '(s: string) => number'. - Type 'string' is not assignable to type 'number'. + The types returned by 'p1(...)' are incompatible between these types. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/incompatibleTypes.ts(49,7): error TS2769: No overload matches this call. Overload 1 of 2, '(n: { a: { a: string; }; b: string; }): number', gave the following error. Argument of type '{ e: number; f: number; }' is not assignable to parameter of type '{ a: { a: string; }; b: string; }'. @@ -95,14 +93,12 @@ tests/cases/compiler/incompatibleTypes.ts(74,5): error TS2322: Type '(a: any) => !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(i: IFoo1): void', gave the following error. !!! error TS2769: Argument of type 'C1' is not assignable to parameter of type 'IFoo1'. -!!! error TS2769: Types of property 'p1' are incompatible. -!!! error TS2769: Type '() => string' is not assignable to type '() => number'. -!!! error TS2769: Type 'string' is not assignable to type 'number'. +!!! error TS2769: The types returned by 'p1()' are incompatible between these types. +!!! error TS2769: Type 'string' is not assignable to type 'number'. !!! error TS2769: Overload 2 of 2, '(i: IFoo2): void', gave the following error. !!! error TS2769: Argument of type 'C1' is not assignable to parameter of type 'IFoo2'. -!!! error TS2769: Types of property 'p1' are incompatible. -!!! error TS2769: Type '() => string' is not assignable to type '(s: string) => number'. -!!! error TS2769: Type 'string' is not assignable to type 'number'. +!!! error TS2769: The types returned by 'p1(...)' are incompatible between these types. +!!! error TS2769: Type 'string' is not assignable to type 'number'. function of1(n: { a: { a: string; }; b: string; }): number; diff --git a/tests/baselines/reference/inheritedModuleMembersForClodule.errors.txt b/tests/baselines/reference/inheritedModuleMembersForClodule.errors.txt index 0b7e00d95ce..e2b744d5a25 100644 --- a/tests/baselines/reference/inheritedModuleMembersForClodule.errors.txt +++ b/tests/baselines/reference/inheritedModuleMembersForClodule.errors.txt @@ -1,7 +1,6 @@ tests/cases/compiler/inheritedModuleMembersForClodule.ts(7,7): error TS2417: Class static side 'typeof D' incorrectly extends base class static side 'typeof C'. - Types of property 'foo' are incompatible. - Type '() => number' is not assignable to type '() => string'. - Type 'number' is not assignable to type 'string'. + The types returned by 'foo()' are incompatible between these types. + Type 'number' is not assignable to type 'string'. ==== tests/cases/compiler/inheritedModuleMembersForClodule.ts (1 errors) ==== @@ -14,9 +13,8 @@ tests/cases/compiler/inheritedModuleMembersForClodule.ts(7,7): error TS2417: Cla class D extends C { ~ !!! error TS2417: Class static side 'typeof D' incorrectly extends base class static side 'typeof C'. -!!! error TS2417: Types of property 'foo' are incompatible. -!!! error TS2417: Type '() => number' is not assignable to type '() => string'. -!!! error TS2417: Type 'number' is not assignable to type 'string'. +!!! error TS2417: The types returned by 'foo()' are incompatible between these types. +!!! error TS2417: Type 'number' is not assignable to type 'string'. } module D { diff --git a/tests/baselines/reference/interfaceThatHidesBaseProperty2.errors.txt b/tests/baselines/reference/interfaceThatHidesBaseProperty2.errors.txt index f66e13c0d9d..779a160c5a6 100644 --- a/tests/baselines/reference/interfaceThatHidesBaseProperty2.errors.txt +++ b/tests/baselines/reference/interfaceThatHidesBaseProperty2.errors.txt @@ -1,8 +1,6 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatHidesBaseProperty2.ts(5,11): error TS2430: Interface 'Derived' incorrectly extends interface 'Base'. - Types of property 'x' are incompatible. - Type '{ a: string; }' is not assignable to type '{ a: number; }'. - Types of property 'a' are incompatible. - Type 'string' is not assignable to type 'number'. + The types of 'x.a' are incompatible between these types. + Type 'string' is not assignable to type 'number'. ==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatHidesBaseProperty2.ts (1 errors) ==== @@ -13,10 +11,8 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceThatHidesBaseP interface Derived extends Base { // error ~~~~~~~ !!! error TS2430: Interface 'Derived' incorrectly extends interface 'Base'. -!!! error TS2430: Types of property 'x' are incompatible. -!!! error TS2430: Type '{ a: string; }' is not assignable to type '{ a: number; }'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type 'string' is not assignable to type 'number'. +!!! error TS2430: The types of 'x.a' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'number'. x: { a: string; }; diff --git a/tests/baselines/reference/interfaceWithMultipleBaseTypes.errors.txt b/tests/baselines/reference/interfaceWithMultipleBaseTypes.errors.txt index 138f3d92096..c885a7859d4 100644 --- a/tests/baselines/reference/interfaceWithMultipleBaseTypes.errors.txt +++ b/tests/baselines/reference/interfaceWithMultipleBaseTypes.errors.txt @@ -1,20 +1,14 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes.ts(21,11): error TS2430: Interface 'Derived2' incorrectly extends interface 'Base2'. - Types of property 'x' are incompatible. - Type '{ a: string; b: number; }' is not assignable to type '{ b: string; }'. - Types of property 'b' are incompatible. - Type 'number' is not assignable to type 'string'. + The types of 'x.b' are incompatible between these types. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes.ts(52,15): error TS2320: Interface 'Derived3' cannot simultaneously extend types 'Base1' and 'Base2'. Named property 'x' of types 'Base1' and 'Base2' are not identical. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes.ts(54,15): error TS2430: Interface 'Derived4' incorrectly extends interface 'Base1'. - Types of property 'x' are incompatible. - Type '{ a: T; b: T; }' is not assignable to type '{ a: number; }'. - Types of property 'a' are incompatible. - Type 'T' is not assignable to type 'number'. + The types of 'x.a' are incompatible between these types. + Type 'T' is not assignable to type 'number'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes.ts(54,15): error TS2430: Interface 'Derived4' incorrectly extends interface 'Base2'. - Types of property 'x' are incompatible. - Type '{ a: T; b: T; }' is not assignable to type '{ b: number; }'. - Types of property 'b' are incompatible. - Type 'T' is not assignable to type 'number'. + The types of 'x.b' are incompatible between these types. + Type 'T' is not assignable to type 'number'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes.ts(60,15): error TS2430: Interface 'Derived5' incorrectly extends interface 'Base1'. Types of property 'x' are incompatible. Type 'T' is not assignable to type '{ a: T; }'. @@ -47,10 +41,8 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBa interface Derived2 extends Base1, Base2 { // error ~~~~~~~~ !!! error TS2430: Interface 'Derived2' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'x' are incompatible. -!!! error TS2430: Type '{ a: string; b: number; }' is not assignable to type '{ b: string; }'. -!!! error TS2430: Types of property 'b' are incompatible. -!!! error TS2430: Type 'number' is not assignable to type 'string'. +!!! error TS2430: The types of 'x.b' are incompatible between these types. +!!! error TS2430: Type 'number' is not assignable to type 'string'. x: { a: string; b: number; } @@ -89,16 +81,12 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBa interface Derived4 extends Base1, Base2 { // error ~~~~~~~~ !!! error TS2430: Interface 'Derived4' incorrectly extends interface 'Base1'. -!!! error TS2430: Types of property 'x' are incompatible. -!!! error TS2430: Type '{ a: T; b: T; }' is not assignable to type '{ a: number; }'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type 'T' is not assignable to type 'number'. +!!! error TS2430: The types of 'x.a' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'number'. ~~~~~~~~ !!! error TS2430: Interface 'Derived4' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'x' are incompatible. -!!! error TS2430: Type '{ a: T; b: T; }' is not assignable to type '{ b: number; }'. -!!! error TS2430: Types of property 'b' are incompatible. -!!! error TS2430: Type 'T' is not assignable to type 'number'. +!!! error TS2430: The types of 'x.b' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'number'. x: { a: T; b: T; } diff --git a/tests/baselines/reference/interfaceWithMultipleBaseTypes2.errors.txt b/tests/baselines/reference/interfaceWithMultipleBaseTypes2.errors.txt index b3459233923..9b7b2eff8ec 100644 --- a/tests/baselines/reference/interfaceWithMultipleBaseTypes2.errors.txt +++ b/tests/baselines/reference/interfaceWithMultipleBaseTypes2.errors.txt @@ -1,8 +1,6 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes2.ts(17,11): error TS2430: Interface 'Derived2' incorrectly extends interface 'Base'. - Types of property 'x' are incompatible. - Type '{ a: number; b: string; }' is not assignable to type '{ a?: string; b: string; }'. - Types of property 'a' are incompatible. - Type 'number' is not assignable to type 'string'. + The types of 'x.a' are incompatible between these types. + Type 'number' is not assignable to type 'string'. ==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBaseTypes2.ts (1 errors) ==== @@ -25,10 +23,8 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithMultipleBa interface Derived2 extends Base, Base2 { // error ~~~~~~~~ !!! error TS2430: Interface 'Derived2' incorrectly extends interface 'Base'. -!!! error TS2430: Types of property 'x' are incompatible. -!!! error TS2430: Type '{ a: number; b: string; }' is not assignable to type '{ a?: string; b: string; }'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type 'number' is not assignable to type 'string'. +!!! error TS2430: The types of 'x.a' are incompatible between these types. +!!! error TS2430: Type 'number' is not assignable to type 'string'. x: { a: number; b: string } } diff --git a/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt b/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt index 0bd79bcf11d..7ab83c61bcd 100644 --- a/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt +++ b/tests/baselines/reference/invariantGenericErrorElaboration.errors.txt @@ -1,13 +1,7 @@ tests/cases/compiler/invariantGenericErrorElaboration.ts(3,7): error TS2322: Type 'Num' is not assignable to type 'Runtype'. - Types of property 'constraint' are incompatible. - Type 'Constraint' is not assignable to type 'Constraint>'. - Types of property 'constraint' are incompatible. - Type 'Constraint>' is not assignable to type 'Constraint>>'. - Types of property 'constraint' are incompatible. - Type 'Constraint>>' is not assignable to type 'Constraint>>>'. - Type 'Constraint>>' is not assignable to type 'Constraint>'. - Types of property 'underlying' are incompatible. - Type 'Constraint>' is not assignable to type 'Constraint'. + The types of 'constraint.constraint.constraint' are incompatible between these types. + Type 'Constraint>>' is not assignable to type 'Constraint>>>'. + Type 'Constraint>' is not assignable to type 'Constraint'. tests/cases/compiler/invariantGenericErrorElaboration.ts(4,19): error TS2322: Type 'Num' is not assignable to type 'Runtype'. @@ -17,16 +11,9 @@ tests/cases/compiler/invariantGenericErrorElaboration.ts(4,19): error TS2322: Ty const wat: Runtype = Num; ~~~ !!! error TS2322: Type 'Num' is not assignable to type 'Runtype'. -!!! error TS2322: Types of property 'constraint' are incompatible. -!!! error TS2322: Type 'Constraint' is not assignable to type 'Constraint>'. -!!! error TS2322: Types of property 'constraint' are incompatible. -!!! error TS2322: Type 'Constraint>' is not assignable to type 'Constraint>>'. -!!! error TS2322: Types of property 'constraint' are incompatible. -!!! error TS2322: Type 'Constraint>>' is not assignable to type 'Constraint>>>'. -!!! error TS2322: Type 'Constraint>>' is not assignable to type 'Constraint>'. -!!! error TS2322: Types of property 'underlying' are incompatible. -!!! error TS2322: Type 'Constraint>' is not assignable to type 'Constraint'. -!!! related TS2728 tests/cases/compiler/invariantGenericErrorElaboration.ts:12:3: 'tag' is declared here. +!!! error TS2322: The types of 'constraint.constraint.constraint' are incompatible between these types. +!!! error TS2322: Type 'Constraint>>' is not assignable to type 'Constraint>>>'. +!!! error TS2322: Type 'Constraint>' is not assignable to type 'Constraint'. const Foo = Obj({ foo: Num }) ~~~ !!! error TS2322: Type 'Num' is not assignable to type 'Runtype'. diff --git a/tests/baselines/reference/iterableArrayPattern28.errors.txt b/tests/baselines/reference/iterableArrayPattern28.errors.txt index 7a1ff6cf42c..605c6feb405 100644 --- a/tests/baselines/reference/iterableArrayPattern28.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern28.errors.txt @@ -1,18 +1,14 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,24): error TS2769: No overload matches this call. Overload 1 of 3, '(iterable: Iterable): Map', gave the following error. Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'Iterable'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator<[string, number] | [string, boolean]>' is not assignable to type '() => Iterator'. - Type 'IterableIterator<[string, number] | [string, boolean]>' is not assignable to type 'Iterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult<[string, number] | [string, boolean], any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. - Type 'IteratorResult<[string, number] | [string, boolean], any>' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorYieldResult'. - Type '[string, number] | [string, boolean]' is not assignable to type 'readonly [string, number]'. - Type '[string, boolean]' is not assignable to type 'readonly [string, number]'. - Types of property '1' are incompatible. - Type 'boolean' is not assignable to type 'number'. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult<[string, number] | [string, boolean], any>' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorYieldResult'. + Type '[string, number] | [string, boolean]' is not assignable to type 'readonly [string, number]'. + Type '[string, boolean]' is not assignable to type 'readonly [string, number]'. + Types of property '1' are incompatible. + Type 'boolean' is not assignable to type 'number'. Overload 2 of 3, '(entries?: readonly (readonly [string, number])[]): Map', gave the following error. Type 'true' is not assignable to type 'number'. @@ -24,17 +20,13 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,24): error !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 3, '(iterable: Iterable): Map', gave the following error. !!! error TS2769: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'Iterable'. -!!! error TS2769: Types of property '[Symbol.iterator]' are incompatible. -!!! error TS2769: Type '() => IterableIterator<[string, number] | [string, boolean]>' is not assignable to type '() => Iterator'. -!!! error TS2769: Type 'IterableIterator<[string, number] | [string, boolean]>' is not assignable to type 'Iterator'. -!!! error TS2769: Types of property 'next' are incompatible. -!!! error TS2769: Type '(...args: [] | [undefined]) => IteratorResult<[string, number] | [string, boolean], any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. -!!! error TS2769: Type 'IteratorResult<[string, number] | [string, boolean], any>' is not assignable to type 'IteratorResult'. -!!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorResult'. -!!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorYieldResult'. -!!! error TS2769: Type '[string, number] | [string, boolean]' is not assignable to type 'readonly [string, number]'. -!!! error TS2769: Type '[string, boolean]' is not assignable to type 'readonly [string, number]'. -!!! error TS2769: Types of property '1' are incompatible. -!!! error TS2769: Type 'boolean' is not assignable to type 'number'. +!!! error TS2769: The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. +!!! error TS2769: Type 'IteratorResult<[string, number] | [string, boolean], any>' is not assignable to type 'IteratorResult'. +!!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorResult'. +!!! error TS2769: Type 'IteratorYieldResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorYieldResult'. +!!! error TS2769: Type '[string, number] | [string, boolean]' is not assignable to type 'readonly [string, number]'. +!!! error TS2769: Type '[string, boolean]' is not assignable to type 'readonly [string, number]'. +!!! error TS2769: Types of property '1' are incompatible. +!!! error TS2769: Type 'boolean' is not assignable to type 'number'. !!! error TS2769: Overload 2 of 3, '(entries?: readonly (readonly [string, number])[]): Map', gave the following error. !!! error TS2769: Type 'true' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt index 0b114bc6477..202c0ab3bf2 100644 --- a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt @@ -1,10 +1,9 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): number[]', gave the following error. Argument of type 'symbol[]' is not assignable to parameter of type 'ConcatArray'. - Types of property 'slice' are incompatible. - Type '(start?: number, end?: number) => symbol[]' is not assignable to type '(start?: number, end?: number) => number[]'. - Type 'symbol[]' is not assignable to type 'number[]'. - Type 'symbol' is not assignable to type 'number'. + The types returned by 'slice(...)' are incompatible between these types. + Type 'symbol[]' is not assignable to type 'number[]'. + Type 'symbol' is not assignable to type 'number'. Overload 2 of 2, '(...items: (number | ConcatArray)[]): number[]', gave the following error. Argument of type 'symbol[]' is not assignable to parameter of type 'number | ConcatArray'. Type 'symbol[]' is not assignable to type 'ConcatArray'. @@ -30,10 +29,9 @@ tests/cases/conformance/es6/spread/iteratorSpreadInArray6.ts(15,14): error TS276 !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(...items: ConcatArray[]): number[]', gave the following error. !!! error TS2769: Argument of type 'symbol[]' is not assignable to parameter of type 'ConcatArray'. -!!! error TS2769: Types of property 'slice' are incompatible. -!!! error TS2769: Type '(start?: number, end?: number) => symbol[]' is not assignable to type '(start?: number, end?: number) => number[]'. -!!! error TS2769: Type 'symbol[]' is not assignable to type 'number[]'. -!!! error TS2769: Type 'symbol' is not assignable to type 'number'. +!!! error TS2769: The types returned by 'slice(...)' are incompatible between these types. +!!! error TS2769: Type 'symbol[]' is not assignable to type 'number[]'. +!!! error TS2769: Type 'symbol' is not assignable to type 'number'. !!! error TS2769: Overload 2 of 2, '(...items: (number | ConcatArray)[]): number[]', gave the following error. !!! error TS2769: Argument of type 'symbol[]' is not assignable to parameter of type 'number | ConcatArray'. !!! error TS2769: Type 'symbol[]' is not assignable to type 'ConcatArray'. \ No newline at end of file diff --git a/tests/baselines/reference/mergedDeclarations7.errors.txt b/tests/baselines/reference/mergedDeclarations7.errors.txt index cd9b3a5e939..bc09ea081a3 100644 --- a/tests/baselines/reference/mergedDeclarations7.errors.txt +++ b/tests/baselines/reference/mergedDeclarations7.errors.txt @@ -1,7 +1,6 @@ tests/cases/compiler/test.ts(4,5): error TS2322: Type 'PassportStatic' is not assignable to type 'Passport'. - Types of property 'use' are incompatible. - Type '() => PassportStatic' is not assignable to type '() => this'. - Type 'PassportStatic' is not assignable to type 'this'. + The types returned by 'use()' are incompatible between these types. + Type 'PassportStatic' is not assignable to type 'this'. ==== tests/cases/compiler/passport.d.ts (0 errors) ==== @@ -27,6 +26,5 @@ tests/cases/compiler/test.ts(4,5): error TS2322: Type 'PassportStatic' is not as let p: Passport = passport.use(); ~ !!! error TS2322: Type 'PassportStatic' is not assignable to type 'Passport'. -!!! error TS2322: Types of property 'use' are incompatible. -!!! error TS2322: Type '() => PassportStatic' is not assignable to type '() => this'. -!!! error TS2322: Type 'PassportStatic' is not assignable to type 'this'. \ No newline at end of file +!!! error TS2322: The types returned by 'use()' are incompatible between these types. +!!! error TS2322: Type 'PassportStatic' is not assignable to type 'this'. \ No newline at end of file diff --git a/tests/baselines/reference/multiLineErrors.errors.txt b/tests/baselines/reference/multiLineErrors.errors.txt index 70366aeabed..851425baef4 100644 --- a/tests/baselines/reference/multiLineErrors.errors.txt +++ b/tests/baselines/reference/multiLineErrors.errors.txt @@ -1,9 +1,7 @@ tests/cases/compiler/multiLineErrors.ts(3,22): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. tests/cases/compiler/multiLineErrors.ts(21,1): error TS2322: Type 'A2' is not assignable to type 'A1'. - Types of property 'x' are incompatible. - Type '{ y: string; }' is not assignable to type '{ y: number; }'. - Types of property 'y' are incompatible. - Type 'string' is not assignable to type 'number'. + The types of 'x.y' are incompatible between these types. + Type 'string' is not assignable to type 'number'. ==== tests/cases/compiler/multiLineErrors.ts (2 errors) ==== @@ -35,8 +33,6 @@ tests/cases/compiler/multiLineErrors.ts(21,1): error TS2322: Type 'A2' is not as t1 = t2; ~~ !!! error TS2322: Type 'A2' is not assignable to type 'A1'. -!!! error TS2322: Types of property 'x' are incompatible. -!!! error TS2322: Type '{ y: string; }' is not assignable to type '{ y: number; }'. -!!! error TS2322: Types of property 'y' are incompatible. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: The types of 'x.y' are incompatible between these types. +!!! error TS2322: Type 'string' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/mutuallyRecursiveCallbacks.errors.txt b/tests/baselines/reference/mutuallyRecursiveCallbacks.errors.txt index bb90bcee999..63a568bf10a 100644 --- a/tests/baselines/reference/mutuallyRecursiveCallbacks.errors.txt +++ b/tests/baselines/reference/mutuallyRecursiveCallbacks.errors.txt @@ -1,9 +1,8 @@ tests/cases/compiler/mutuallyRecursiveCallbacks.ts(7,1): error TS2322: Type '(bar: Bar) => void' is not assignable to type 'Bar<{}>'. Types of parameters 'bar' and 'foo' are incompatible. Types of parameters 'bar' and 'foo' are incompatible. - Type 'Foo' is not assignable to type 'Bar<{}>'. - Types of parameters 'bar' and 'foo' are incompatible. - Type 'void' is not assignable to type 'Foo'. + Types of parameters 'bar' and 'foo' are incompatible. + Type 'void' is not assignable to type 'Foo'. ==== tests/cases/compiler/mutuallyRecursiveCallbacks.ts (1 errors) ==== @@ -18,7 +17,6 @@ tests/cases/compiler/mutuallyRecursiveCallbacks.ts(7,1): error TS2322: Type ' !!! error TS2322: Type '(bar: Bar) => void' is not assignable to type 'Bar<{}>'. !!! error TS2322: Types of parameters 'bar' and 'foo' are incompatible. !!! error TS2322: Types of parameters 'bar' and 'foo' are incompatible. -!!! error TS2322: Type 'Foo' is not assignable to type 'Bar<{}>'. -!!! error TS2322: Types of parameters 'bar' and 'foo' are incompatible. -!!! error TS2322: Type 'void' is not assignable to type 'Foo'. +!!! error TS2322: Types of parameters 'bar' and 'foo' are incompatible. +!!! error TS2322: Type 'void' is not assignable to type 'Foo'. \ No newline at end of file diff --git a/tests/baselines/reference/nestedCallbackErrorNotFlattened.errors.txt b/tests/baselines/reference/nestedCallbackErrorNotFlattened.errors.txt new file mode 100644 index 00000000000..3749d3765b0 --- /dev/null +++ b/tests/baselines/reference/nestedCallbackErrorNotFlattened.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/nestedCallbackErrorNotFlattened.ts(6,1): error TS2322: Type '() => () => () => () => number' is not assignable to type '() => () => () => () => string'. + Call signature return types '() => () => () => number' and '() => () => () => string' are incompatible. + Call signature return types '() => () => number' and '() => () => string' are incompatible. + Call signature return types '() => number' and '() => string' are incompatible. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/compiler/nestedCallbackErrorNotFlattened.ts (1 errors) ==== + type Cb = {noAlias: () => T}["noAlias"]; // `"noAlias"` here prevents an alias symbol from being made + // which means the comparison will definitely be structural, rather than by variance + + declare const x: Cb>>>; // one more layer of `Cb` adn we'd get a `true` from the deeply-nested symbol check + declare let y: Cb>>>; + y = x; + ~ +!!! error TS2322: Type '() => () => () => () => number' is not assignable to type '() => () => () => () => string'. +!!! error TS2322: Call signature return types '() => () => () => number' and '() => () => () => string' are incompatible. +!!! error TS2322: Call signature return types '() => () => number' and '() => () => string' are incompatible. +!!! error TS2322: Call signature return types '() => number' and '() => string' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/nestedCallbackErrorNotFlattened.js b/tests/baselines/reference/nestedCallbackErrorNotFlattened.js new file mode 100644 index 00000000000..0c5edf9760b --- /dev/null +++ b/tests/baselines/reference/nestedCallbackErrorNotFlattened.js @@ -0,0 +1,11 @@ +//// [nestedCallbackErrorNotFlattened.ts] +type Cb = {noAlias: () => T}["noAlias"]; // `"noAlias"` here prevents an alias symbol from being made +// which means the comparison will definitely be structural, rather than by variance + +declare const x: Cb>>>; // one more layer of `Cb` adn we'd get a `true` from the deeply-nested symbol check +declare let y: Cb>>>; +y = x; + +//// [nestedCallbackErrorNotFlattened.js] +"use strict"; +y = x; diff --git a/tests/baselines/reference/nestedCallbackErrorNotFlattened.symbols b/tests/baselines/reference/nestedCallbackErrorNotFlattened.symbols new file mode 100644 index 00000000000..2019b787822 --- /dev/null +++ b/tests/baselines/reference/nestedCallbackErrorNotFlattened.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/nestedCallbackErrorNotFlattened.ts === +type Cb = {noAlias: () => T}["noAlias"]; // `"noAlias"` here prevents an alias symbol from being made +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) +>T : Symbol(T, Decl(nestedCallbackErrorNotFlattened.ts, 0, 8)) +>noAlias : Symbol(noAlias, Decl(nestedCallbackErrorNotFlattened.ts, 0, 14)) +>T : Symbol(T, Decl(nestedCallbackErrorNotFlattened.ts, 0, 8)) + +// which means the comparison will definitely be structural, rather than by variance + +declare const x: Cb>>>; // one more layer of `Cb` adn we'd get a `true` from the deeply-nested symbol check +>x : Symbol(x, Decl(nestedCallbackErrorNotFlattened.ts, 3, 13)) +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) + +declare let y: Cb>>>; +>y : Symbol(y, Decl(nestedCallbackErrorNotFlattened.ts, 4, 11)) +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) +>Cb : Symbol(Cb, Decl(nestedCallbackErrorNotFlattened.ts, 0, 0)) + +y = x; +>y : Symbol(y, Decl(nestedCallbackErrorNotFlattened.ts, 4, 11)) +>x : Symbol(x, Decl(nestedCallbackErrorNotFlattened.ts, 3, 13)) + diff --git a/tests/baselines/reference/nestedCallbackErrorNotFlattened.types b/tests/baselines/reference/nestedCallbackErrorNotFlattened.types new file mode 100644 index 00000000000..5e753714b34 --- /dev/null +++ b/tests/baselines/reference/nestedCallbackErrorNotFlattened.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/nestedCallbackErrorNotFlattened.ts === +type Cb = {noAlias: () => T}["noAlias"]; // `"noAlias"` here prevents an alias symbol from being made +>Cb : () => T +>noAlias : () => T + +// which means the comparison will definitely be structural, rather than by variance + +declare const x: Cb>>>; // one more layer of `Cb` adn we'd get a `true` from the deeply-nested symbol check +>x : () => () => () => () => number + +declare let y: Cb>>>; +>y : () => () => () => () => string + +y = x; +>y = x : () => () => () => () => number +>y : () => () => () => () => string +>x : () => () => () => () => number + diff --git a/tests/baselines/reference/nestedRecursiveArraysOrObjectsError01.errors.txt b/tests/baselines/reference/nestedRecursiveArraysOrObjectsError01.errors.txt index 138a4a84158..650a808e598 100644 --- a/tests/baselines/reference/nestedRecursiveArraysOrObjectsError01.errors.txt +++ b/tests/baselines/reference/nestedRecursiveArraysOrObjectsError01.errors.txt @@ -1,17 +1,14 @@ tests/cases/compiler/nestedRecursiveArraysOrObjectsError01.ts(10,9): error TS2322: Type '{ foo: string; jj: number; }[][][]' is not assignable to type 'Style'. Type '{ foo: string; jj: number; }[][][]' is not assignable to type 'StyleArray'. - Types of property 'pop' are incompatible. - Type '() => { foo: string; jj: number; }[][]' is not assignable to type '() => Style'. - Type '{ foo: string; jj: number; }[][]' is not assignable to type 'Style'. - Type '{ foo: string; jj: number; }[][]' is not assignable to type 'StyleArray'. - Types of property 'pop' are incompatible. - Type '() => { foo: string; jj: number; }[]' is not assignable to type '() => Style'. - Type '{ foo: string; jj: number; }[]' is not assignable to type 'Style'. - Type '{ foo: string; jj: number; }[]' is not assignable to type 'StyleArray'. - Types of property 'pop' are incompatible. - Type '() => { foo: string; jj: number; }' is not assignable to type '() => Style'. - Type '{ foo: string; jj: number; }' is not assignable to type 'Style'. - Object literal may only specify known properties, and 'jj' does not exist in type 'Style'. + The types returned by 'pop()' are incompatible between these types. + Type '{ foo: string; jj: number; }[][]' is not assignable to type 'Style'. + Type '{ foo: string; jj: number; }[][]' is not assignable to type 'StyleArray'. + The types returned by 'pop()' are incompatible between these types. + Type '{ foo: string; jj: number; }[]' is not assignable to type 'Style'. + Type '{ foo: string; jj: number; }[]' is not assignable to type 'StyleArray'. + The types returned by 'pop()' are incompatible between these types. + Type '{ foo: string; jj: number; }' is not assignable to type 'Style'. + Object literal may only specify known properties, and 'jj' does not exist in type 'Style'. ==== tests/cases/compiler/nestedRecursiveArraysOrObjectsError01.ts (1 errors) ==== @@ -28,18 +25,15 @@ tests/cases/compiler/nestedRecursiveArraysOrObjectsError01.ts(10,9): error TS232 ~~~~~ !!! error TS2322: Type '{ foo: string; jj: number; }[][][]' is not assignable to type 'Style'. !!! error TS2322: Type '{ foo: string; jj: number; }[][][]' is not assignable to type 'StyleArray'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => { foo: string; jj: number; }[][]' is not assignable to type '() => Style'. -!!! error TS2322: Type '{ foo: string; jj: number; }[][]' is not assignable to type 'Style'. -!!! error TS2322: Type '{ foo: string; jj: number; }[][]' is not assignable to type 'StyleArray'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => { foo: string; jj: number; }[]' is not assignable to type '() => Style'. -!!! error TS2322: Type '{ foo: string; jj: number; }[]' is not assignable to type 'Style'. -!!! error TS2322: Type '{ foo: string; jj: number; }[]' is not assignable to type 'StyleArray'. -!!! error TS2322: Types of property 'pop' are incompatible. -!!! error TS2322: Type '() => { foo: string; jj: number; }' is not assignable to type '() => Style'. -!!! error TS2322: Type '{ foo: string; jj: number; }' is not assignable to type 'Style'. -!!! error TS2322: Object literal may only specify known properties, and 'jj' does not exist in type 'Style'. +!!! error TS2322: The types returned by 'pop()' are incompatible between these types. +!!! error TS2322: Type '{ foo: string; jj: number; }[][]' is not assignable to type 'Style'. +!!! error TS2322: Type '{ foo: string; jj: number; }[][]' is not assignable to type 'StyleArray'. +!!! error TS2322: The types returned by 'pop()' are incompatible between these types. +!!! error TS2322: Type '{ foo: string; jj: number; }[]' is not assignable to type 'Style'. +!!! error TS2322: Type '{ foo: string; jj: number; }[]' is not assignable to type 'StyleArray'. +!!! error TS2322: The types returned by 'pop()' are incompatible between these types. +!!! error TS2322: Type '{ foo: string; jj: number; }' is not assignable to type 'Style'. +!!! error TS2322: Object literal may only specify known properties, and 'jj' does not exist in type 'Style'. }]] ]; diff --git a/tests/baselines/reference/objectTypeHidingMembersOfObjectAssignmentCompat.errors.txt b/tests/baselines/reference/objectTypeHidingMembersOfObjectAssignmentCompat.errors.txt index c4ee3ea17b2..d4afd97723e 100644 --- a/tests/baselines/reference/objectTypeHidingMembersOfObjectAssignmentCompat.errors.txt +++ b/tests/baselines/reference/objectTypeHidingMembersOfObjectAssignmentCompat.errors.txt @@ -1,15 +1,12 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat.ts(7,1): error TS2322: Type 'I' is not assignable to type 'Object'. - Types of property 'toString' are incompatible. - Type '() => void' is not assignable to type '() => string'. - Type 'void' is not assignable to type 'string'. + The types returned by 'toString()' are incompatible between these types. + Type 'void' is not assignable to type 'string'. tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat.ts(14,1): error TS2322: Type 'C' is not assignable to type 'Object'. - Types of property 'toString' are incompatible. - Type '() => void' is not assignable to type '() => string'. - Type 'void' is not assignable to type 'string'. + The types returned by 'toString()' are incompatible between these types. + Type 'void' is not assignable to type 'string'. tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat.ts(20,1): error TS2322: Type '{ toString: () => void; }' is not assignable to type 'Object'. - Types of property 'toString' are incompatible. - Type '() => void' is not assignable to type '() => string'. - Type 'void' is not assignable to type 'string'. + The types returned by 'toString()' are incompatible between these types. + Type 'void' is not assignable to type 'string'. ==== tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat.ts (3 errors) ==== @@ -22,9 +19,8 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentC o = i; // error ~ !!! error TS2322: Type 'I' is not assignable to type 'Object'. -!!! error TS2322: Types of property 'toString' are incompatible. -!!! error TS2322: Type '() => void' is not assignable to type '() => string'. -!!! error TS2322: Type 'void' is not assignable to type 'string'. +!!! error TS2322: The types returned by 'toString()' are incompatible between these types. +!!! error TS2322: Type 'void' is not assignable to type 'string'. i = o; // ok class C { @@ -34,9 +30,8 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentC o = c; // error ~ !!! error TS2322: Type 'C' is not assignable to type 'Object'. -!!! error TS2322: Types of property 'toString' are incompatible. -!!! error TS2322: Type '() => void' is not assignable to type '() => string'. -!!! error TS2322: Type 'void' is not assignable to type 'string'. +!!! error TS2322: The types returned by 'toString()' are incompatible between these types. +!!! error TS2322: Type 'void' is not assignable to type 'string'. c = o; // ok var a = { @@ -45,7 +40,6 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentC o = a; // error ~ !!! error TS2322: Type '{ toString: () => void; }' is not assignable to type 'Object'. -!!! error TS2322: Types of property 'toString' are incompatible. -!!! error TS2322: Type '() => void' is not assignable to type '() => string'. -!!! error TS2322: Type 'void' is not assignable to type 'string'. +!!! error TS2322: The types returned by 'toString()' are incompatible between these types. +!!! error TS2322: Type 'void' is not assignable to type 'string'. a = o; // ok \ No newline at end of file diff --git a/tests/baselines/reference/objectTypeHidingMembersOfObjectAssignmentCompat2.errors.txt b/tests/baselines/reference/objectTypeHidingMembersOfObjectAssignmentCompat2.errors.txt index 3e27b22240e..28d466457d7 100644 --- a/tests/baselines/reference/objectTypeHidingMembersOfObjectAssignmentCompat2.errors.txt +++ b/tests/baselines/reference/objectTypeHidingMembersOfObjectAssignmentCompat2.errors.txt @@ -1,25 +1,18 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat2.ts(7,1): error TS2322: Type 'I' is not assignable to type 'Object'. - Types of property 'toString' are incompatible. - Type '() => number' is not assignable to type '() => string'. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat2.ts(8,1): error TS2322: Type 'Object' is not assignable to type 'I'. - The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? - Types of property 'toString' are incompatible. - Type '() => string' is not assignable to type '() => number'. - Type 'string' is not assignable to type 'number'. + The types returned by 'toString()' are incompatible between these types. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat2.ts(8,1): error TS2696: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? + The types returned by 'toString()' are incompatible between these types. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat2.ts(14,1): error TS2322: Type 'C' is not assignable to type 'Object'. - Types of property 'toString' are incompatible. - Type '() => number' is not assignable to type '() => string'. - Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat2.ts(15,1): error TS2322: Type 'Object' is not assignable to type 'C'. - The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? - Types of property 'toString' are incompatible. - Type '() => string' is not assignable to type '() => number'. - Type 'string' is not assignable to type 'number'. + The types returned by 'toString()' are incompatible between these types. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat2.ts(15,1): error TS2696: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? + The types returned by 'toString()' are incompatible between these types. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat2.ts(20,1): error TS2322: Type '{ toString: () => void; }' is not assignable to type 'Object'. - Types of property 'toString' are incompatible. - Type '() => void' is not assignable to type '() => string'. - Type 'void' is not assignable to type 'string'. + The types returned by 'toString()' are incompatible between these types. + Type 'void' is not assignable to type 'string'. ==== tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentCompat2.ts (5 errors) ==== @@ -32,16 +25,13 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentC o = i; // error ~ !!! error TS2322: Type 'I' is not assignable to type 'Object'. -!!! error TS2322: Types of property 'toString' are incompatible. -!!! error TS2322: Type '() => number' is not assignable to type '() => string'. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: The types returned by 'toString()' are incompatible between these types. +!!! error TS2322: Type 'number' is not assignable to type 'string'. i = o; // error ~ -!!! error TS2322: Type 'Object' is not assignable to type 'I'. -!!! error TS2322: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? -!!! error TS2322: Types of property 'toString' are incompatible. -!!! error TS2322: Type '() => string' is not assignable to type '() => number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2696: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? +!!! error TS2696: The types returned by 'toString()' are incompatible between these types. +!!! error TS2696: Type 'string' is not assignable to type 'number'. class C { toString(): number { return 1; } @@ -50,16 +40,13 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentC o = c; // error ~ !!! error TS2322: Type 'C' is not assignable to type 'Object'. -!!! error TS2322: Types of property 'toString' are incompatible. -!!! error TS2322: Type '() => number' is not assignable to type '() => string'. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: The types returned by 'toString()' are incompatible between these types. +!!! error TS2322: Type 'number' is not assignable to type 'string'. c = o; // error ~ -!!! error TS2322: Type 'Object' is not assignable to type 'C'. -!!! error TS2322: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? -!!! error TS2322: Types of property 'toString' are incompatible. -!!! error TS2322: Type '() => string' is not assignable to type '() => number'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2696: The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? +!!! error TS2696: The types returned by 'toString()' are incompatible between these types. +!!! error TS2696: Type 'string' is not assignable to type 'number'. var a = { toString: () => { } @@ -67,7 +54,6 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfObjectAssignmentC o = a; // error ~ !!! error TS2322: Type '{ toString: () => void; }' is not assignable to type 'Object'. -!!! error TS2322: Types of property 'toString' are incompatible. -!!! error TS2322: Type '() => void' is not assignable to type '() => string'. -!!! error TS2322: Type 'void' is not assignable to type 'string'. +!!! error TS2322: The types returned by 'toString()' are incompatible between these types. +!!! error TS2322: Type 'void' is not assignable to type 'string'. a = o; // ok \ No newline at end of file diff --git a/tests/baselines/reference/promisePermutations.errors.txt b/tests/baselines/reference/promisePermutations.errors.txt index 1cb61562fe3..87743ab77a3 100644 --- a/tests/baselines/reference/promisePermutations.errors.txt +++ b/tests/baselines/reference/promisePermutations.errors.txt @@ -122,8 +122,8 @@ tests/cases/compiler/promisePermutations.ts(159,21): error TS2769: No overload m tests/cases/compiler/promisePermutations.ts(160,21): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => IPromise'. - Type 'Promise' is not assignable to type 'IPromise'. - Types of property 'then' are incompatible. + Call signature return types 'Promise' and 'IPromise' are incompatible. + The types of 'then' are incompatible between these types. Type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }' is not assignable to type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }'. Types of parameters 'onfulfilled' and 'success' are incompatible. Types of parameters 'value' and 'value' are incompatible. @@ -481,8 +481,8 @@ tests/cases/compiler/promisePermutations.ts(160,21): error TS2769: No overload m !!! error TS2769: No overload matches this call. !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => IPromise'. -!!! error TS2769: Type 'Promise' is not assignable to type 'IPromise'. -!!! error TS2769: Types of property 'then' are incompatible. +!!! error TS2769: Call signature return types 'Promise' and 'IPromise' are incompatible. +!!! error TS2769: The types of 'then' are incompatible between these types. !!! error TS2769: Type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }' is not assignable to type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }'. !!! error TS2769: Types of parameters 'onfulfilled' and 'success' are incompatible. !!! error TS2769: Types of parameters 'value' and 'value' are incompatible. diff --git a/tests/baselines/reference/promisePermutations2.errors.txt b/tests/baselines/reference/promisePermutations2.errors.txt index d601a5049bf..b69eaab3157 100644 --- a/tests/baselines/reference/promisePermutations2.errors.txt +++ b/tests/baselines/reference/promisePermutations2.errors.txt @@ -80,8 +80,8 @@ tests/cases/compiler/promisePermutations2.ts(158,21): error TS2345: Argument of Type 'Promise' is not assignable to type 'Promise'. Type 'number' is not assignable to type 'string'. tests/cases/compiler/promisePermutations2.ts(159,21): error TS2345: Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => IPromise'. - Type 'Promise' is not assignable to type 'IPromise'. - Types of property 'then' are incompatible. + Call signature return types 'Promise' and 'IPromise' are incompatible. + The types of 'then' are incompatible between these types. Type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }' is not assignable to type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }'. Types of parameters 'onfulfilled' and 'success' are incompatible. Types of parameters 'value' and 'value' are incompatible. @@ -376,8 +376,8 @@ tests/cases/compiler/promisePermutations2.ts(159,21): error TS2345: Argument of var s11c = s11.then(testFunction11P, testFunction11, testFunction11); // ok ~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => IPromise'. -!!! error TS2345: Type 'Promise' is not assignable to type 'IPromise'. -!!! error TS2345: Types of property 'then' are incompatible. +!!! error TS2345: Call signature return types 'Promise' and 'IPromise' are incompatible. +!!! error TS2345: The types of 'then' are incompatible between these types. !!! error TS2345: Type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }' is not assignable to type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }'. !!! error TS2345: Types of parameters 'onfulfilled' and 'success' are incompatible. !!! error TS2345: Types of parameters 'value' and 'value' are incompatible. diff --git a/tests/baselines/reference/promisePermutations3.errors.txt b/tests/baselines/reference/promisePermutations3.errors.txt index d3574d2a4c3..929b0d5459c 100644 --- a/tests/baselines/reference/promisePermutations3.errors.txt +++ b/tests/baselines/reference/promisePermutations3.errors.txt @@ -101,8 +101,8 @@ tests/cases/compiler/promisePermutations3.ts(158,21): error TS2769: No overload tests/cases/compiler/promisePermutations3.ts(159,21): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => IPromise'. - Type 'Promise' is not assignable to type 'IPromise'. - Types of property 'then' are incompatible. + Call signature return types 'Promise' and 'IPromise' are incompatible. + The types of 'then' are incompatible between these types. Type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }' is not assignable to type '(success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise'. Types of parameters 'onfulfilled' and 'success' are incompatible. Types of parameters 'value' and 'value' are incompatible. @@ -429,8 +429,8 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of !!! error TS2769: No overload matches this call. !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => IPromise'. -!!! error TS2769: Type 'Promise' is not assignable to type 'IPromise'. -!!! error TS2769: Types of property 'then' are incompatible. +!!! error TS2769: Call signature return types 'Promise' and 'IPromise' are incompatible. +!!! error TS2769: The types of 'then' are incompatible between these types. !!! error TS2769: Type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }' is not assignable to type '(success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise'. !!! error TS2769: Types of parameters 'onfulfilled' and 'success' are incompatible. !!! error TS2769: Types of parameters 'value' and 'value' are incompatible. diff --git a/tests/baselines/reference/promiseTypeInference.errors.txt b/tests/baselines/reference/promiseTypeInference.errors.txt index 04ba3a0d878..7056e35432f 100644 --- a/tests/baselines/reference/promiseTypeInference.errors.txt +++ b/tests/baselines/reference/promiseTypeInference.errors.txt @@ -5,10 +5,9 @@ tests/cases/compiler/promiseTypeInference.ts(10,39): error TS2769: No overload m Type 'IPromise' is not assignable to type 'number | PromiseLike'. Type 'IPromise' is not assignable to type 'PromiseLike'. Types of property 'then' are incompatible. - Type '(success?: (value: number) => IPromise) => IPromise' is not assignable to type '(onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. - Types of parameters 'success' and 'onfulfilled' are incompatible. - Type 'TResult1 | PromiseLike' is not assignable to type 'IPromise'. - Type 'TResult1' is not assignable to type 'IPromise'. + Types of parameters 'success' and 'onfulfilled' are incompatible. + Type 'TResult1 | PromiseLike' is not assignable to type 'IPromise'. + Type 'TResult1' is not assignable to type 'IPromise'. ==== tests/cases/compiler/promiseTypeInference.ts (1 errors) ==== @@ -30,10 +29,9 @@ tests/cases/compiler/promiseTypeInference.ts(10,39): error TS2769: No overload m !!! error TS2769: Type 'IPromise' is not assignable to type 'number | PromiseLike'. !!! error TS2769: Type 'IPromise' is not assignable to type 'PromiseLike'. !!! error TS2769: Types of property 'then' are incompatible. -!!! error TS2769: Type '(success?: (value: number) => IPromise) => IPromise' is not assignable to type '(onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. -!!! error TS2769: Types of parameters 'success' and 'onfulfilled' are incompatible. -!!! error TS2769: Type 'TResult1 | PromiseLike' is not assignable to type 'IPromise'. -!!! error TS2769: Type 'TResult1' is not assignable to type 'IPromise'. +!!! error TS2769: Types of parameters 'success' and 'onfulfilled' are incompatible. +!!! error TS2769: Type 'TResult1 | PromiseLike' is not assignable to type 'IPromise'. +!!! error TS2769: Type 'TResult1' is not assignable to type 'IPromise'. !!! related TS2728 /.ts/lib.es5.d.ts:1413:5: 'catch' is declared here. !!! related TS6502 tests/cases/compiler/promiseTypeInference.ts:2:23: The expected type comes from the return type of this signature. !!! related TS6502 /.ts/lib.es5.d.ts:1406:57: The expected type comes from the return type of this signature. diff --git a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt index 3ff04c44fb7..6f474663dcb 100644 --- a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt +++ b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt @@ -69,9 +69,8 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(126,1): error TS2322: Type 'Cr tests/cases/compiler/strictFunctionTypesErrors.ts(127,1): error TS2322: Type 'Crate' is not assignable to type 'Crate'. Types of property 'item' are incompatible. Type 'Animal' is not assignable to type 'Dog'. -tests/cases/compiler/strictFunctionTypesErrors.ts(133,1): error TS2322: Type '(f: (x: Dog) => Dog) => void' is not assignable to type '(f: (x: Animal) => Animal) => void'. - Types of parameters 'f' and 'f' are incompatible. - Type 'Animal' is not assignable to type 'Dog'. +tests/cases/compiler/strictFunctionTypesErrors.ts(133,1): error TS2328: Types of parameters 'f' and 'f' are incompatible. + Type 'Animal' is not assignable to type 'Dog'. tests/cases/compiler/strictFunctionTypesErrors.ts(134,1): error TS2322: Type '(f: (x: Animal) => Animal) => void' is not assignable to type '(f: (x: Dog) => Dog) => void'. Types of parameters 'f' and 'f' are incompatible. Types of parameters 'x' and 'x' are incompatible. @@ -324,9 +323,8 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c declare let fc2: (f: (x: Dog) => Dog) => void; fc1 = fc2; // Error ~~~ -!!! error TS2322: Type '(f: (x: Dog) => Dog) => void' is not assignable to type '(f: (x: Animal) => Animal) => void'. -!!! error TS2322: Types of parameters 'f' and 'f' are incompatible. -!!! error TS2322: Type 'Animal' is not assignable to type 'Dog'. +!!! error TS2328: Types of parameters 'f' and 'f' are incompatible. +!!! error TS2328: Type 'Animal' is not assignable to type 'Dog'. fc2 = fc1; // Error ~~~ !!! error TS2322: Type '(f: (x: Animal) => Animal) => void' is not assignable to type '(f: (x: Dog) => Dog) => void'. diff --git a/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt b/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt index 7dfb078170a..b8bc5100402 100644 --- a/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt +++ b/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt @@ -1,12 +1,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts(70,15): error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. - Types of property 'a' are incompatible. - Type '(x: string) => string' is not assignable to type '{ (x: "a"): number; (x: string): number; }'. - Type 'string' is not assignable to type 'number'. + The types returned by 'a(...)' are incompatible between these types. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts(76,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. - Types of property 'a2' are incompatible. - Type '(x: T) => string' is not assignable to type '(x: T) => T'. - Type 'string' is not assignable to type 'T'. - 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a2(...)' are incompatible between these types. + Type 'string' is not assignable to type 'T'. + 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts (2 errors) ==== @@ -82,9 +80,8 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I2 extends Base2 { ~~ !!! error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type '(x: string) => string' is not assignable to type '{ (x: "a"): number; (x: string): number; }'. -!!! error TS2430: Type 'string' is not assignable to type 'number'. +!!! error TS2430: The types returned by 'a(...)' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'number'. // N's a: (x: string) => string; // error because base returns non-void; } @@ -93,10 +90,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I3 extends Base2 { ~~ !!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type '(x: T) => string' is not assignable to type '(x: T) => T'. -!!! error TS2430: Type 'string' is not assignable to type 'T'. -!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a2(...)' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'T'. +!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. // N's a2: (x: T) => string; // error because base returns non-void; } diff --git a/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt b/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt index 8f4a219407a..db493045f09 100644 --- a/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt +++ b/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt @@ -1,12 +1,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts(70,15): error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. - Types of property 'a' are incompatible. - Type 'new (x: string) => string' is not assignable to type '{ new (x: "a"): number; new (x: string): number; }'. - Type 'string' is not assignable to type 'number'. + The types returned by 'new a(...)' are incompatible between these types. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts(76,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. - Types of property 'a2' are incompatible. - Type 'new (x: T) => string' is not assignable to type 'new (x: T) => T'. - Type 'string' is not assignable to type 'T'. - 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a2(...)' are incompatible between these types. + Type 'string' is not assignable to type 'T'. + 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts (2 errors) ==== @@ -82,9 +80,8 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I2 extends Base2 { ~~ !!! error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type 'new (x: string) => string' is not assignable to type '{ new (x: "a"): number; new (x: string): number; }'. -!!! error TS2430: Type 'string' is not assignable to type 'number'. +!!! error TS2430: The types returned by 'new a(...)' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'number'. // N's a: new (x: string) => string; // error because base returns non-void; } @@ -93,10 +90,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I3 extends Base2 { ~~ !!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type 'new (x: T) => string' is not assignable to type 'new (x: T) => T'. -!!! error TS2430: Type 'string' is not assignable to type 'T'. -!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a2(...)' are incompatible between these types. +!!! error TS2430: Type 'string' is not assignable to type 'T'. +!!! error TS2430: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. // N's a2: new (x: T) => string; // error because base returns non-void; } diff --git a/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt b/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt index 36380fc97f4..4e0ef2113ec 100644 --- a/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt +++ b/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt @@ -5,23 +5,20 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Types of property 'a3' are incompatible. Type '(x: T, y: T) => T' is not assignable to type '(x: T) => T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(100,15): error TS2430: Interface 'I1' incorrectly extends interface 'Base2'. - Types of property 'a' are incompatible. - Type '() => T' is not assignable to type '() => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a()' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(104,15): error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. - Types of property 'a' are incompatible. - Type '(x?: T) => T' is not assignable to type '() => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(108,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. Types of property 'a' are incompatible. Type '(x: T) => T' is not assignable to type '() => T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(113,15): error TS2430: Interface 'I4' incorrectly extends interface 'Base2'. - Types of property 'a2' are incompatible. - Type '() => T' is not assignable to type '(x?: T) => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a2(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(117,15): error TS2430: Interface 'I5' incorrectly extends interface 'Base2'. Types of property 'a2' are incompatible. Type '(x?: T) => T' is not assignable to type '(x?: T) => T'. @@ -35,10 +32,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(126,15): error TS2430: Interface 'I7' incorrectly extends interface 'Base2'. - Types of property 'a3' are incompatible. - Type '() => T' is not assignable to type '(x: T) => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a3(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(130,15): error TS2430: Interface 'I8' incorrectly extends interface 'Base2'. Types of property 'a3' are incompatible. Type '(x?: T) => T' is not assignable to type '(x: T) => T'. @@ -55,10 +51,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Types of property 'a3' are incompatible. Type '(x: T, y: T) => T' is not assignable to type '(x: T) => T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(143,15): error TS2430: Interface 'I11' incorrectly extends interface 'Base2'. - Types of property 'a4' are incompatible. - Type '() => T' is not assignable to type '(x: T, y?: T) => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a4(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(147,15): error TS2430: Interface 'I12' incorrectly extends interface 'Base2'. Types of property 'a4' are incompatible. Type '(x?: T, y?: T) => T' is not assignable to type '(x: T, y?: T) => T'. @@ -78,10 +73,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(160,15): error TS2430: Interface 'I15' incorrectly extends interface 'Base2'. - Types of property 'a5' are incompatible. - Type '() => T' is not assignable to type '(x?: T, y?: T) => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'a5(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(164,15): error TS2430: Interface 'I16' incorrectly extends interface 'Base2'. Types of property 'a5' are incompatible. Type '(x?: T, y?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. @@ -219,20 +213,18 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I1 extends Base2 { ~~ !!! error TS2430: Interface 'I1' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type '() => T' is not assignable to type '() => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a()' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a: () => T; } interface I2 extends Base2 { ~~ !!! error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type '(x?: T) => T' is not assignable to type '() => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a: (x?: T) => T; } @@ -248,10 +240,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I4 extends Base2 { ~~ !!! error TS2430: Interface 'I4' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type '() => T' is not assignable to type '(x?: T) => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a2(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a2: () => T; } @@ -281,10 +272,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I7 extends Base2 { ~~ !!! error TS2430: Interface 'I7' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a3' are incompatible. -!!! error TS2430: Type '() => T' is not assignable to type '(x: T) => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a3(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a3: () => T; } @@ -322,10 +312,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I11 extends Base2 { ~~~ !!! error TS2430: Interface 'I11' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a4' are incompatible. -!!! error TS2430: Type '() => T' is not assignable to type '(x: T, y?: T) => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a4(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a4: () => T; } @@ -366,10 +355,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I15 extends Base2 { ~~~ !!! error TS2430: Interface 'I15' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a5' are incompatible. -!!! error TS2430: Type '() => T' is not assignable to type '(x?: T, y?: T) => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'a5(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a5: () => T; } diff --git a/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt b/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt index 427c7c1f19e..7481ba54f1e 100644 --- a/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt +++ b/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt @@ -5,23 +5,20 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Types of property 'a3' are incompatible. Type 'new (x: T, y: T) => T' is not assignable to type 'new (x: T) => T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(100,15): error TS2430: Interface 'I1' incorrectly extends interface 'Base2'. - Types of property 'a' are incompatible. - Type 'new () => T' is not assignable to type 'new () => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a()' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(104,15): error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. - Types of property 'a' are incompatible. - Type 'new (x?: T) => T' is not assignable to type 'new () => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(108,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. Types of property 'a' are incompatible. Type 'new (x: T) => T' is not assignable to type 'new () => T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(113,15): error TS2430: Interface 'I4' incorrectly extends interface 'Base2'. - Types of property 'a2' are incompatible. - Type 'new () => T' is not assignable to type 'new (x?: T) => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a2(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(117,15): error TS2430: Interface 'I5' incorrectly extends interface 'Base2'. Types of property 'a2' are incompatible. Type 'new (x?: T) => T' is not assignable to type 'new (x?: T) => T'. @@ -35,10 +32,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(126,15): error TS2430: Interface 'I7' incorrectly extends interface 'Base2'. - Types of property 'a3' are incompatible. - Type 'new () => T' is not assignable to type 'new (x: T) => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a3(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(130,15): error TS2430: Interface 'I8' incorrectly extends interface 'Base2'. Types of property 'a3' are incompatible. Type 'new (x?: T) => T' is not assignable to type 'new (x: T) => T'. @@ -55,10 +51,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Types of property 'a3' are incompatible. Type 'new (x: T, y: T) => T' is not assignable to type 'new (x: T) => T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(143,15): error TS2430: Interface 'I11' incorrectly extends interface 'Base2'. - Types of property 'a4' are incompatible. - Type 'new () => T' is not assignable to type 'new (x: T, y?: T) => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a4(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(147,15): error TS2430: Interface 'I12' incorrectly extends interface 'Base2'. Types of property 'a4' are incompatible. Type 'new (x?: T, y?: T) => T' is not assignable to type 'new (x: T, y?: T) => T'. @@ -78,10 +73,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(160,15): error TS2430: Interface 'I15' incorrectly extends interface 'Base2'. - Types of property 'a5' are incompatible. - Type 'new () => T' is not assignable to type 'new (x?: T, y?: T) => T'. - Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. - 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. + The types returned by 'new a5(...)' are incompatible between these types. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(164,15): error TS2430: Interface 'I16' incorrectly extends interface 'Base2'. Types of property 'a5' are incompatible. Type 'new (x?: T, y?: T) => T' is not assignable to type 'new (x?: T, y?: T) => T'. @@ -219,20 +213,18 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I1 extends Base2 { ~~ !!! error TS2430: Interface 'I1' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type 'new () => T' is not assignable to type 'new () => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a()' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a: new () => T; } interface I2 extends Base2 { ~~ !!! error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a' are incompatible. -!!! error TS2430: Type 'new (x?: T) => T' is not assignable to type 'new () => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a: new (x?: T) => T; } @@ -248,10 +240,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I4 extends Base2 { ~~ !!! error TS2430: Interface 'I4' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a2' are incompatible. -!!! error TS2430: Type 'new () => T' is not assignable to type 'new (x?: T) => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a2(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a2: new () => T; } @@ -281,10 +272,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I7 extends Base2 { ~~ !!! error TS2430: Interface 'I7' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a3' are incompatible. -!!! error TS2430: Type 'new () => T' is not assignable to type 'new (x: T) => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a3(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a3: new () => T; } @@ -322,10 +312,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I11 extends Base2 { ~~~ !!! error TS2430: Interface 'I11' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a4' are incompatible. -!!! error TS2430: Type 'new () => T' is not assignable to type 'new (x: T, y?: T) => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a4(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a4: new () => T; } @@ -366,10 +355,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I15 extends Base2 { ~~~ !!! error TS2430: Interface 'I15' incorrectly extends interface 'Base2'. -!!! error TS2430: Types of property 'a5' are incompatible. -!!! error TS2430: Type 'new () => T' is not assignable to type 'new (x?: T, y?: T) => T'. -!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. -!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. +!!! error TS2430: The types returned by 'new a5(...)' are incompatible between these types. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: 'T' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. a5: new () => T; } diff --git a/tests/baselines/reference/typeParameterArgumentEquivalence5.errors.txt b/tests/baselines/reference/typeParameterArgumentEquivalence5.errors.txt index e5196d3d4a5..b832ce6cb7c 100644 --- a/tests/baselines/reference/typeParameterArgumentEquivalence5.errors.txt +++ b/tests/baselines/reference/typeParameterArgumentEquivalence5.errors.txt @@ -1,9 +1,9 @@ tests/cases/compiler/typeParameterArgumentEquivalence5.ts(4,5): error TS2322: Type '() => (item: any) => T' is not assignable to type '() => (item: any) => U'. - Type '(item: any) => T' is not assignable to type '(item: any) => U'. + Call signature return types '(item: any) => T' and '(item: any) => U' are incompatible. Type 'T' is not assignable to type 'U'. 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint '{}'. tests/cases/compiler/typeParameterArgumentEquivalence5.ts(5,5): error TS2322: Type '() => (item: any) => U' is not assignable to type '() => (item: any) => T'. - Type '(item: any) => U' is not assignable to type '(item: any) => T'. + Call signature return types '(item: any) => U' and '(item: any) => T' are incompatible. Type 'U' is not assignable to type 'T'. 'U' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. @@ -15,13 +15,13 @@ tests/cases/compiler/typeParameterArgumentEquivalence5.ts(5,5): error TS2322: Ty x = y; // Should be an error ~ !!! error TS2322: Type '() => (item: any) => T' is not assignable to type '() => (item: any) => U'. -!!! error TS2322: Type '(item: any) => T' is not assignable to type '(item: any) => U'. +!!! error TS2322: Call signature return types '(item: any) => T' and '(item: any) => U' are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'U'. !!! error TS2322: 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint '{}'. y = x; // Shound be an error ~ !!! error TS2322: Type '() => (item: any) => U' is not assignable to type '() => (item: any) => T'. -!!! error TS2322: Type '(item: any) => U' is not assignable to type '(item: any) => T'. +!!! error TS2322: Call signature return types '(item: any) => U' and '(item: any) => T' are incompatible. !!! error TS2322: Type 'U' is not assignable to type 'T'. !!! error TS2322: 'U' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'. } diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt index 9f22060b9e9..3d588abf1ee 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt +++ b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt @@ -1,39 +1,29 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(2,12): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(8,12): error TS2504: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(10,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. - Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. - Type 'Promise>' is not assignable to type 'Promise>'. - Type 'IteratorResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. - Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. - Type 'string' is not assignable to type 'number'. + Call signature return types 'AsyncGenerator' and 'AsyncIterableIterator' are incompatible. + The types returned by 'next(...)' are incompatible between these types. + Type 'Promise>' is not assignable to type 'Promise>'. + Type 'IteratorResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(13,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(16,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. - Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. - Type 'Promise>' is not assignable to type 'Promise>'. + Call signature return types 'AsyncGenerator' and 'AsyncIterableIterator' are incompatible. + The types returned by 'next(...)' are incompatible between these types. + Type 'Promise>' is not assignable to type 'Promise>'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(19,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterable'. - Type 'AsyncGenerator' is not assignable to type 'AsyncIterable'. - Types of property '[Symbol.asyncIterator]' are incompatible. - Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. - Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. - Type 'Promise>' is not assignable to type 'Promise>'. + Call signature return types 'AsyncGenerator' and 'AsyncIterable' are incompatible. + The types returned by '[Symbol.asyncIterator]().next(...)' are incompatible between these types. + Type 'Promise>' is not assignable to type 'Promise>'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(22,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterable'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterable'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(25,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterable'. - Type 'AsyncGenerator' is not assignable to type 'AsyncIterable'. - Types of property '[Symbol.asyncIterator]' are incompatible. - Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. - Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. - Type 'Promise>' is not assignable to type 'Promise>'. + Call signature return types 'AsyncGenerator' and 'AsyncIterable' are incompatible. + The types returned by '[Symbol.asyncIterator]().next(...)' are incompatible between these types. + Type 'Promise>' is not assignable to type 'Promise>'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(28,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(31,7): error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. @@ -52,10 +42,9 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(64,42): error TS2741: Property '[Symbol.iterator]' is missing in type 'AsyncGenerator' but required in type 'IterableIterator'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(67,42): error TS2741: Property '[Symbol.iterator]' is missing in type 'AsyncGenerator' but required in type 'Iterable'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(70,42): error TS2322: Type 'AsyncGenerator' is not assignable to type 'Iterator'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. - Type 'Promise>' is not assignable to type 'IteratorResult'. - Property 'value' is missing in type 'Promise>' but required in type 'IteratorYieldResult'. + The types returned by 'next(...)' are incompatible between these types. + Type 'Promise>' is not assignable to type 'IteratorResult'. + Property 'value' is missing in type 'Promise>' but required in type 'IteratorYieldResult'. tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts(74,12): error TS2504: Type '{}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. @@ -77,14 +66,13 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( const assignability1: () => AsyncIterableIterator = async function * () { ~~~~~~~~~~~~~~ !!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. -!!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. -!!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. -!!! error TS2322: Type 'IteratorResult' is not assignable to type 'IteratorResult'. -!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. -!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Call signature return types 'AsyncGenerator' and 'AsyncIterableIterator' are incompatible. +!!! error TS2322: The types returned by 'next(...)' are incompatible between these types. +!!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. +!!! error TS2322: Type 'IteratorResult' is not assignable to type 'IteratorResult'. +!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. +!!! error TS2322: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. yield "a"; }; const assignability2: () => AsyncIterableIterator = async function * () { @@ -96,22 +84,17 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( const assignability3: () => AsyncIterableIterator = async function * () { ~~~~~~~~~~~~~~ !!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterableIterator'. -!!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterableIterator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. -!!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. +!!! error TS2322: Call signature return types 'AsyncGenerator' and 'AsyncIterableIterator' are incompatible. +!!! error TS2322: The types returned by 'next(...)' are incompatible between these types. +!!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. yield* (async function * () { yield "a"; })(); }; const assignability4: () => AsyncIterable = async function * () { ~~~~~~~~~~~~~~ !!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterable'. -!!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterable'. -!!! error TS2322: Types of property '[Symbol.asyncIterator]' are incompatible. -!!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. -!!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. -!!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. +!!! error TS2322: Call signature return types 'AsyncGenerator' and 'AsyncIterable' are incompatible. +!!! error TS2322: The types returned by '[Symbol.asyncIterator]().next(...)' are incompatible between these types. +!!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. yield "a"; }; const assignability5: () => AsyncIterable = async function * () { @@ -123,13 +106,9 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( const assignability6: () => AsyncIterable = async function * () { ~~~~~~~~~~~~~~ !!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterable'. -!!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterable'. -!!! error TS2322: Types of property '[Symbol.asyncIterator]' are incompatible. -!!! error TS2322: Type '() => AsyncGenerator' is not assignable to type '() => AsyncIterator'. -!!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'AsyncIterator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [unknown]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => Promise>'. -!!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. +!!! error TS2322: Call signature return types 'AsyncGenerator' and 'AsyncIterable' are incompatible. +!!! error TS2322: The types returned by '[Symbol.asyncIterator]().next(...)' are incompatible between these types. +!!! error TS2322: Type 'Promise>' is not assignable to type 'Promise>'. yield* (async function * () { yield "a"; })(); }; const assignability7: () => AsyncIterator = async function * () { @@ -210,10 +189,9 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( async function * explicitReturnType12(): Iterator { ~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'AsyncGenerator' is not assignable to type 'Iterator'. -!!! error TS2322: Types of property 'next' are incompatible. -!!! error TS2322: Type '(...args: [] | [undefined]) => Promise>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult'. -!!! error TS2322: Type 'Promise>' is not assignable to type 'IteratorResult'. -!!! error TS2322: Property 'value' is missing in type 'Promise>' but required in type 'IteratorYieldResult'. +!!! error TS2322: The types returned by 'next(...)' are incompatible between these types. +!!! error TS2322: Type 'Promise>' is not assignable to type 'IteratorResult'. +!!! error TS2322: Property 'value' is missing in type 'Promise>' but required in type 'IteratorYieldResult'. !!! related TS2728 /.ts/lib.es2015.iterable.d.ts:33:5: 'value' is declared here. yield 1; } diff --git a/tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts b/tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts new file mode 100644 index 00000000000..d802c707830 --- /dev/null +++ b/tests/cases/compiler/deeplyNestedAssignabilityErrorsCombined.ts @@ -0,0 +1,15 @@ +let x = { a: { b: { c: { d: { e: { f() { return { g: "hello" }; } } } } } } }; +let y = { a: { b: { c: { d: { e: { f() { return { g: 12345 }; } } } } } } }; +x = y; + +class Ctor1 { + g = "ok" +} + +class Ctor2 { + g = 12; +} + +let x2 = { a: { b: { c: { d: { e: { f: Ctor1 } } } } } }; +let y2 = { a: { b: { c: { d: { e: { f: Ctor2 } } } } } }; +x2 = y2; \ No newline at end of file diff --git a/tests/cases/compiler/nestedCallbackErrorNotFlattened.ts b/tests/cases/compiler/nestedCallbackErrorNotFlattened.ts new file mode 100644 index 00000000000..76a1fabdf6e --- /dev/null +++ b/tests/cases/compiler/nestedCallbackErrorNotFlattened.ts @@ -0,0 +1,7 @@ +// @strict: true +type Cb = {noAlias: () => T}["noAlias"]; // `"noAlias"` here prevents an alias symbol from being made +// which means the comparison will definitely be structural, rather than by variance + +declare const x: Cb>>>; // one more layer of `Cb` adn we'd get a `true` from the deeply-nested symbol check +declare let y: Cb>>>; +y = x; \ No newline at end of file From 367b82055cf231948901e472cb3531450a8e0d70 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Sep 2019 16:52:03 -0700 Subject: [PATCH 095/100] =?UTF-8?q?Hoist=20and=20distribute=20type=20param?= =?UTF-8?q?eter=20constraints=20over=20type=20parameters=20=E2=80=A6=20(#3?= =?UTF-8?q?3453)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Hoist and distribute type parameter constraints over type parameters when comparing against union targets when fetching union constraints * Fix PR nits --- src/compiler/checker.ts | 26 ++++++++---- ...intersectionWithUnionConstraint.errors.txt | 40 +++++-------------- .../keyofAndIndexedAccessErrors.errors.txt | 8 ---- ...ameterExtendsUnionConstraintDistributed.js | 11 +++++ ...rExtendsUnionConstraintDistributed.symbols | 32 +++++++++++++++ ...terExtendsUnionConstraintDistributed.types | 17 ++++++++ ...ameterExtendsUnionConstraintDistributed.ts | 5 +++ 7 files changed, 93 insertions(+), 46 deletions(-) create mode 100644 tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.js create mode 100644 tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.symbols create mode 100644 tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.types create mode 100644 tests/cases/conformance/jsdoc/typeParameterExtendsUnionConstraintDistributed.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index de5c3b5b358..b3f88661a8c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7965,10 +7965,10 @@ namespace ts { return hasNonCircularBaseConstraint(type) ? getConstraintFromConditionalType(type) : undefined; } - function getUnionConstraintOfIntersection(type: IntersectionType, targetIsUnion: boolean) { + function getEffectiveConstraintOfIntersection(types: readonly Type[], targetIsUnion: boolean) { let constraints: Type[] | undefined; let hasDisjointDomainType = false; - for (const t of type.types) { + for (const t of types) { if (t.flags & TypeFlags.Instantiable) { // We keep following constraints as long as we have an instantiable type that is known // not to be circular or infinite (hence we stop on index access types). @@ -7978,6 +7978,9 @@ namespace ts { } if (constraint) { constraints = append(constraints, constraint); + if (targetIsUnion) { + constraints = append(constraints, t); + } } } else if (t.flags & TypeFlags.DisjointDomains) { @@ -7990,7 +7993,7 @@ namespace ts { if (hasDisjointDomainType) { // We add any types belong to one of the disjoint domains because they might cause the final // intersection operation to reduce the union constraints. - for (const t of type.types) { + for (const t of types) { if (t.flags & TypeFlags.DisjointDomains) { constraints = append(constraints, t); } @@ -13089,7 +13092,7 @@ namespace ts { } } } - if (!result && source.flags & TypeFlags.Intersection) { + if (!result && source.flags & (TypeFlags.Intersection | TypeFlags.TypeParameter)) { // The combined constraint of an intersection type is the intersection of the constraints of // the constituents. When an intersection type contains instantiable types with union type // constraints, there are situations where we need to examine the combined constraint. One is @@ -13099,10 +13102,17 @@ namespace ts { // we need to check this constraint against a union on the target side. Also, given a type // variable V constrained to 'string | number', 'V & number' has a combined constraint of // 'string & number | number & number' which reduces to just 'number'. - const constraint = getUnionConstraintOfIntersection(source, !!(target.flags & TypeFlags.Union)); - if (constraint) { - if (result = isRelatedTo(constraint, target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) { - resetErrorInfo(saveErrorInfo); + // This also handles type parameters, as a type parameter with a union constraint compared against a union + // needs to have its constraint hoisted into an intersection with said type parameter, this way + // the type param can be compared with itself in the target (with the influence of its constraint to match other parts) + // For example, if `T extends 1 | 2` and `U extends 2 | 3` and we compare `T & U` to `T & U & (1 | 2 | 3)` + const constraint = getEffectiveConstraintOfIntersection(source.flags & TypeFlags.Intersection ? (source).types: [source], !!(target.flags & TypeFlags.Union)); + if (constraint && (source.flags & TypeFlags.Intersection || target.flags & TypeFlags.Union)) { + if (everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself + // TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this + if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) { + resetErrorInfo(saveErrorInfo); + } } } } diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt b/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt index 97ed1cf4895..7bc436915a1 100644 --- a/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt +++ b/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt @@ -1,23 +1,13 @@ tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(7,9): error TS2322: Type 'T & U' is not assignable to type 'string | number'. - Type 'string | undefined' is not assignable to type 'string | number'. - Type 'undefined' is not assignable to type 'string | number'. - Type 'T & U' is not assignable to type 'number'. + Type 'T & U' is not assignable to type 'number'. tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(8,9): error TS2322: Type 'T & U' is not assignable to type 'string | null'. - Type 'string | undefined' is not assignable to type 'string | null'. - Type 'undefined' is not assignable to type 'string | null'. - Type 'T & U' is not assignable to type 'string'. + Type 'T & U' is not assignable to type 'string'. tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(10,9): error TS2322: Type 'T & U' is not assignable to type 'number | null'. - Type 'string | undefined' is not assignable to type 'number | null'. - Type 'undefined' is not assignable to type 'number | null'. - Type 'T & U' is not assignable to type 'number'. + Type 'T & U' is not assignable to type 'number'. tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(11,9): error TS2322: Type 'T & U' is not assignable to type 'number | undefined'. - Type 'string | undefined' is not assignable to type 'number | undefined'. - Type 'string' is not assignable to type 'number | undefined'. - Type 'T & U' is not assignable to type 'number'. + Type 'T & U' is not assignable to type 'number'. tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12,9): error TS2322: Type 'T & U' is not assignable to type 'null | undefined'. - Type 'string | undefined' is not assignable to type 'null | undefined'. - Type 'string' is not assignable to type 'null | undefined'. - Type 'T & U' is not assignable to type 'null'. + Type 'T & U' is not assignable to type 'null'. ==== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts (5 errors) ==== @@ -30,34 +20,24 @@ tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12 let y1: string | number = x; // Error ~~ !!! error TS2322: Type 'T & U' is not assignable to type 'string | number'. -!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | number'. -!!! error TS2322: Type 'undefined' is not assignable to type 'string | number'. -!!! error TS2322: Type 'T & U' is not assignable to type 'number'. +!!! error TS2322: Type 'T & U' is not assignable to type 'number'. let y2: string | null = x; // Error ~~ !!! error TS2322: Type 'T & U' is not assignable to type 'string | null'. -!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | null'. -!!! error TS2322: Type 'undefined' is not assignable to type 'string | null'. -!!! error TS2322: Type 'T & U' is not assignable to type 'string'. +!!! error TS2322: Type 'T & U' is not assignable to type 'string'. let y3: string | undefined = x; let y4: number | null = x; // Error ~~ !!! error TS2322: Type 'T & U' is not assignable to type 'number | null'. -!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | null'. -!!! error TS2322: Type 'undefined' is not assignable to type 'number | null'. -!!! error TS2322: Type 'T & U' is not assignable to type 'number'. +!!! error TS2322: Type 'T & U' is not assignable to type 'number'. let y5: number | undefined = x; // Error ~~ !!! error TS2322: Type 'T & U' is not assignable to type 'number | undefined'. -!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | undefined'. -!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'. -!!! error TS2322: Type 'T & U' is not assignable to type 'number'. +!!! error TS2322: Type 'T & U' is not assignable to type 'number'. let y6: null | undefined = x; // Error ~~ !!! error TS2322: Type 'T & U' is not assignable to type 'null | undefined'. -!!! error TS2322: Type 'string | undefined' is not assignable to type 'null | undefined'. -!!! error TS2322: Type 'string' is not assignable to type 'null | undefined'. -!!! error TS2322: Type 'T & U' is not assignable to type 'null'. +!!! error TS2322: Type 'T & U' is not assignable to type 'null'. } type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 69f992447e8..bb628d4f4fb 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -48,8 +48,6 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(103,9): error 'string & keyof T' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. Type 'string' is not assignable to type 'K'. 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. - Type 'string' is not assignable to type 'K'. - 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(105,9): error TS2322: Type 'T[Extract]' is not assignable to type 'T[K]'. Type 'Extract' is not assignable to type 'K'. 'Extract' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. @@ -68,8 +66,6 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(114,5): error 'string & keyof T' is assignable to the constraint of type 'J', but 'J' could be instantiated with a different subtype of constraint 'string'. Type 'string' is not assignable to type 'J'. 'string' is assignable to the constraint of type 'J', but 'J' could be instantiated with a different subtype of constraint 'string'. - Type 'string' is not assignable to type 'J'. - 'string' is assignable to the constraint of type 'J', but 'J' could be instantiated with a different subtype of constraint 'string'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'. Type 'T' is not assignable to type 'U'. 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint '{}'. @@ -264,8 +260,6 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(142,5): error !!! error TS2322: 'string & keyof T' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. !!! error TS2322: Type 'string' is not assignable to type 'K'. !!! error TS2322: 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. -!!! error TS2322: Type 'string' is not assignable to type 'K'. -!!! error TS2322: 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. t[key] = tk; // ok, T[K] ==> T[keyof T] tk = t[key]; // error, T[keyof T] =/=> T[K] ~~ @@ -299,8 +293,6 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(142,5): error !!! error TS2322: 'string & keyof T' is assignable to the constraint of type 'J', but 'J' could be instantiated with a different subtype of constraint 'string'. !!! error TS2322: Type 'string' is not assignable to type 'J'. !!! error TS2322: 'string' is assignable to the constraint of type 'J', but 'J' could be instantiated with a different subtype of constraint 'string'. -!!! error TS2322: Type 'string' is not assignable to type 'J'. -!!! error TS2322: 'string' is assignable to the constraint of type 'J', but 'J' could be instantiated with a different subtype of constraint 'string'. tk = uj; uj = tk; // error diff --git a/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.js b/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.js new file mode 100644 index 00000000000..ea8ac927061 --- /dev/null +++ b/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.js @@ -0,0 +1,11 @@ +//// [typeParameterExtendsUnionConstraintDistributed.ts] +type A = 1 | 2; +function f(a: T): A & T { return a; } // Shouldn't error + +type B = 2 | 3; +function f2(ab: T & U): (A | B) & T & U { return ab; } // Also shouldn't error + + +//// [typeParameterExtendsUnionConstraintDistributed.js] +function f(a) { return a; } // Shouldn't error +function f2(ab) { return ab; } // Also shouldn't error diff --git a/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.symbols b/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.symbols new file mode 100644 index 00000000000..2d47ed96e14 --- /dev/null +++ b/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.symbols @@ -0,0 +1,32 @@ +=== tests/cases/conformance/jsdoc/typeParameterExtendsUnionConstraintDistributed.ts === +type A = 1 | 2; +>A : Symbol(A, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 0, 0)) + +function f(a: T): A & T { return a; } // Shouldn't error +>f : Symbol(f, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 0, 15)) +>T : Symbol(T, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 1, 11)) +>A : Symbol(A, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 0, 0)) +>a : Symbol(a, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 1, 24)) +>T : Symbol(T, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 1, 11)) +>A : Symbol(A, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 0, 0)) +>T : Symbol(T, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 1, 11)) +>a : Symbol(a, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 1, 24)) + +type B = 2 | 3; +>B : Symbol(B, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 1, 50)) + +function f2(ab: T & U): (A | B) & T & U { return ab; } // Also shouldn't error +>f2 : Symbol(f2, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 3, 15)) +>T : Symbol(T, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 4, 12)) +>A : Symbol(A, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 0, 0)) +>U : Symbol(U, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 4, 24)) +>B : Symbol(B, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 1, 50)) +>ab : Symbol(ab, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 4, 38)) +>T : Symbol(T, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 4, 12)) +>U : Symbol(U, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 4, 24)) +>A : Symbol(A, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 0, 0)) +>B : Symbol(B, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 1, 50)) +>T : Symbol(T, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 4, 12)) +>U : Symbol(U, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 4, 24)) +>ab : Symbol(ab, Decl(typeParameterExtendsUnionConstraintDistributed.ts, 4, 38)) + diff --git a/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.types b/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.types new file mode 100644 index 00000000000..4e81c9728c4 --- /dev/null +++ b/tests/baselines/reference/typeParameterExtendsUnionConstraintDistributed.types @@ -0,0 +1,17 @@ +=== tests/cases/conformance/jsdoc/typeParameterExtendsUnionConstraintDistributed.ts === +type A = 1 | 2; +>A : A + +function f(a: T): A & T { return a; } // Shouldn't error +>f : (a: T) => (1 & T) | (2 & T) +>a : T +>a : T + +type B = 2 | 3; +>B : B + +function f2(ab: T & U): (A | B) & T & U { return ab; } // Also shouldn't error +>f2 : (ab: T & U) => (1 & T & U) | (2 & T & U) | (3 & T & U) +>ab : T & U +>ab : T & U + diff --git a/tests/cases/conformance/jsdoc/typeParameterExtendsUnionConstraintDistributed.ts b/tests/cases/conformance/jsdoc/typeParameterExtendsUnionConstraintDistributed.ts new file mode 100644 index 00000000000..2a87bb3ccaa --- /dev/null +++ b/tests/cases/conformance/jsdoc/typeParameterExtendsUnionConstraintDistributed.ts @@ -0,0 +1,5 @@ +type A = 1 | 2; +function f(a: T): A & T { return a; } // Shouldn't error + +type B = 2 | 3; +function f2(ab: T & U): (A | B) & T & U { return ab; } // Also shouldn't error From 00a43d7b49cc3b067a33c44f6e953a9d73b9e904 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Sep 2019 16:55:19 -0700 Subject: [PATCH 096/100] Cache propagating variance flags in the relationship cache (#32225) * Cache propagating variance flags in the relationship cache * Convert base fields in relation comparison result to flags --- src/compiler/checker.ts | 58 +++++++------- src/compiler/types.ts | 10 ++- ...eRepeatedlyPropegatesWithUnreliableFlag.js | 25 ++++++ ...atedlyPropegatesWithUnreliableFlag.symbols | 77 +++++++++++++++++++ ...peatedlyPropegatesWithUnreliableFlag.types | 51 ++++++++++++ ...eRepeatedlyPropegatesWithUnreliableFlag.ts | 17 ++++ 6 files changed, 206 insertions(+), 32 deletions(-) create mode 100644 tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.js create mode 100644 tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.symbols create mode 100644 tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.types create mode 100644 tests/cases/compiler/varianceRepeatedlyPropegatesWithUnreliableFlag.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b3f88661a8c..fdd3cac69b4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12561,12 +12561,12 @@ namespace ts { return true; } const id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol); - const relation = enumRelation.get(id); - if (relation !== undefined && !(relation === RelationComparisonResult.Failed && errorReporter)) { - return relation === RelationComparisonResult.Succeeded; + const entry = enumRelation.get(id); + if (entry !== undefined && !(!(entry & RelationComparisonResult.Reported) && entry & RelationComparisonResult.Failed && errorReporter)) { + return !!(entry & RelationComparisonResult.Succeeded); } if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & SymbolFlags.RegularEnum) || !(targetSymbol.flags & SymbolFlags.RegularEnum)) { - enumRelation.set(id, RelationComparisonResult.FailedAndReported); + enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); return false; } const targetEnumType = getTypeOfSymbol(targetSymbol); @@ -12577,7 +12577,7 @@ namespace ts { if (errorReporter) { errorReporter(Diagnostics.Property_0_is_missing_in_type_1, symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); - enumRelation.set(id, RelationComparisonResult.FailedAndReported); + enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); } else { enumRelation.set(id, RelationComparisonResult.Failed); @@ -12642,7 +12642,7 @@ namespace ts { if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { const related = relation.get(getRelationKey(source, target, relation)); if (related !== undefined) { - return related === RelationComparisonResult.Succeeded; + return !!(related & RelationComparisonResult.Succeeded); } } if (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable) { @@ -13463,18 +13463,6 @@ namespace ts { return result; } - function propagateSidebandVarianceFlags(typeArguments: readonly Type[], variances: VarianceFlags[]) { - for (let i = 0; i < variances.length; i++) { - const v = variances[i]; - if (v & VarianceFlags.Unmeasurable) { - instantiateType(typeArguments[i], reportUnmeasurableMarkers); - } - if (v & VarianceFlags.Unreliable) { - instantiateType(typeArguments[i], reportUnreliableMarkers); - } - } - } - // Determine if possibly recursive types are related. First, check if the result is already available in the global cache. // Second, check if we have already started a comparison of the given two types in which case we assume the result to be true. // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are @@ -13485,24 +13473,24 @@ namespace ts { return Ternary.False; } const id = getRelationKey(source, target, relation); - const related = relation.get(id); - if (related !== undefined) { - if (reportErrors && related === RelationComparisonResult.Failed) { + const entry = relation.get(id); + if (entry !== undefined) { + if (reportErrors && entry & RelationComparisonResult.Failed && !(entry & RelationComparisonResult.Reported)) { // We are elaborating errors and the cached result is an unreported failure. The result will be reported // as a failure, and should be updated as a reported failure by the bottom of this function. } else { if (outofbandVarianceMarkerHandler) { // We're in the middle of variance checking - integrate any unmeasurable/unreliable flags from this cached component - if (source.flags & (TypeFlags.Object | TypeFlags.Conditional) && source.aliasSymbol && - source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) { - propagateSidebandVarianceFlags(source.aliasTypeArguments, getAliasVariances(source.aliasSymbol)); + const saved = entry & RelationComparisonResult.ReportsMask; + if (saved & RelationComparisonResult.ReportsUnmeasurable) { + instantiateType(source, reportUnmeasurableMarkers); } - if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source).target === (target).target && length((source).typeArguments)) { - propagateSidebandVarianceFlags((source).typeArguments!, getVariances((source).target)); + if (saved & RelationComparisonResult.ReportsUnreliable) { + instantiateType(source, reportUnreliableMarkers); } } - return related === RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False; + return entry & RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False; } } if (!maybeKeys) { @@ -13531,14 +13519,26 @@ namespace ts { const saveExpandingFlags = expandingFlags; if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= ExpandingFlags.Source; if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, depth)) expandingFlags |= ExpandingFlags.Target; + let originalHandler: typeof outofbandVarianceMarkerHandler; + let propagatingVarianceFlags: RelationComparisonResult = 0; + if (outofbandVarianceMarkerHandler) { + originalHandler = outofbandVarianceMarkerHandler; + outofbandVarianceMarkerHandler = onlyUnreliable => { + propagatingVarianceFlags |= onlyUnreliable ? RelationComparisonResult.ReportsUnreliable : RelationComparisonResult.ReportsUnmeasurable; + return originalHandler!(onlyUnreliable); + }; + } const result = expandingFlags !== ExpandingFlags.Both ? structuredTypeRelatedTo(source, target, reportErrors, isIntersectionConstituent) : Ternary.Maybe; + if (outofbandVarianceMarkerHandler) { + outofbandVarianceMarkerHandler = originalHandler; + } expandingFlags = saveExpandingFlags; depth--; if (result) { if (result === Ternary.True || depth === 0) { // If result is definitely true, record all maybe keys as having succeeded for (let i = maybeStart; i < maybeCount; i++) { - relation.set(maybeKeys[i], RelationComparisonResult.Succeeded); + relation.set(maybeKeys[i], RelationComparisonResult.Succeeded | propagatingVarianceFlags); } maybeCount = maybeStart; } @@ -13546,7 +13546,7 @@ namespace ts { else { // A false result goes straight into global cache (when something is false under // assumptions it will also be false without assumptions) - relation.set(id, reportErrors ? RelationComparisonResult.FailedAndReported : RelationComparisonResult.Failed); + relation.set(id, (reportErrors ? RelationComparisonResult.Reported : 0) | RelationComparisonResult.Failed | propagatingVarianceFlags); maybeCount = maybeStart; } return result; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index eb568ed5cff..76bc461d878 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -614,9 +614,13 @@ namespace ts { /* @internal */ export const enum RelationComparisonResult { - Succeeded = 1, // Should be truthy - Failed = 2, - FailedAndReported = 3 + Succeeded = 1 << 0, // Should be truthy + Failed = 1 << 1, + Reported = 1 << 2, + + ReportsUnmeasurable = 1 << 3, + ReportsUnreliable = 1 << 4, + ReportsMask = ReportsUnmeasurable | ReportsUnreliable } export interface Node extends TextRange { diff --git a/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.js b/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.js new file mode 100644 index 00000000000..73062e82014 --- /dev/null +++ b/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.js @@ -0,0 +1,25 @@ +//// [varianceRepeatedlyPropegatesWithUnreliableFlag.ts] +type A = { a: number }; +type B = { b: number }; +type X = ({ [K in keyof T]: T[K] } & Record)[keyof T]; +type P1 = { data: X }; +type P2 = { data: X }; + +interface I { + fn(p1: P1>, p2: P2>): void; +} + +const i: I = null as any; +const p2: P2 = null as any; + +// Commenting out the below line will remove the error on the `const _i: I = i;` +i.fn(null as any, p2); + +const _i: I = i; + +//// [varianceRepeatedlyPropegatesWithUnreliableFlag.js] +var i = null; +var p2 = null; +// Commenting out the below line will remove the error on the `const _i: I = i;` +i.fn(null, p2); +var _i = i; diff --git a/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.symbols b/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.symbols new file mode 100644 index 00000000000..b2e1f46f1e8 --- /dev/null +++ b/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.symbols @@ -0,0 +1,77 @@ +=== tests/cases/compiler/varianceRepeatedlyPropegatesWithUnreliableFlag.ts === +type A = { a: number }; +>A : Symbol(A, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 0, 0)) +>a : Symbol(a, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 0, 10)) + +type B = { b: number }; +>B : Symbol(B, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 0, 23)) +>b : Symbol(b, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 1, 10)) + +type X = ({ [K in keyof T]: T[K] } & Record)[keyof T]; +>X : Symbol(X, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 1, 23)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 2, 7)) +>K : Symbol(K, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 2, 16)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 2, 7)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 2, 7)) +>K : Symbol(K, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 2, 16)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 2, 7)) + +type P1 = { data: X }; +>P1 : Symbol(P1, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 2, 71)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 3, 8)) +>data : Symbol(data, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 3, 14)) +>X : Symbol(X, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 1, 23)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 3, 8)) + +type P2 = { data: X }; +>P2 : Symbol(P2, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 3, 28)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 4, 8)) +>data : Symbol(data, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 4, 14)) +>X : Symbol(X, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 1, 23)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 4, 8)) + +interface I { +>I : Symbol(I, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 4, 28)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 6, 12)) + + fn(p1: P1>, p2: P2>): void; +>fn : Symbol(I.fn, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 6, 16)) +>K : Symbol(K, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 7, 7)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 6, 12)) +>p1 : Symbol(p1, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 7, 26)) +>P1 : Symbol(P1, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 2, 71)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 6, 12)) +>K : Symbol(K, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 7, 7)) +>p2 : Symbol(p2, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 7, 45)) +>P2 : Symbol(P2, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 3, 28)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 6, 12)) +>K : Symbol(K, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 7, 7)) +} + +const i: I = null as any; +>i : Symbol(i, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 10, 5)) +>I : Symbol(I, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 4, 28)) +>A : Symbol(A, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 0, 0)) +>B : Symbol(B, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 0, 23)) + +const p2: P2 = null as any; +>p2 : Symbol(p2, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 11, 5)) +>P2 : Symbol(P2, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 3, 28)) +>A : Symbol(A, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 0, 0)) + +// Commenting out the below line will remove the error on the `const _i: I = i;` +i.fn(null as any, p2); +>i.fn : Symbol(I.fn, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 6, 16)) +>i : Symbol(i, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 10, 5)) +>fn : Symbol(I.fn, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 6, 16)) +>p2 : Symbol(p2, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 11, 5)) + +const _i: I = i; +>_i : Symbol(_i, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 16, 5)) +>I : Symbol(I, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 4, 28)) +>A : Symbol(A, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 0, 0)) +>i : Symbol(i, Decl(varianceRepeatedlyPropegatesWithUnreliableFlag.ts, 10, 5)) + diff --git a/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.types b/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.types new file mode 100644 index 00000000000..82bf01d05d9 --- /dev/null +++ b/tests/baselines/reference/varianceRepeatedlyPropegatesWithUnreliableFlag.types @@ -0,0 +1,51 @@ +=== tests/cases/compiler/varianceRepeatedlyPropegatesWithUnreliableFlag.ts === +type A = { a: number }; +>A : A +>a : number + +type B = { b: number }; +>B : B +>b : number + +type X = ({ [K in keyof T]: T[K] } & Record)[keyof T]; +>X : ({ [K in keyof T]: T[K]; } & Record)[keyof T] + +type P1 = { data: X }; +>P1 : P1 +>data : ({ [K in keyof T]: T[K]; } & Record)[keyof T] + +type P2 = { data: X }; +>P2 : P2 +>data : ({ [K in keyof T]: T[K]; } & Record)[keyof T] + +interface I { + fn(p1: P1>, p2: P2>): void; +>fn : (p1: P1>, p2: P2>) => void +>p1 : P1> +>p2 : P2> +} + +const i: I = null as any; +>i : I +>null as any : any +>null : null + +const p2: P2 = null as any; +>p2 : P2 +>null as any : any +>null : null + +// Commenting out the below line will remove the error on the `const _i: I = i;` +i.fn(null as any, p2); +>i.fn(null as any, p2) : void +>i.fn : (p1: P1>, p2: P2>) => void +>i : I +>fn : (p1: P1>, p2: P2>) => void +>null as any : any +>null : null +>p2 : P2 + +const _i: I = i; +>_i : I +>i : I + diff --git a/tests/cases/compiler/varianceRepeatedlyPropegatesWithUnreliableFlag.ts b/tests/cases/compiler/varianceRepeatedlyPropegatesWithUnreliableFlag.ts new file mode 100644 index 00000000000..03cdaee0e9d --- /dev/null +++ b/tests/cases/compiler/varianceRepeatedlyPropegatesWithUnreliableFlag.ts @@ -0,0 +1,17 @@ +type A = { a: number }; +type B = { b: number }; +type X = ({ [K in keyof T]: T[K] } & Record)[keyof T]; +type P1 = { data: X }; +type P2 = { data: X }; + +interface I { + fn(p1: P1>, p2: P2>): void; +} + +const i: I = null as any; +const p2: P2 = null as any; + +// Commenting out the below line will remove the error on the `const _i: I = i;` +i.fn(null as any, p2); + +const _i: I = i; \ No newline at end of file From 0a4f39af715c164cf7c905999fd8051f839e5d6c Mon Sep 17 00:00:00 2001 From: typescript-bot Date: Tue, 24 Sep 2019 14:10:40 +0000 Subject: [PATCH 097/100] Update user baselines --- .../reference/docker/office-ui-fabric.log | 21 +---- tests/baselines/reference/user/assert.log | 40 ++++---- .../user/chrome-devtools-frontend.log | 91 ++++++++----------- tests/baselines/reference/user/prettier.log | 75 ++++++++------- 4 files changed, 100 insertions(+), 127 deletions(-) diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index 9cda725e39e..e75c479de90 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -1,14 +1,5 @@ Exit Code: 1 Standard output: -@uifabric/codepen-loader: yarn run vX.X.X -@uifabric/codepen-loader: $ just-scripts build --production --lint -@uifabric/codepen-loader: [XX:XX:XX XM] ■ Removing [lib, temp, dist, coverage, lib-commonjs] -@uifabric/codepen-loader: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/codepen-loader/tsconfig.json -@uifabric/codepen-loader: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --module commonjs --outDir "./lib" --project "/office-ui-fabric-react/packages/codepen-loader/tsconfig.json" -@uifabric/codepen-loader: [XX:XX:XX XM] ■ Running Jest -@uifabric/codepen-loader: [XX:XX:XX XM] ■ /usr/local/bin/node "/office-ui-fabric-react/node_modules/jest/bin/jest.js" --config "/office-ui-fabric-react/packages/codepen-loader/jest.config.js" --passWithNoTests --colors --forceExit -@uifabric/codepen-loader: PASS src/__tests__/codepenTransform.test.ts -@uifabric/codepen-loader: Done in ?s. @uifabric/build: yarn run vX.X.X @uifabric/build: $ node ./just-scripts.js no-op --production --lint @uifabric/build: Done in ?s. @@ -36,9 +27,11 @@ Standard output: @uifabric/migration: Done in ?s. @uifabric/monaco-editor: yarn run vX.X.X @uifabric/monaco-editor: $ just-scripts build --production --lint -@uifabric/monaco-editor: [XX:XX:XX XM] ■ Removing [esm, lib] +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Removing [esm, lib, lib-commonjs] @uifabric/monaco-editor: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/monaco-editor/tsconfig.json @uifabric/monaco-editor: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib --module esnext --project "/office-ui-fabric-react/packages/monaco-editor/tsconfig.json" +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Running /office-ui-fabric-react/node_modules/typescript/lib/tsc.js with /office-ui-fabric-react/packages/monaco-editor/tsconfig.json +@uifabric/monaco-editor: [XX:XX:XX XM] ■ Executing: /usr/local/bin/node "/office-ui-fabric-react/node_modules/typescript/lib/tsc.js" --pretty --target es5 --inlineSources --sourceRoot "../src" --outDir lib-commonjs --module commonjs --project "/office-ui-fabric-react/packages/monaco-editor/tsconfig.json" @uifabric/monaco-editor: Done in ?s. @uifabric/set-version: yarn run vX.X.X @uifabric/set-version: $ just-scripts build --production --lint @@ -91,6 +84,7 @@ Standard output: @uifabric/merge-styles: PASS src/extractStyleParts.test.ts @uifabric/merge-styles: PASS src/server.test.ts @uifabric/merge-styles: PASS src/concatStyleSetsWithProps.test.ts +@uifabric/merge-styles: PASS src/fontFace.test.ts @uifabric/merge-styles: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/merge-styles/lib/index.d.ts' @uifabric/merge-styles: Done in ?s. @uifabric/jest-serializer-merge-styles: yarn run vX.X.X @@ -206,7 +200,6 @@ Standard output: @uifabric/styling: PASS src/styles/theme.test.ts @uifabric/styling: PASS src/styles/scheme.test.ts @uifabric/styling: PASS src/styles/getGlobalClassNames.test.ts -@uifabric/styling: PASS src/utilities/icons.test.ts @uifabric/styling: [XX:XX:XX XM] ■ Extracting Public API surface from '/office-ui-fabric-react/packages/styling/lib/index.d.ts' @uifabric/styling: Done in ?s. @uifabric/file-type-icons: yarn run vX.X.X @@ -249,11 +242,7 @@ Standard output: Standard error: info cli using local version of lerna lerna notice cli vX.X.X -lerna info Executing command in 43 packages: "yarn run build --production --lint" -@uifabric/codepen-loader: ts-jest[versions] (WARN) Version X.X.X-insiders.xxxxxxxx of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=2.7.0 <4.0.0). Please do not report issues in ts-jest if you are using unsupported versions. -@uifabric/codepen-loader: Force exiting Jest -@uifabric/codepen-loader: -@uifabric/codepen-loader: Have you considered using `--detectOpenHandles` to detect async operations that kept running after all tests finished? +lerna info Executing command in 42 packages: "yarn run build --production --lint" @uifabric/example-data: [XX:XX:XX XM] ▲ One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect @uifabric/set-version: [XX:XX:XX XM] ▲ One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect @uifabric/merge-styles: [XX:XX:XX XM] ▲ One of these [node-sass, postcss, autoprefixer] is not installed, so this task has no effect diff --git a/tests/baselines/reference/user/assert.log b/tests/baselines/reference/user/assert.log index 4b00cccc6ab..ce8e6cc19d0 100644 --- a/tests/baselines/reference/user/assert.log +++ b/tests/baselines/reference/user/assert.log @@ -1,34 +1,34 @@ Exit Code: 1 Standard output: node_modules/assert/test.js(25,5): error TS2367: This condition will always return 'false' since the types 'string | undefined' and 'boolean' have no overlap. -node_modules/assert/test.js(39,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(55,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(74,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(84,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(94,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(103,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(120,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(128,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(39,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(55,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(74,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(84,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(94,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(103,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(120,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(128,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. node_modules/assert/test.js(140,10): error TS2339: Property 'a' does not exist on type 'number[]'. node_modules/assert/test.js(141,10): error TS2339: Property 'b' does not exist on type 'number[]'. node_modules/assert/test.js(142,10): error TS2339: Property 'b' does not exist on type 'number[]'. node_modules/assert/test.js(143,10): error TS2339: Property 'a' does not exist on type 'number[]'. -node_modules/assert/test.js(149,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(149,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. node_modules/assert/test.js(157,51): error TS2349: This expression is not callable. Type 'never' has no call signatures. -node_modules/assert/test.js(161,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(161,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. node_modules/assert/test.js(168,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(182,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(229,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(235,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(250,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(254,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(182,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(229,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(235,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(250,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(254,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? node_modules/assert/test.js(256,55): error TS2345: Argument of type 'TypeError' is not assignable to parameter of type 'string'. -node_modules/assert/test.js(262,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(279,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(285,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(320,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(346,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(262,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(279,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(285,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(320,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? +node_modules/assert/test.js(346,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? diff --git a/tests/baselines/reference/user/chrome-devtools-frontend.log b/tests/baselines/reference/user/chrome-devtools-frontend.log index bad901d3d57..c9ce3bc730b 100644 --- a/tests/baselines/reference/user/chrome-devtools-frontend.log +++ b/tests/baselines/reference/user/chrome-devtools-frontend.log @@ -3990,10 +3990,9 @@ node_modules/chrome-devtools-frontend/front_end/console/ConsoleView.js(1277,60): node_modules/chrome-devtools-frontend/front_end/console/ConsoleView.js(1278,42): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>[]): { key: string; text: string; regex: RegExp; negative: boolean; }[]', gave the following error. Argument of type '{ key: any; text: string; negative: boolean; }[]' is not assignable to parameter of type 'ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>'. - Types of property 'slice' are incompatible. - Type '(start?: number, end?: number) => { key: any; text: string; negative: boolean; }[]' is not assignable to type '(start?: number, end?: number) => { key: string; text: string; regex: RegExp; negative: boolean; }[]'. - Type '{ key: any; text: string; negative: boolean; }[]' is not assignable to type '{ key: string; text: string; regex: RegExp; negative: boolean; }[]'. - Property 'regex' is missing in type '{ key: any; text: string; negative: boolean; }' but required in type '{ key: string; text: string; regex: RegExp; negative: boolean; }'. + The types returned by 'slice(...)' are incompatible between these types. + Type '{ key: any; text: string; negative: boolean; }[]' is not assignable to type '{ key: string; text: string; regex: RegExp; negative: boolean; }[]'. + Property 'regex' is missing in type '{ key: any; text: string; negative: boolean; }' but required in type '{ key: string; text: string; regex: RegExp; negative: boolean; }'. Overload 2 of 2, '(...items: ({ key: string; text: string; regex: RegExp; negative: boolean; } | ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>)[]): { key: string; text: string; regex: RegExp; negative: boolean; }[]', gave the following error. Argument of type '{ key: any; text: string; negative: boolean; }[]' is not assignable to parameter of type '{ key: string; text: string; regex: RegExp; negative: boolean; } | ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>'. Type '{ key: any; text: string; negative: boolean; }[]' is not assignable to type 'ConcatArray<{ key: string; text: string; regex: RegExp; negative: boolean; }>'. @@ -5038,22 +5037,18 @@ node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js( node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js(91,24): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(Promise | Promise)[]' is not assignable to parameter of type 'Iterable>'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator | Promise>' is not assignable to type '() => Iterator, any, undefined>'. - Type 'IterableIterator | Promise>' is not assignable to type 'Iterator, any, undefined>'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult | Promise, any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult, any>'. - Type 'IteratorResult | Promise, any>' is not assignable to type 'IteratorResult, any>'. - Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorResult, any>'. - Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorYieldResult>'. - Type 'Promise | Promise' is not assignable to type 'CSSMatchedStyles | PromiseLike'. - Type 'Promise' is not assignable to type 'CSSMatchedStyles | PromiseLike'. - Type 'Promise' is not assignable to type 'PromiseLike'. - Types of property 'then' are incompatible. - Type '(onfulfilled?: (value: ComputedStyle) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise' is not assignable to type '(onfulfilled?: (value: CSSMatchedStyles) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike<...>'. - Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. - Types of parameters 'value' and 'value' are incompatible. - Type 'ComputedStyle' is missing the following properties from type 'CSSMatchedStyles': _cssModel, _node, _nodeStyles, _nodeForStyle, and 22 more. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult | Promise, any>' is not assignable to type 'IteratorResult, any>'. + Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorResult, any>'. + Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorYieldResult>'. + Type 'Promise | Promise' is not assignable to type 'CSSMatchedStyles | PromiseLike'. + Type 'Promise' is not assignable to type 'CSSMatchedStyles | PromiseLike'. + Type 'Promise' is not assignable to type 'PromiseLike'. + Types of property 'then' are incompatible. + Type '(onfulfilled?: (value: ComputedStyle) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise' is not assignable to type '(onfulfilled?: (value: CSSMatchedStyles) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike<...>'. + Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. + Types of parameters 'value' and 'value' are incompatible. + Type 'ComputedStyle' is missing the following properties from type 'CSSMatchedStyles': _cssModel, _node, _nodeStyles, _nodeForStyle, and 22 more. node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js(147,52): error TS2339: Property 'keysArray' does not exist on type 'Map'. node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js(179,50): error TS2339: Property 'createChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/elements/ComputedStyleWidget.js(200,74): error TS2339: Property 'consume' does not exist on type 'Event'. @@ -5339,22 +5334,18 @@ node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(5 node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(82,24): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(Promise> | Promise)[]' is not assignable to parameter of type 'Iterable | PromiseLike>>'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator> | Promise>' is not assignable to type '() => Iterator | PromiseLike>, any, undefined>'. - Type 'IterableIterator> | Promise>' is not assignable to type 'Iterator | PromiseLike>, any, undefined>'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult> | Promise, any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult | PromiseLike>, any>'. - Type 'IteratorResult> | Promise, any>' is not assignable to type 'IteratorResult | PromiseLike>, any>'. - Type 'IteratorYieldResult> | Promise>' is not assignable to type 'IteratorResult | PromiseLike>, any>'. - Type 'IteratorYieldResult> | Promise>' is not assignable to type 'IteratorYieldResult | PromiseLike>>'. - Type 'Promise> | Promise' is not assignable to type 'Map | PromiseLike>'. - Type 'Promise' is not assignable to type 'Map | PromiseLike>'. - Type 'Promise' is not assignable to type 'PromiseLike>'. - Types of property 'then' are incompatible. - Type '(onfulfilled?: (value: InlineStyleResult) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise<...>' is not assignable to type ', TResult2 = never>(onfulfilled?: (value: Map) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike<...>'. - Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. - Types of parameters 'value' and 'value' are incompatible. - Type 'InlineStyleResult' is missing the following properties from type 'Map': clear, delete, forEach, get, and 8 more. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult> | Promise, any>' is not assignable to type 'IteratorResult | PromiseLike>, any>'. + Type 'IteratorYieldResult> | Promise>' is not assignable to type 'IteratorResult | PromiseLike>, any>'. + Type 'IteratorYieldResult> | Promise>' is not assignable to type 'IteratorYieldResult | PromiseLike>>'. + Type 'Promise> | Promise' is not assignable to type 'Map | PromiseLike>'. + Type 'Promise' is not assignable to type 'Map | PromiseLike>'. + Type 'Promise' is not assignable to type 'PromiseLike>'. + Types of property 'then' are incompatible. + Type '(onfulfilled?: (value: InlineStyleResult) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise<...>' is not assignable to type ', TResult2 = never>(onfulfilled?: (value: Map) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike<...>'. + Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. + Types of parameters 'value' and 'value' are incompatible. + Type 'InlineStyleResult' is missing the following properties from type 'Map': clear, delete, forEach, get, and 8 more. node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(120,11): error TS2339: Property 'consume' does not exist on type 'Event'. node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(164,22): error TS2339: Property 'toFixedIfFloating' does not exist on type 'NumberConstructor'. node_modules/chrome-devtools-frontend/front_end/elements/MetricsSidebarPane.js(179,18): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. @@ -12648,22 +12639,18 @@ node_modules/chrome-devtools-frontend/front_end/ui/View.js(454,38): error TS2339 node_modules/chrome-devtools-frontend/front_end/ui/View.js(461,44): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(Promise | Promise)[]' is not assignable to parameter of type 'Iterable>'. - Types of property '[Symbol.iterator]' are incompatible. - Type '() => IterableIterator | Promise>' is not assignable to type '() => Iterator, any, undefined>'. - Type 'IterableIterator | Promise>' is not assignable to type 'Iterator, any, undefined>'. - Types of property 'next' are incompatible. - Type '(...args: [] | [undefined]) => IteratorResult | Promise, any>' is not assignable to type '(...args: [] | [undefined]) => IteratorResult, any>'. - Type 'IteratorResult | Promise, any>' is not assignable to type 'IteratorResult, any>'. - Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorResult, any>'. - Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorYieldResult>'. - Type 'Promise | Promise' is not assignable to type 'void | PromiseLike'. - Type 'Promise' is not assignable to type 'void | PromiseLike'. - Type 'Promise' is not assignable to type 'PromiseLike'. - Types of property 'then' are incompatible. - Type '(onfulfilled?: (value: ToolbarItem[]) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise' is not assignable to type '(onfulfilled?: (value: void) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. - Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. - Types of parameters 'value' and 'value' are incompatible. - Type 'ToolbarItem[]' is not assignable to type 'void'. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult | Promise, any>' is not assignable to type 'IteratorResult, any>'. + Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorResult, any>'. + Type 'IteratorYieldResult | Promise>' is not assignable to type 'IteratorYieldResult>'. + Type 'Promise | Promise' is not assignable to type 'void | PromiseLike'. + Type 'Promise' is not assignable to type 'void | PromiseLike'. + Type 'Promise' is not assignable to type 'PromiseLike'. + Types of property 'then' are incompatible. + Type '(onfulfilled?: (value: ToolbarItem[]) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise' is not assignable to type '(onfulfilled?: (value: void) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. + Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible. + Types of parameters 'value' and 'value' are incompatible. + Type 'ToolbarItem[]' is not assignable to type 'void'. node_modules/chrome-devtools-frontend/front_end/ui/View.js(495,24): error TS2339: Property 'createTextChild' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/ui/View.js(496,24): error TS2339: Property 'tabIndex' does not exist on type 'Element'. node_modules/chrome-devtools-frontend/front_end/ui/View.js(501,25): error TS2339: Property 'createChild' does not exist on type 'Element'. diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log index 635c0bc0b36..71fb532b794 100644 --- a/tests/baselines/reference/user/prettier.log +++ b/tests/baselines/reference/user/prettier.log @@ -142,10 +142,9 @@ src/language-html/printer-html.js(314,13): error TS2769: No overload matches thi src/language-html/printer-html.js(471,11): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type '{ type: string; parts: any; }[]' is not assignable to parameter of type 'ConcatArray'. - Types of property 'slice' are incompatible. - Type '(start?: number | undefined, end?: number | undefined) => { type: string; parts: any; }[]' is not assignable to type '(start?: number | undefined, end?: number | undefined) => never[]'. - Type '{ type: string; parts: any; }[]' is not assignable to type 'never[]'. - Type '{ type: string; parts: any; }' is not assignable to type 'never'. + The types returned by 'slice(...)' are incompatible between these types. + Type '{ type: string; parts: any; }[]' is not assignable to type 'never[]'. + Type '{ type: string; parts: any; }' is not assignable to type 'never'. Overload 2 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type '{ type: string; parts: any; }[]' is not assignable to parameter of type 'ConcatArray'. src/language-html/printer-html.js(492,11): error TS2769: No overload matches this call. @@ -200,11 +199,10 @@ src/language-js/index.js(81,60): error TS2345: Argument of type '{ override: { s src/language-js/needs-parens.js(871,14): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<(childPath: any) => any>[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type 'ConcatArray<(childPath: any) => any>'. - Types of property 'slice' are incompatible. - Type '(start?: number | undefined, end?: number | undefined) => (string | number)[]' is not assignable to type '(start?: number | undefined, end?: number | undefined) => ((childPath: any) => any)[]'. - Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. - Type 'string | number' is not assignable to type '(childPath: any) => any'. - Type 'string' is not assignable to type '(childPath: any) => any'. + The types returned by 'slice(...)' are incompatible between these types. + Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. + Type 'string | number' is not assignable to type '(childPath: any) => any'. + Type 'string' is not assignable to type '(childPath: any) => any'. Overload 2 of 2, '(...items: (((childPath: any) => any) | ConcatArray<(childPath: any) => any>)[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type '((childPath: any) => any) | ConcatArray<(childPath: any) => any>'. Type '(string | number)[]' is not assignable to type 'ConcatArray<(childPath: any) => any>'. @@ -219,56 +217,55 @@ src/language-js/printer-estree.js(400,9): error TS2769: No overload matches this Overload 2 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type '{ type: string; parts: any; } | { type: string; contents: any; n: any; }' is not assignable to parameter of type 'ConcatArray'. Type '{ type: string; parts: any; }' is not assignable to type 'ConcatArray'. -src/language-js/printer-estree.js(1480,28): error TS2769: No overload matches this call. +src/language-js/printer-estree.js(1481,28): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): (string | { type: string; id: any; contents: any; break: boolean; expandedStates: any; })[]', gave the following error. Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'ConcatArray'. Type '{ type: string; parts: any; }' is missing the following properties from type 'ConcatArray': length, join, slice Overload 2 of 2, '(...items: (string | { type: string; id: any; contents: any; break: boolean; expandedStates: any; } | ConcatArray)[]): (string | { ...; })[]', gave the following error. Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string | { type: string; id: any; contents: any; break: boolean; expandedStates: any; } | ConcatArray'. Type '{ type: string; parts: any; }' is missing the following properties from type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }': id, contents, break, expandedStates -src/language-js/printer-estree.js(1913,20): error TS2345: Argument of type '" "' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. -src/language-js/printer-estree.js(1915,20): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. -src/language-js/printer-estree.js(1917,18): error TS2345: Argument of type '"while ("' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. -src/language-js/printer-estree.js(1926,9): error TS2345: Argument of type '")"' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. -src/language-js/printer-estree.js(3472,11): error TS2769: No overload matches this call. +src/language-js/printer-estree.js(1914,20): error TS2345: Argument of type '" "' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(1916,20): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(1918,18): error TS2345: Argument of type '"while ("' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(1927,9): error TS2345: Argument of type '")"' is not assignable to parameter of type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(3473,11): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type 'never[] | { type: string; parts: any; }' is not assignable to parameter of type 'ConcatArray'. Type '{ type: string; parts: any; }' is not assignable to type 'ConcatArray'. Overload 2 of 2, '(...items: ConcatArray[]): never[]', gave the following error. Argument of type 'never[] | { type: string; parts: any; }' is not assignable to parameter of type 'ConcatArray'. Type '{ type: string; parts: any; }' is not assignable to type 'ConcatArray'. -src/language-js/printer-estree.js(3901,22): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. -src/language-js/printer-estree.js(3968,14): error TS2339: Property 'comments' does not exist on type 'Expression'. +src/language-js/printer-estree.js(3902,22): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. +src/language-js/printer-estree.js(3969,14): error TS2339: Property 'comments' does not exist on type 'Expression'. Property 'comments' does not exist on type 'Identifier'. -src/language-js/printer-estree.js(3980,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"OptionalMemberExpression"' have no overlap. -src/language-js/printer-estree.js(3981,13): error TS2339: Property 'property' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. +src/language-js/printer-estree.js(3981,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"OptionalMemberExpression"' have no overlap. +src/language-js/printer-estree.js(3982,13): error TS2339: Property 'property' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. Property 'property' does not exist on type 'SimpleLiteral'. -src/language-js/printer-estree.js(3981,52): error TS2339: Property 'property' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. +src/language-js/printer-estree.js(3982,52): error TS2339: Property 'property' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. Property 'property' does not exist on type 'SimpleLiteral'. -src/language-js/printer-estree.js(3986,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"OptionalMemberExpression"' have no overlap. -src/language-js/printer-estree.js(3988,29): error TS2339: Property 'object' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. +src/language-js/printer-estree.js(3987,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"OptionalMemberExpression"' have no overlap. +src/language-js/printer-estree.js(3989,29): error TS2339: Property 'object' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. Property 'object' does not exist on type 'SimpleLiteral'. -src/language-js/printer-estree.js(3989,22): error TS2339: Property 'comments' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. +src/language-js/printer-estree.js(3990,22): error TS2339: Property 'comments' does not exist on type 'SimpleLiteral | RegExpLiteral | FunctionExpression | ArrowFunctionExpression | ArrayExpression | ObjectExpression | YieldExpression | UnaryExpression | UpdateExpression | ... 12 more ... | AwaitExpression'. Property 'comments' does not exist on type 'SimpleLiteral'. -src/language-js/printer-estree.js(3995,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"Identifier"' have no overlap. -src/language-js/printer-estree.js(3996,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"ThisExpression"' have no overlap. -src/language-js/printer-estree.js(4200,23): error TS2532: Object is possibly 'undefined'. -src/language-js/printer-estree.js(4201,24): error TS2532: Object is possibly 'undefined'. -src/language-js/printer-estree.js(4557,5): error TS2345: Argument of type '"" | { type: string; parts: any; } | { type: string; contents: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(3996,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"Identifier"' have no overlap. +src/language-js/printer-estree.js(3997,9): error TS2367: This condition will always return 'false' since the types '"FunctionExpression" | "ClassExpression" | "ObjectExpression" | "TaggedTemplateExpression" | "CallExpression" | "ConditionalExpression" | "UpdateExpression" | "SequenceExpression" | ... 11 more ... | "MetaProperty"' and '"ThisExpression"' have no overlap. +src/language-js/printer-estree.js(4201,23): error TS2532: Object is possibly 'undefined'. +src/language-js/printer-estree.js(4202,24): error TS2532: Object is possibly 'undefined'. +src/language-js/printer-estree.js(4558,5): error TS2345: Argument of type '"" | { type: string; parts: any; } | { type: string; contents: any; }' is not assignable to parameter of type 'string'. Type '{ type: string; parts: any; }' is not assignable to type 'string'. -src/language-js/printer-estree.js(4561,16): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. -src/language-js/printer-estree.js(4609,11): error TS2322: Type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }' is not assignable to type 'string'. -src/language-js/printer-estree.js(4624,11): error TS2322: Type '{ type: string; parts: any; }' is not assignable to type 'string'. -src/language-js/printer-estree.js(4636,9): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. -src/language-js/printer-estree.js(4923,9): error TS2554: Expected 0-2 arguments, but got 3. -src/language-js/printer-estree.js(6130,7): error TS2769: No overload matches this call. +src/language-js/printer-estree.js(4562,16): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(4610,11): error TS2322: Type '{ type: string; id: any; contents: any; break: boolean; expandedStates: any; }' is not assignable to type 'string'. +src/language-js/printer-estree.js(4625,11): error TS2322: Type '{ type: string; parts: any; }' is not assignable to type 'string'. +src/language-js/printer-estree.js(4637,9): error TS2345: Argument of type '{ type: string; parts: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(4924,9): error TS2554: Expected 0-2 arguments, but got 3. +src/language-js/printer-estree.js(6131,7): error TS2769: No overload matches this call. Overload 1 of 2, '(...items: ConcatArray<(childPath: any) => any>[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type 'ConcatArray<(childPath: any) => any>'. - Types of property 'slice' are incompatible. - Type '(start?: number | undefined, end?: number | undefined) => (string | number)[]' is not assignable to type '(start?: number | undefined, end?: number | undefined) => ((childPath: any) => any)[]'. - Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. - Type 'string | number' is not assignable to type '(childPath: any) => any'. - Type 'string' is not assignable to type '(childPath: any) => any'. + The types returned by 'slice(...)' are incompatible between these types. + Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. + Type 'string | number' is not assignable to type '(childPath: any) => any'. + Type 'string' is not assignable to type '(childPath: any) => any'. Overload 2 of 2, '(...items: (((childPath: any) => any) | ConcatArray<(childPath: any) => any>)[]): ((childPath: any) => any)[]', gave the following error. Argument of type '(string | number)[]' is not assignable to parameter of type '((childPath: any) => any) | ConcatArray<(childPath: any) => any>'. Type '(string | number)[]' is not assignable to type 'ConcatArray<(childPath: any) => any>'. From aca0bb943f24c57854062b1a0bc13b1d64d73136 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 24 Sep 2019 08:30:18 -0700 Subject: [PATCH 098/100] Fix lint on master --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7a44ac66229..71c72a4cf82 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33314,7 +33314,7 @@ namespace ts { // Modifiers are never allowed on properties except for 'async' on a method declaration if (prop.modifiers) { - for (const mod of prop.modifiers!) { // TODO: GH#19955 + for (const mod of prop.modifiers) { if (mod.kind !== SyntaxKind.AsyncKeyword || prop.kind !== SyntaxKind.MethodDeclaration) { grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod)); } From 4ddf1919bbdf3df09fe32cfdbe3fef7423fc5e51 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 24 Sep 2019 08:47:45 -0700 Subject: [PATCH 099/100] try eslint-disable-next-line instead --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 71c72a4cf82..e3494a1f341 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33314,7 +33314,8 @@ namespace ts { // Modifiers are never allowed on properties except for 'async' on a method declaration if (prop.modifiers) { - for (const mod of prop.modifiers) { + // eslint-disable-next-line no-unnecessary-type-assertion + for (const mod of prop.modifiers!) { // TODO: GH#19955 if (mod.kind !== SyntaxKind.AsyncKeyword || prop.kind !== SyntaxKind.MethodDeclaration) { grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod)); } From 41c3e545457005c6c8fe3c78f1da56b4379bcf03 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 24 Sep 2019 09:38:44 -0700 Subject: [PATCH 100/100] change eslint-disable rule name --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e3494a1f341..2a3f2390cf3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33314,7 +33314,7 @@ namespace ts { // Modifiers are never allowed on properties except for 'async' on a method declaration if (prop.modifiers) { - // eslint-disable-next-line no-unnecessary-type-assertion + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion for (const mod of prop.modifiers!) { // TODO: GH#19955 if (mod.kind !== SyntaxKind.AsyncKeyword || prop.kind !== SyntaxKind.MethodDeclaration) { grammarErrorOnNode(mod, Diagnostics._0_modifier_cannot_be_used_here, getTextOfNode(mod));