diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 90762a54f978b..e66148eea31c2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10573,7 +10573,7 @@ namespace ts { function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { if (isTypeRelatedTo(source, target, relation)) return true; - if (!errorNode || !elaborateError(expr, source, target)) { + if (!errorNode || !elaborateError(expr, source, target, relation)) { return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain); } return false; @@ -10583,25 +10583,49 @@ namespace ts { return !!(type.flags & TypeFlags.Conditional || (type.flags & TypeFlags.Intersection && some((type as IntersectionType).types, isOrHasGenericConditional))); } - function elaborateError(node: Expression | undefined, source: Type, target: Type): boolean { + function elaborateError(node: Expression | undefined, source: Type, target: Type, relation: Map): boolean { if (!node || isOrHasGenericConditional(target)) return false; + if (!checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined) && elaborateDidYouMeanToCallOrConstruct(node, source, target, relation)) { + return true; + } switch (node.kind) { case SyntaxKind.JsxExpression: case SyntaxKind.ParenthesizedExpression: - return elaborateError((node as ParenthesizedExpression | JsxExpression).expression, source, target); + return elaborateError((node as ParenthesizedExpression | JsxExpression).expression, source, target, relation); case SyntaxKind.BinaryExpression: switch ((node as BinaryExpression).operatorToken.kind) { case SyntaxKind.EqualsToken: case SyntaxKind.CommaToken: - return elaborateError((node as BinaryExpression).right, source, target); + return elaborateError((node as BinaryExpression).right, source, target, relation); } break; case SyntaxKind.ObjectLiteralExpression: - return elaborateObjectLiteral(node as ObjectLiteralExpression, source, target); + return elaborateObjectLiteral(node as ObjectLiteralExpression, source, target, relation); case SyntaxKind.ArrayLiteralExpression: - return elaborateArrayLiteral(node as ArrayLiteralExpression, source, target); + return elaborateArrayLiteral(node as ArrayLiteralExpression, source, target, relation); case SyntaxKind.JsxAttributes: - return elaborateJsxAttributes(node as JsxAttributes, source, target); + return elaborateJsxAttributes(node as JsxAttributes, source, target, relation); + } + return false; + } + + function elaborateDidYouMeanToCallOrConstruct(node: Expression, source: Type, target: Type, relation: Map): boolean { + const callSignatures = getSignaturesOfType(source, SignatureKind.Call); + const constructSignatures = getSignaturesOfType(source, SignatureKind.Construct); + for (const signatures of [constructSignatures, callSignatures]) { + if (some(signatures, s => { + const returnType = getReturnTypeOfSignature(s); + return !(returnType.flags & (TypeFlags.Any | TypeFlags.Never)) && checkTypeRelatedTo(returnType, target, relation, /*errorNode*/ undefined); + })) { + const resultObj: { error?: Diagnostic } = {}; + checkTypeAssignableTo(source, target, node, /*errorMessage*/ undefined, /*containingChain*/ undefined, resultObj); + const diagnostic = resultObj.error!; + addRelatedInfo(diagnostic, createDiagnosticForNode( + node, + signatures === constructSignatures ? Diagnostics.Did_you_mean_to_use_new_with_this_expression : Diagnostics.Did_you_mean_to_call_this_expression + )); + return true; + } } return false; } @@ -10612,7 +10636,7 @@ namespace ts { * If that element would issue an error, we first attempt to dive into that element's inner expression and issue a more specific error by recuring into `elaborateError` * Otherwise, we issue an error on _every_ element which fail the assignability check */ - function elaborateElementwise(iterator: ElaborationIterator, source: Type, target: Type) { + function elaborateElementwise(iterator: ElaborationIterator, source: Type, target: Type, relation: Map) { // Assignability failure - check each prop individually, and if that fails, fall back on the bad error span let reportedError = false; for (let status = iterator.next(); !status.done; status = iterator.next()) { @@ -10620,7 +10644,7 @@ namespace ts { const sourcePropType = getIndexedAccessType(source, nameType, /*accessNode*/ undefined, errorType); const targetPropType = getIndexedAccessType(target, nameType, /*accessNode*/ undefined, errorType); if (sourcePropType !== errorType && targetPropType !== errorType && !isTypeAssignableTo(sourcePropType, targetPropType)) { - const elaborated = next && elaborateError(next, sourcePropType, targetPropType); + const elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation); if (elaborated) { reportedError = true; } @@ -10629,10 +10653,10 @@ namespace ts { const resultObj: { error?: Diagnostic } = {}; // Use the expression type, if available const specificSource = next ? checkExpressionForMutableLocation(next, CheckMode.Normal, sourcePropType) : sourcePropType; - const result = checkTypeAssignableTo(specificSource, targetPropType, prop, errorMessage, /*containingChain*/ undefined, resultObj); + const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage, /*containingChain*/ undefined, resultObj); if (result && specificSource !== sourcePropType) { // If for whatever reason the expression type doesn't yield an error, make sure we still issue an error on the sourcePropType - checkTypeAssignableTo(sourcePropType, targetPropType, prop, errorMessage, /*containingChain*/ undefined, resultObj); + checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage, /*containingChain*/ undefined, resultObj); } if (resultObj.error) { const reportedDiag = resultObj.error; @@ -10674,8 +10698,8 @@ namespace ts { } } - function elaborateJsxAttributes(node: JsxAttributes, source: Type, target: Type) { - return elaborateElementwise(generateJsxAttributes(node), source, target); + function elaborateJsxAttributes(node: JsxAttributes, source: Type, target: Type, relation: Map) { + return elaborateElementwise(generateJsxAttributes(node), source, target, relation); } function *generateLimitedTupleElements(node: ArrayLiteralExpression, target: Type): ElaborationIterator { @@ -10691,9 +10715,9 @@ namespace ts { } } - function elaborateArrayLiteral(node: ArrayLiteralExpression, source: Type, target: Type) { + function elaborateArrayLiteral(node: ArrayLiteralExpression, source: Type, target: Type, relation: Map) { if (isTupleLikeType(source)) { - return elaborateElementwise(generateLimitedTupleElements(node, target), source, target); + return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation); } return false; } @@ -10722,8 +10746,8 @@ namespace ts { } } - function elaborateObjectLiteral(node: ObjectLiteralExpression, source: Type, target: Type) { - return elaborateElementwise(generateObjectLiteralElements(node), source, target); + function elaborateObjectLiteral(node: ObjectLiteralExpression, source: Type, target: Type, relation: Map) { + return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation); } /** diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7a57b89d3206d..a4069e3c5a9f3 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3716,6 +3716,14 @@ "category": "Message", "code": 6211 }, + "Did you mean to call this expression?": { + "category": "Message", + "code": 6212 + }, + "Did you mean to use `new` with this expression?": { + "category": "Message", + "code": 6213 + }, "Projects to reference": { "category": "Message", diff --git a/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.errors.txt b/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.errors.txt new file mode 100644 index 0000000000000..9f1f60b9d1e30 --- /dev/null +++ b/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.errors.txt @@ -0,0 +1,51 @@ +tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts(10,8): error TS2322: Type 'typeof Bar' is not assignable to type 'Bar'. + Property 'x' is missing in type 'typeof Bar'. +tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts(11,8): error TS2322: Type 'DateConstructor' is not assignable to type 'Date'. + Property 'toDateString' is missing in type 'DateConstructor'. +tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts(17,4): error TS2322: Type '() => number' is not assignable to type 'number'. +tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts(26,5): error TS2322: Type '() => number' is not assignable to type 'number'. + + +==== tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts (4 errors) ==== + class Bar { + x!: string; + } + + declare function getNum(): number; + + declare function foo(arg: { x: Bar, y: Date }, item: number, items?: [number, number, number]): void; + + foo({ + x: Bar, + ~~~ +!!! error TS2322: Type 'typeof Bar' is not assignable to type 'Bar'. +!!! error TS2322: Property 'x' is missing in type 'typeof Bar'. +!!! related TS6213 tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts:10:8: Did you mean to use `new` with this expression? + y: Date + ~~~~ +!!! error TS2322: Type 'DateConstructor' is not assignable to type 'Date'. +!!! error TS2322: Property 'toDateString' is missing in type 'DateConstructor'. +!!! related TS6213 tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts:11:8: Did you mean to use `new` with this expression? + }, getNum()); + + foo({ + x: new Bar(), + y: new Date() + }, getNum); + ~~~~~~ +!!! error TS2322: Type '() => number' is not assignable to type 'number'. +!!! related TS6212 tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts:17:4: Did you mean to call this expression? + + + foo({ + x: new Bar(), + y: new Date() + }, getNum(), [ + 1, + 2, + getNum + ~~~~~~ +!!! error TS2322: Type '() => number' is not assignable to type 'number'. +!!! related TS6212 tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts:26:5: Did you mean to call this expression? + ]); + \ No newline at end of file diff --git a/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.js b/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.js new file mode 100644 index 0000000000000..3e2aaec27a44c --- /dev/null +++ b/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.js @@ -0,0 +1,52 @@ +//// [didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts] +class Bar { + x!: string; +} + +declare function getNum(): number; + +declare function foo(arg: { x: Bar, y: Date }, item: number, items?: [number, number, number]): void; + +foo({ + x: Bar, + y: Date +}, getNum()); + +foo({ + x: new Bar(), + y: new Date() +}, getNum); + + +foo({ + x: new Bar(), + y: new Date() +}, getNum(), [ + 1, + 2, + getNum +]); + + +//// [didYouMeanElaborationsForExpressionsWhichCouldBeCalled.js] +var Bar = /** @class */ (function () { + function Bar() { + } + return Bar; +}()); +foo({ + x: Bar, + y: Date +}, getNum()); +foo({ + x: new Bar(), + y: new Date() +}, getNum); +foo({ + x: new Bar(), + y: new Date() +}, getNum(), [ + 1, + 2, + getNum +]); diff --git a/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.symbols b/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.symbols new file mode 100644 index 0000000000000..d7f6457c262b3 --- /dev/null +++ b/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.symbols @@ -0,0 +1,71 @@ +=== tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts === +class Bar { +>Bar : Symbol(Bar, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 0, 0)) + + x!: string; +>x : Symbol(Bar.x, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 0, 11)) +} + +declare function getNum(): number; +>getNum : Symbol(getNum, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 2, 1)) + +declare function foo(arg: { x: Bar, y: Date }, item: number, items?: [number, number, number]): void; +>foo : Symbol(foo, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 4, 34)) +>arg : Symbol(arg, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 6, 21)) +>x : Symbol(x, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 6, 27)) +>Bar : Symbol(Bar, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 0, 0)) +>y : Symbol(y, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 6, 35)) +>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) +>item : Symbol(item, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 6, 46)) +>items : Symbol(items, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 6, 60)) + +foo({ +>foo : Symbol(foo, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 4, 34)) + + x: Bar, +>x : Symbol(x, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 8, 5)) +>Bar : Symbol(Bar, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 0, 0)) + + y: Date +>y : Symbol(y, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 9, 11)) +>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) + +}, getNum()); +>getNum : Symbol(getNum, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 2, 1)) + +foo({ +>foo : Symbol(foo, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 4, 34)) + + x: new Bar(), +>x : Symbol(x, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 13, 5)) +>Bar : Symbol(Bar, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 0, 0)) + + y: new Date() +>y : Symbol(y, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 14, 17)) +>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) + +}, getNum); +>getNum : Symbol(getNum, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 2, 1)) + + +foo({ +>foo : Symbol(foo, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 4, 34)) + + x: new Bar(), +>x : Symbol(x, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 19, 5)) +>Bar : Symbol(Bar, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 0, 0)) + + y: new Date() +>y : Symbol(y, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 20, 17)) +>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) + +}, getNum(), [ +>getNum : Symbol(getNum, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 2, 1)) + + 1, + 2, + getNum +>getNum : Symbol(getNum, Decl(didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts, 2, 1)) + +]); + diff --git a/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.types b/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.types new file mode 100644 index 0000000000000..bd60a27864513 --- /dev/null +++ b/tests/baselines/reference/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.types @@ -0,0 +1,86 @@ +=== tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts === +class Bar { +>Bar : Bar + + x!: string; +>x : string +} + +declare function getNum(): number; +>getNum : () => number + +declare function foo(arg: { x: Bar, y: Date }, item: number, items?: [number, number, number]): void; +>foo : (arg: { x: Bar; y: Date; }, item: number, items?: [number, number, number]) => void +>arg : { x: Bar; y: Date; } +>x : Bar +>y : Date +>item : number +>items : [number, number, number] + +foo({ +>foo({ x: Bar, y: Date}, getNum()) : void +>foo : (arg: { x: Bar; y: Date; }, item: number, items?: [number, number, number]) => void +>{ x: Bar, y: Date} : { x: typeof Bar; y: DateConstructor; } + + x: Bar, +>x : typeof Bar +>Bar : typeof Bar + + y: Date +>y : DateConstructor +>Date : DateConstructor + +}, getNum()); +>getNum() : number +>getNum : () => number + +foo({ +>foo({ x: new Bar(), y: new Date()}, getNum) : void +>foo : (arg: { x: Bar; y: Date; }, item: number, items?: [number, number, number]) => void +>{ x: new Bar(), y: new Date()} : { x: Bar; y: Date; } + + x: new Bar(), +>x : Bar +>new Bar() : Bar +>Bar : typeof Bar + + y: new Date() +>y : Date +>new Date() : Date +>Date : DateConstructor + +}, getNum); +>getNum : () => number + + +foo({ +>foo({ x: new Bar(), y: new Date()}, getNum(), [ 1, 2, getNum]) : void +>foo : (arg: { x: Bar; y: Date; }, item: number, items?: [number, number, number]) => void +>{ x: new Bar(), y: new Date()} : { x: Bar; y: Date; } + + x: new Bar(), +>x : Bar +>new Bar() : Bar +>Bar : typeof Bar + + y: new Date() +>y : Date +>new Date() : Date +>Date : DateConstructor + +}, getNum(), [ +>getNum() : number +>getNum : () => number +>[ 1, 2, getNum] : (number | (() => number))[] + + 1, +>1 : 1 + + 2, +>2 : 2 + + getNum +>getNum : () => number + +]); + diff --git a/tests/baselines/reference/functionSignatureAssignmentCompat1.errors.txt b/tests/baselines/reference/functionSignatureAssignmentCompat1.errors.txt index f91a4f9154789..bc2dc17dfbc9c 100644 --- a/tests/baselines/reference/functionSignatureAssignmentCompat1.errors.txt +++ b/tests/baselines/reference/functionSignatureAssignmentCompat1.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/functionSignatureAssignmentCompat1.ts(10,5): error TS2322: Type '(delimiter?: string) => ParserFunc' is not assignable to type 'ParserFunc'. +tests/cases/compiler/functionSignatureAssignmentCompat1.ts(10,21): error TS2322: Type '(delimiter?: string) => ParserFunc' is not assignable to type 'ParserFunc'. Types of parameters 'delimiter' and 'eventEmitter' are incompatible. Type 'number' is not assignable to type 'string'. @@ -14,8 +14,9 @@ tests/cases/compiler/functionSignatureAssignmentCompat1.ts(10,5): error TS2322: var parsers: Parsers; var c: ParserFunc = parsers.raw; // ok! var d: ParserFunc = parsers.readline; // not ok - ~ + ~~~~~~~~~~~~~~~~ !!! error TS2322: Type '(delimiter?: string) => ParserFunc' is not assignable to type 'ParserFunc'. !!! error TS2322: Types of parameters 'delimiter' and 'eventEmitter' are incompatible. !!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! related TS6212 tests/cases/compiler/functionSignatureAssignmentCompat1.ts:10:21: Did you mean to call this expression? var e: ParserFunc = parsers.readline(); // ok \ No newline at end of file diff --git a/tests/baselines/reference/invalidAssignmentsToVoid.errors.txt b/tests/baselines/reference/invalidAssignmentsToVoid.errors.txt index 4b9b316e01097..fd3fa48c01be2 100644 --- a/tests/baselines/reference/invalidAssignmentsToVoid.errors.txt +++ b/tests/baselines/reference/invalidAssignmentsToVoid.errors.txt @@ -7,7 +7,7 @@ tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts(10,1): tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts(14,1): error TS2322: Type 'I' is not assignable to type 'void'. tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts(17,1): error TS2322: Type 'typeof M' is not assignable to type 'void'. tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts(20,5): error TS2322: Type 'T' is not assignable to type 'void'. -tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts(22,1): error TS2322: Type '(a: T) => void' is not assignable to type 'void'. +tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts(22,5): error TS2322: Type '(a: T) => void' is not assignable to type 'void'. ==== tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts (10 errors) ==== @@ -51,5 +51,6 @@ tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts(22,1): !!! error TS2322: Type 'T' is not assignable to type 'void'. } x = f; - ~ -!!! error TS2322: Type '(a: T) => void' is not assignable to type 'void'. \ No newline at end of file + ~ +!!! error TS2322: Type '(a: T) => void' is not assignable to type 'void'. +!!! related TS6212 tests/cases/conformance/types/primitives/void/invalidAssignmentsToVoid.ts:22:5: Did you mean to call this expression? \ No newline at end of file diff --git a/tests/baselines/reference/invalidVoidValues.errors.txt b/tests/baselines/reference/invalidVoidValues.errors.txt index 8fc015f692f10..51155152864b3 100644 --- a/tests/baselines/reference/invalidVoidValues.errors.txt +++ b/tests/baselines/reference/invalidVoidValues.errors.txt @@ -8,7 +8,7 @@ tests/cases/conformance/types/primitives/void/invalidVoidValues.ts(16,1): error tests/cases/conformance/types/primitives/void/invalidVoidValues.ts(18,1): error TS2322: Type '{ f(): void; }' is not assignable to type 'void'. tests/cases/conformance/types/primitives/void/invalidVoidValues.ts(21,1): error TS2322: Type 'typeof M' is not assignable to type 'void'. tests/cases/conformance/types/primitives/void/invalidVoidValues.ts(24,5): error TS2322: Type 'T' is not assignable to type 'void'. -tests/cases/conformance/types/primitives/void/invalidVoidValues.ts(26,1): error TS2322: Type '(a: T) => void' is not assignable to type 'void'. +tests/cases/conformance/types/primitives/void/invalidVoidValues.ts(26,5): error TS2322: Type '(a: T) => void' is not assignable to type 'void'. ==== tests/cases/conformance/types/primitives/void/invalidVoidValues.ts (11 errors) ==== @@ -58,5 +58,6 @@ tests/cases/conformance/types/primitives/void/invalidVoidValues.ts(26,1): error !!! error TS2322: Type 'T' is not assignable to type 'void'. } x = f; - ~ -!!! error TS2322: Type '(a: T) => void' is not assignable to type 'void'. \ No newline at end of file + ~ +!!! error TS2322: Type '(a: T) => void' is not assignable to type 'void'. +!!! related TS6212 tests/cases/conformance/types/primitives/void/invalidVoidValues.ts:26:5: Did you mean to call this expression? \ No newline at end of file diff --git a/tests/baselines/reference/optionalParamAssignmentCompat.errors.txt b/tests/baselines/reference/optionalParamAssignmentCompat.errors.txt index 5ab492540ac90..10222bc5d8fc0 100644 --- a/tests/baselines/reference/optionalParamAssignmentCompat.errors.txt +++ b/tests/baselines/reference/optionalParamAssignmentCompat.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/optionalParamAssignmentCompat.ts(10,5): error TS2322: Type '(p1?: string) => I1' is not assignable to type 'I1'. +tests/cases/compiler/optionalParamAssignmentCompat.ts(10,13): error TS2322: Type '(p1?: string) => I1' is not assignable to type 'I1'. Types of parameters 'p1' and 'p1' are incompatible. Type 'number' is not assignable to type 'string'. @@ -14,8 +14,9 @@ tests/cases/compiler/optionalParamAssignmentCompat.ts(10,5): error TS2322: Type var i2: I2; var c: I1 = i2.p1; // should be ok var d: I1 = i2.m1; // should error - ~ + ~~~~~ !!! error TS2322: Type '(p1?: string) => I1' is not assignable to type 'I1'. !!! error TS2322: Types of parameters 'p1' and 'p1' are incompatible. !!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! related TS6212 tests/cases/compiler/optionalParamAssignmentCompat.ts:10:13: Did you mean to call this expression? \ No newline at end of file diff --git a/tests/baselines/reference/parser536727.errors.txt b/tests/baselines/reference/parser536727.errors.txt index 4204e62c93b03..6cdf152582f38 100644 --- a/tests/baselines/reference/parser536727.errors.txt +++ b/tests/baselines/reference/parser536727.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/parser/ecmascript5/RegressionTests/parser536727.ts(7,5): error TS2345: Argument of type '() => (x: string) => string' is not assignable to parameter of type '(x: string) => string'. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser536727.ts(7,5): error TS2322: Type '() => (x: string) => string' is not assignable to type '(x: string) => string'. Type '(x: string) => string' is not assignable to type 'string'. -tests/cases/conformance/parser/ecmascript5/RegressionTests/parser536727.ts(8,5): error TS2345: Argument of type '() => (x: string) => string' is not assignable to parameter of type '(x: string) => string'. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser536727.ts(8,5): error TS2322: Type '() => (x: string) => string' is not assignable to type '(x: string) => string'. Type '(x: string) => string' is not assignable to type 'string'. @@ -13,10 +13,12 @@ tests/cases/conformance/parser/ecmascript5/RegressionTests/parser536727.ts(8,5): foo(g); foo(() => g); ~~~~~~~ -!!! error TS2345: Argument of type '() => (x: string) => string' is not assignable to parameter of type '(x: string) => string'. -!!! error TS2345: Type '(x: string) => string' is not assignable to type 'string'. +!!! error TS2322: Type '() => (x: string) => string' is not assignable to type '(x: string) => string'. +!!! error TS2322: Type '(x: string) => string' is not assignable to type 'string'. +!!! related TS6212 tests/cases/conformance/parser/ecmascript5/RegressionTests/parser536727.ts:7:5: Did you mean to call this expression? foo(x); ~ -!!! error TS2345: Argument of type '() => (x: string) => string' is not assignable to parameter of type '(x: string) => string'. -!!! error TS2345: Type '(x: string) => string' is not assignable to type 'string'. +!!! error TS2322: Type '() => (x: string) => string' is not assignable to type '(x: string) => string'. +!!! error TS2322: Type '(x: string) => string' is not assignable to type 'string'. +!!! related TS6212 tests/cases/conformance/parser/ecmascript5/RegressionTests/parser536727.ts:8:5: Did you mean to call this expression? \ No newline at end of file diff --git a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt index 36ead7083319d..734ef74c21860 100644 --- a/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt +++ b/tests/baselines/reference/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.errors.txt @@ -1,10 +1,10 @@ tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(12,1): error TS2322: Type 'C' is not assignable to type 'A'. Property 'prop' is missing in type 'C'. -tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(13,1): error TS2322: Type 'typeof B' is not assignable to type 'A'. +tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(13,5): error TS2322: Type 'typeof B' is not assignable to type 'A'. Property 'prop' is missing in type 'typeof B'. tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(16,5): error TS2322: Type 'C' is not assignable to type 'B'. Property 'prop' is missing in type 'C'. -tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(17,1): error TS2322: Type 'typeof B' is not assignable to type 'B'. +tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts(17,5): error TS2322: Type 'typeof B' is not assignable to type 'B'. Property 'prop' is missing in type 'typeof B'. @@ -25,9 +25,10 @@ tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment. !!! error TS2322: Type 'C' is not assignable to type 'A'. !!! error TS2322: Property 'prop' is missing in type 'C'. a = B; // error prop is missing - ~ + ~ !!! error TS2322: Type 'typeof B' is not assignable to type 'A'. !!! error TS2322: Property 'prop' is missing in type 'typeof B'. +!!! related TS6213 tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts:13:5: Did you mean to use `new` with this expression? a = C; var b: B = new C(); // error prop is missing @@ -35,9 +36,10 @@ tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment. !!! error TS2322: Type 'C' is not assignable to type 'B'. !!! error TS2322: Property 'prop' is missing in type 'C'. b = B; // error prop is missing - ~ + ~ !!! error TS2322: Type 'typeof B' is not assignable to type 'B'. !!! error TS2322: Property 'prop' is missing in type 'typeof B'. +!!! related TS6213 tests/cases/compiler/staticMemberOfClassAndPublicMemberOfAnotherClassAssignment.ts:17:5: Did you mean to use `new` with this expression? b = C; b = a; diff --git a/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations2.errors.txt b/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations2.errors.txt index 3a33fe7405631..511a1ef68a85c 100644 --- a/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations2.errors.txt +++ b/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations2.errors.txt @@ -4,9 +4,9 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(24,5): error TS2411: Property 'd' of type 'string' is not assignable to string index type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(31,5): error TS2411: Property 'c' of type 'number' is not assignable to string index type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(32,5): error TS2411: Property 'd' of type 'string' is not assignable to string index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(37,5): error TS2322: Type 'typeof A' is not assignable to type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(37,8): error TS2322: Type 'typeof A' is not assignable to type 'A'. Property 'foo' is missing in type 'typeof A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(38,5): error TS2322: Type 'typeof B' is not assignable to type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(38,8): error TS2322: Type 'typeof B' is not assignable to type 'A'. Property 'foo' is missing in type 'typeof B'. @@ -60,13 +60,13 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon // error var b: { [x: string]: A } = { a: A, - ~ + ~ !!! error TS2322: Type 'typeof A' is not assignable to type 'A'. !!! error TS2322: Property 'foo' is missing in type 'typeof A'. -!!! related TS6501 tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts:36:10: The expected type comes from this index signature. +!!! related TS6213 tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts:37:8: Did you mean to use `new` with this expression? b: B - ~ + ~ !!! error TS2322: Type 'typeof B' is not assignable to type 'A'. !!! error TS2322: Property 'foo' is missing in type 'typeof B'. -!!! related TS6501 tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts:36:10: The expected type comes from this index signature. +!!! related TS6213 tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts:38:8: Did you mean to use `new` with this expression? } \ No newline at end of file diff --git a/tests/baselines/reference/typeMatch1.errors.txt b/tests/baselines/reference/typeMatch1.errors.txt index 7025fd0c3b2dc..598d9f97483a7 100644 --- a/tests/baselines/reference/typeMatch1.errors.txt +++ b/tests/baselines/reference/typeMatch1.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/typeMatch1.ts(18,1): error TS2322: Type 'D' is not assignable to type 'C'. Types have separate declarations of a private property 'x'. -tests/cases/compiler/typeMatch1.ts(19,1): error TS2322: Type 'typeof C' is not assignable to type 'C'. +tests/cases/compiler/typeMatch1.ts(19,4): error TS2322: Type 'typeof C' is not assignable to type 'C'. Property 'x' is missing in type 'typeof C'. tests/cases/compiler/typeMatch1.ts(20,1): error TS2367: This condition will always return 'false' since the types 'typeof C' and 'typeof D' have no overlap. @@ -28,9 +28,10 @@ tests/cases/compiler/typeMatch1.ts(20,1): error TS2367: This condition will alwa !!! error TS2322: Type 'D' is not assignable to type 'C'. !!! error TS2322: Types have separate declarations of a private property 'x'. x6=C; - ~~ + ~ !!! error TS2322: Type 'typeof C' is not assignable to type 'C'. !!! error TS2322: Property 'x' is missing in type 'typeof C'. +!!! related TS6213 tests/cases/compiler/typeMatch1.ts:19:4: Did you mean to use `new` with this expression? C==D; ~~~~ !!! error TS2367: This condition will always return 'false' since the types 'typeof C' and 'typeof D' have no overlap. diff --git a/tests/baselines/reference/weakType.errors.txt b/tests/baselines/reference/weakType.errors.txt index ffc1d23759358..869f60cd92439 100644 --- a/tests/baselines/reference/weakType.errors.txt +++ b/tests/baselines/reference/weakType.errors.txt @@ -29,12 +29,15 @@ tests/cases/compiler/weakType.ts(62,5): error TS2322: Type '{ properties: { wron doSomething(getDefaultSettings); ~~~~~~~~~~~~~~~~~~ !!! error TS2560: Value of type '() => { timeout: number; }' has no properties in common with type 'Settings'. Did you mean to call it? +!!! related TS6212 tests/cases/compiler/weakType.ts:15:13: Did you mean to call this expression? doSomething(() => ({ timeout: 1000 })); ~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2560: Value of type '() => { timeout: number; }' has no properties in common with type 'Settings'. Did you mean to call it? +!!! related TS6212 tests/cases/compiler/weakType.ts:16:13: Did you mean to call this expression? doSomething(null as CtorOnly); ~~~~~~~~~~~~~~~~ !!! error TS2560: Value of type 'CtorOnly' has no properties in common with type 'Settings'. Did you mean to call it? +!!! related TS6213 tests/cases/compiler/weakType.ts:17:13: Did you mean to use `new` with this expression? doSomething(12); ~~ !!! error TS2559: Type '12' has no properties in common with type 'Settings'. diff --git a/tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts b/tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts new file mode 100644 index 0000000000000..392f3461d9a47 --- /dev/null +++ b/tests/cases/compiler/didYouMeanElaborationsForExpressionsWhichCouldBeCalled.ts @@ -0,0 +1,27 @@ +class Bar { + x!: string; +} + +declare function getNum(): number; + +declare function foo(arg: { x: Bar, y: Date }, item: number, items?: [number, number, number]): void; + +foo({ + x: Bar, + y: Date +}, getNum()); + +foo({ + x: new Bar(), + y: new Date() +}, getNum); + + +foo({ + x: new Bar(), + y: new Date() +}, getNum(), [ + 1, + 2, + getNum +]);