diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1a99c2642fd..c89c78e83eb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24537,7 +24537,9 @@ namespace ts { if (awaitedTypesAreCompatible) { const awaitedLeftType = getAwaitedType(leftType); const awaitedRightType = getAwaitedType(rightType); - wouldWorkWithAwait = !!(awaitedLeftType && awaitedRightType) && awaitedTypesAreCompatible(awaitedLeftType, awaitedRightType); + wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType) + && !!(awaitedLeftType && awaitedRightType) + && awaitedTypesAreCompatible(awaitedLeftType, awaitedRightType); } if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) { @@ -24558,11 +24560,11 @@ namespace ts { switch (operatorToken.kind) { case SyntaxKind.EqualsEqualsEqualsToken: case SyntaxKind.EqualsEqualsToken: - typeName = "true"; + typeName = "false"; break; case SyntaxKind.ExclamationEqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: - typeName = "false"; + typeName = "true"; } if (typeName) { diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt new file mode 100644 index 00000000000..20f5767d027 --- /dev/null +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.errors.txt @@ -0,0 +1,91 @@ +tests/cases/compiler/operationsAvailableOnPromisedType.ts(11,9): error TS2766: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(12,5): error TS2765: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(13,5): error TS2763: Operator '+' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(14,5): error TS2763: Operator '>' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(15,5): error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(16,7): error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(17,5): error TS2776: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(18,9): error TS2769: Type 'Promise' is not an array type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(19,21): error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(20,9): error TS2554: Expected 7 arguments, but got 4. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(21,11): error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(23,27): error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? +tests/cases/compiler/operationsAvailableOnPromisedType.ts(24,5): error TS2774: This expression is not callable. Did you forget to use 'await'? + Type 'Promise<() => void>' has no call signatures. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(25,5): error TS2774: This expression is not callable. Did you forget to use 'await'? + Not all constituents of type 'Promise<() => void> | (() => void)' are callable. + Type 'Promise<() => void>' has no call signatures. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(26,9): error TS2775: This expression is not constructable. Did you forget to use 'await'? + Type 'Promise any>' has no construct signatures. +tests/cases/compiler/operationsAvailableOnPromisedType.ts(27,5): error TS2349: This expression is not callable. + Type 'Promise' has no call signatures. + + +==== tests/cases/compiler/operationsAvailableOnPromisedType.ts (16 errors) ==== + async function fn( + a: number, + b: Promise, + c: Promise, + d: Promise<{ prop: string }>, + e: Promise<() => void>, + f: Promise<() => void> | (() => void), + g: Promise<{ new(): any }> + ) { + // All errors + a | b; + ~ +!!! error TS2766: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? + b | a; + ~ +!!! error TS2765: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? + a + b; + ~~~~~ +!!! error TS2763: Operator '+' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? + a > b; + ~~~~~ +!!! error TS2763: Operator '>' cannot be applied to types 'number' and 'Promise'. Did you forget to use 'await'? + b++; + ~ +!!! error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? + --b; + ~ +!!! error TS2764: An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'? + a === b; + ~~~~~~~ +!!! error TS2776: This condition will always return 'false' since the types 'number' and 'Promise' have no overlap. Did you forget to use 'await'? + [...c]; + ~ +!!! error TS2769: Type 'Promise' is not an array type. Did you forget to use 'await'? + for (const s of c) { + ~ +!!! error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? + fn(b, b, c, d); + ~~~~~~~~~~~~~~ +!!! error TS2554: Expected 7 arguments, but got 4. +!!! related TS6210 tests/cases/compiler/operationsAvailableOnPromisedType.ts:6:5: An argument for 'e' was not provided. + d.prop; + ~~~~ +!!! error TS2570: Property 'prop' does not exist on type 'Promise<{ prop: string; }>'. Did you forget to use 'await'? + } + for await (const s of c) {} + ~ +!!! error TS2770: Type 'Promise' is not an array type or a string type. Did you forget to use 'await'? + e(); + ~ +!!! error TS2774: This expression is not callable. Did you forget to use 'await'? +!!! error TS2774: Type 'Promise<() => void>' has no call signatures. + f(); + ~ +!!! error TS2774: This expression is not callable. Did you forget to use 'await'? +!!! error TS2774: Not all constituents of type 'Promise<() => void> | (() => void)' are callable. +!!! error TS2774: Type 'Promise<() => void>' has no call signatures. + new g(); + ~ +!!! error TS2775: This expression is not constructable. Did you forget to use 'await'? +!!! error TS2775: Type 'Promise any>' has no construct signatures. + b(); + ~ +!!! error TS2349: This expression is not callable. +!!! error TS2349: Type 'Promise' has no call signatures. + } + \ No newline at end of file diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.js b/tests/baselines/reference/operationsAvailableOnPromisedType.js new file mode 100644 index 00000000000..889797a64b0 --- /dev/null +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.js @@ -0,0 +1,141 @@ +//// [operationsAvailableOnPromisedType.ts] +async function fn( + a: number, + b: Promise, + c: Promise, + d: Promise<{ prop: string }>, + e: Promise<() => void>, + f: Promise<() => void> | (() => void), + g: Promise<{ new(): any }> +) { + // All errors + a | b; + b | a; + a + b; + a > b; + b++; + --b; + a === b; + [...c]; + for (const s of c) { + fn(b, b, c, d); + d.prop; + } + for await (const s of c) {} + e(); + f(); + new g(); + b(); +} + + +//// [operationsAvailableOnPromisedType.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var __asyncValues = (this && this.__asyncValues) || function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } +}; +var __spreadArrays = (this && this.__spreadArrays) || function () { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; +}; +function fn(a, b, c, d, e, f, g) { + var c_1, c_1_1; + var e_1, _a; + return __awaiter(this, void 0, void 0, function () { + var _i, c_2, s, s, e_1_1; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + // All errors + a | b; + b | a; + a + b; + a > b; + b++; + --b; + a === b; + __spreadArrays(c); + for (_i = 0, c_2 = c; _i < c_2.length; _i++) { + s = c_2[_i]; + fn(b, b, c, d); + d.prop; + } + _b.label = 1; + case 1: + _b.trys.push([1, 6, 7, 12]); + c_1 = __asyncValues(c); + _b.label = 2; + case 2: return [4 /*yield*/, c_1.next()]; + case 3: + if (!(c_1_1 = _b.sent(), !c_1_1.done)) return [3 /*break*/, 5]; + s = c_1_1.value; + _b.label = 4; + case 4: return [3 /*break*/, 2]; + case 5: return [3 /*break*/, 12]; + case 6: + e_1_1 = _b.sent(); + e_1 = { error: e_1_1 }; + return [3 /*break*/, 12]; + case 7: + _b.trys.push([7, , 10, 11]); + if (!(c_1_1 && !c_1_1.done && (_a = c_1["return"]))) return [3 /*break*/, 9]; + return [4 /*yield*/, _a.call(c_1)]; + case 8: + _b.sent(); + _b.label = 9; + case 9: return [3 /*break*/, 11]; + case 10: + if (e_1) throw e_1.error; + return [7 /*endfinally*/]; + case 11: return [7 /*endfinally*/]; + case 12: + e(); + f(); + new g(); + b(); + return [2 /*return*/]; + } + }); + }); +} diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.symbols b/tests/baselines/reference/operationsAvailableOnPromisedType.symbols new file mode 100644 index 00000000000..7f746d2486c --- /dev/null +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.symbols @@ -0,0 +1,94 @@ +=== tests/cases/compiler/operationsAvailableOnPromisedType.ts === +async function fn( +>fn : Symbol(fn, Decl(operationsAvailableOnPromisedType.ts, 0, 0)) + + a: number, +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) + + b: Promise, +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + + c: Promise, +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + + d: Promise<{ prop: string }>, +>d : Symbol(d, Decl(operationsAvailableOnPromisedType.ts, 3, 25)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +>prop : Symbol(prop, Decl(operationsAvailableOnPromisedType.ts, 4, 16)) + + e: Promise<() => void>, +>e : Symbol(e, Decl(operationsAvailableOnPromisedType.ts, 4, 33)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + + f: Promise<() => void> | (() => void), +>f : Symbol(f, Decl(operationsAvailableOnPromisedType.ts, 5, 27)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + + g: Promise<{ new(): any }> +>g : Symbol(g, Decl(operationsAvailableOnPromisedType.ts, 6, 42)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) + +) { + // All errors + a | b; +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + b | a; +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) + + a + b; +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + a > b; +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + b++; +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + --b; +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + a === b; +>a : Symbol(a, Decl(operationsAvailableOnPromisedType.ts, 0, 18)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) + + [...c]; +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) + + for (const s of c) { +>s : Symbol(s, Decl(operationsAvailableOnPromisedType.ts, 18, 14)) +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) + + fn(b, b, c, d); +>fn : Symbol(fn, Decl(operationsAvailableOnPromisedType.ts, 0, 0)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) +>d : Symbol(d, Decl(operationsAvailableOnPromisedType.ts, 3, 25)) + + d.prop; +>d : Symbol(d, Decl(operationsAvailableOnPromisedType.ts, 3, 25)) + } + for await (const s of c) {} +>s : Symbol(s, Decl(operationsAvailableOnPromisedType.ts, 22, 20)) +>c : Symbol(c, Decl(operationsAvailableOnPromisedType.ts, 2, 23)) + + e(); +>e : Symbol(e, Decl(operationsAvailableOnPromisedType.ts, 4, 33)) + + f(); +>f : Symbol(f, Decl(operationsAvailableOnPromisedType.ts, 5, 27)) + + new g(); +>g : Symbol(g, Decl(operationsAvailableOnPromisedType.ts, 6, 42)) + + b(); +>b : Symbol(b, Decl(operationsAvailableOnPromisedType.ts, 1, 14)) +} + diff --git a/tests/baselines/reference/operationsAvailableOnPromisedType.types b/tests/baselines/reference/operationsAvailableOnPromisedType.types new file mode 100644 index 00000000000..207f9efcfd3 --- /dev/null +++ b/tests/baselines/reference/operationsAvailableOnPromisedType.types @@ -0,0 +1,104 @@ +=== tests/cases/compiler/operationsAvailableOnPromisedType.ts === +async function fn( +>fn : (a: number, b: Promise, c: Promise, d: Promise<{ prop: string; }>, e: Promise<() => void>, f: Promise<() => void> | (() => void), g: Promise any>) => Promise + + a: number, +>a : number + + b: Promise, +>b : Promise + + c: Promise, +>c : Promise + + d: Promise<{ prop: string }>, +>d : Promise<{ prop: string; }> +>prop : string + + e: Promise<() => void>, +>e : Promise<() => void> + + f: Promise<() => void> | (() => void), +>f : Promise<() => void> | (() => void) + + g: Promise<{ new(): any }> +>g : Promise any> + +) { + // All errors + a | b; +>a | b : number +>a : number +>b : Promise + + b | a; +>b | a : number +>b : Promise +>a : number + + a + b; +>a + b : any +>a : number +>b : Promise + + a > b; +>a > b : boolean +>a : number +>b : Promise + + b++; +>b++ : number +>b : Promise + + --b; +>--b : number +>b : Promise + + a === b; +>a === b : boolean +>a : number +>b : Promise + + [...c]; +>[...c] : any[] +>...c : any +>c : Promise + + for (const s of c) { +>s : any +>c : Promise + + fn(b, b, c, d); +>fn(b, b, c, d) : Promise +>fn : (a: number, b: Promise, c: Promise, d: Promise<{ prop: string; }>, e: Promise<() => void>, f: Promise<() => void> | (() => void), g: Promise any>) => Promise +>b : Promise +>b : Promise +>c : Promise +>d : Promise<{ prop: string; }> + + d.prop; +>d.prop : any +>d : Promise<{ prop: string; }> +>prop : any + } + for await (const s of c) {} +>s : any +>c : Promise + + e(); +>e() : any +>e : Promise<() => void> + + f(); +>f() : any +>f : Promise<() => void> | (() => void) + + new g(); +>new g() : any +>g : Promise any> + + b(); +>b() : any +>b : Promise +} + diff --git a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt index c8c4ed39ed7..b00f35c503f 100644 --- a/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt +++ b/tests/baselines/reference/types.asyncGenerators.es2018.2.errors.txt @@ -1,5 +1,5 @@ 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(8,12): error TS2780: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'? 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. @@ -71,7 +71,7 @@ tests/cases/conformance/types/asyncGenerators/types.asyncGenerators.es2018.2.ts( async function * inferReturnType3() { yield* Promise.resolve([1, 2]); ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2504: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. +!!! error TS2780: Type 'Promise' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'? } const assignability1: () => AsyncIterableIterator = async function * () { ~~~~~~~~~~~~~~