From bc386c11fd3f026ca84ec556b1b8fb4a2eee0038 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 7 Feb 2019 13:35:07 -0800 Subject: [PATCH 01/14] Use execFileSync in typing installer --- .../unittests/tsserver/typingsInstaller.ts | 12 ++++++------ src/typingsInstaller/nodeTypingsInstaller.ts | 16 ++++++++-------- src/typingsInstallerCore/typingsInstaller.ts | 17 ++++++++++++----- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/testRunner/unittests/tsserver/typingsInstaller.ts b/src/testRunner/unittests/tsserver/typingsInstaller.ts index 76df993468..5d648ba23a 100644 --- a/src/testRunner/unittests/tsserver/typingsInstaller.ts +++ b/src/testRunner/unittests/tsserver/typingsInstaller.ts @@ -1684,9 +1684,9 @@ namespace ts.projectSystem { TI.getNpmCommandForInstallation(npmPath, tsVersion, packageNames, packageNames.length - Math.ceil(packageNames.length / 2)).command ]; it("works when the command is too long to install all packages at once", () => { - const commands: string[] = []; - const hasError = TI.installNpmPackages(npmPath, tsVersion, packageNames, command => { - commands.push(command); + const commands: [string, string[]][] = []; + const hasError = TI.installNpmPackages(npmPath, tsVersion, packageNames, (file, args) => { + commands.push([file, args]); return false; }); assert.isFalse(hasError); @@ -1694,9 +1694,9 @@ namespace ts.projectSystem { }); it("installs remaining packages when one of the partial command fails", () => { - const commands: string[] = []; - const hasError = TI.installNpmPackages(npmPath, tsVersion, packageNames, command => { - commands.push(command); + const commands: [string, string[]][] = []; + const hasError = TI.installNpmPackages(npmPath, tsVersion, packageNames, (file, args) => { + commands.push([file, args]); return commands.length === 1; }); assert.isTrue(hasError); diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index 62bdcfce26..1d75218c88 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -70,10 +70,10 @@ namespace ts.server.typingsInstaller { cwd: string; encoding: "utf-8"; } - type ExecSync = (command: string, options: ExecSyncOptions) => string; + type ExecFileSync = (file: string, args: string[], options: ExecSyncOptions) => string; export class NodeTypingsInstaller extends TypingsInstaller { - private readonly nodeExecSync: ExecSync; + private readonly nodeExecFileSync: ExecFileSync; private readonly npmPath: string; readonly typesRegistry: Map>; @@ -97,7 +97,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`Process id: ${process.pid}`); this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`); } - ({ execSync: this.nodeExecSync } = require("child_process")); + ({ execFileSync: this.nodeExecFileSync } = require("child_process")); this.ensurePackageDirectoryExists(globalTypingsCacheLocation); @@ -105,7 +105,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Updating ${typesRegistryPackageName} npm package...`); } - this.execSyncAndLog(`${this.npmPath} install --ignore-scripts ${typesRegistryPackageName}@${this.latestDistTag}`, { cwd: globalTypingsCacheLocation }); + this.execFileSyncAndLog(this.npmPath, ["install", "--ignore-scripts", `${typesRegistryPackageName}@${this.latestDistTag}`], { cwd: globalTypingsCacheLocation }); if (this.log.isEnabled()) { this.log.writeLine(`Updated ${typesRegistryPackageName} npm package`); } @@ -189,7 +189,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(packageNames)}'.`); } const start = Date.now(); - const hasError = installNpmPackages(this.npmPath, version, packageNames, command => this.execSyncAndLog(command, { cwd })); + const hasError = installNpmPackages(this.npmPath, version, packageNames, (file, args) => this.execFileSyncAndLog(file, args, { cwd })); if (this.log.isEnabled()) { this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms`); } @@ -197,12 +197,12 @@ namespace ts.server.typingsInstaller { } /** Returns 'true' in case of error. */ - private execSyncAndLog(command: string, options: Pick): boolean { + private execFileSyncAndLog(file: string, args: string[], options: Pick): boolean { if (this.log.isEnabled()) { - this.log.writeLine(`Exec: ${command}`); + this.log.writeLine(`Exec: ${file} ${args.join(" ")}`); } try { - const stdout = this.nodeExecSync(command, { ...options, encoding: "utf-8" }); + const stdout = this.nodeExecFileSync(file, args, { ...options, encoding: "utf-8" }); if (this.log.isEnabled()) { this.log.writeLine(` Succeeded. stdout:${indent(sys.newLine, stdout)}`); } diff --git a/src/typingsInstallerCore/typingsInstaller.ts b/src/typingsInstallerCore/typingsInstaller.ts index df83f1a677..3d0858d7df 100644 --- a/src/typingsInstallerCore/typingsInstaller.ts +++ b/src/typingsInstallerCore/typingsInstaller.ts @@ -31,28 +31,35 @@ namespace ts.server.typingsInstaller { } /*@internal*/ - export function installNpmPackages(npmPath: string, tsVersion: string, packageNames: string[], install: (command: string) => boolean) { + export function installNpmPackages(npmPath: string, tsVersion: string, packageNames: string[], install: (file: string, args: string[]) => boolean) { let hasError = false; for (let remaining = packageNames.length; remaining > 0;) { const result = getNpmCommandForInstallation(npmPath, tsVersion, packageNames, remaining); remaining = result.remaining; - hasError = install(result.command) || hasError; + hasError = install(result.command[0], result.command[1]) || hasError; } return hasError; } + function getUserAgent(tsVersion: string) { + return `--user-agent="typesInstaller/${tsVersion}"`; + } + const npmInstall = "install", ignoreScripts = "--ignore-scripts", saveDev = "--save-dev"; + const commandBaseLength = npmInstall.length + ignoreScripts.length + saveDev.length + getUserAgent("").length + 5; /*@internal*/ export function getNpmCommandForInstallation(npmPath: string, tsVersion: string, packageNames: string[], remaining: number) { const sliceStart = packageNames.length - remaining; - let command: string, toSlice = remaining; + let packages: string[], toSlice = remaining; while (true) { - command = `${npmPath} install --ignore-scripts ${(toSlice === packageNames.length ? packageNames : packageNames.slice(sliceStart, sliceStart + toSlice)).join(" ")} --save-dev --user-agent="typesInstaller/${tsVersion}"`; - if (command.length < 8000) { + packages = toSlice === packageNames.length ? packageNames : packageNames.slice(sliceStart, sliceStart + toSlice); + const commandLength = npmPath.length + commandBaseLength + packages.join(" ").length + tsVersion.length; + if (commandLength < 8000) { break; } toSlice = toSlice - Math.floor(toSlice / 2); } + const command: [string, string[]] = [npmPath, [npmInstall, ignoreScripts, ...packages, saveDev, getUserAgent(tsVersion)]]; return { command, remaining: remaining - toSlice }; } From 950861ec7f314db7092f71eab815c248fe5dc5b8 Mon Sep 17 00:00:00 2001 From: Titian Cernicova-Dragomir Date: Wed, 13 Feb 2019 17:25:23 +0200 Subject: [PATCH 02/14] Improve error message for using value as type. --- src/compiler/checker.ts | 14 +++++++++++++- src/compiler/diagnosticMessages.json | 4 ++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9021a50ef8..a1248d536a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1518,7 +1518,8 @@ namespace ts { !checkAndReportErrorForExtendingInterface(errorLocation) && !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) && !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) && - !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) { + !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) && + !checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) { let suggestion: Symbol | undefined; if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) { suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning); @@ -1708,6 +1709,17 @@ namespace ts { return false; } + function checkAndReportErrorForUsingValueAsType(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean { + if (meaning & (SymbolFlags.Type & ~SymbolFlags.Namespace)) { + const symbol = resolveSymbol(resolveName(errorLocation, name, ~SymbolFlags.Type & SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false)); + if (symbol && !(symbol.flags & SymbolFlags.Namespace)) { + error(errorLocation, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here, unescapeLeadingUnderscores(name)); + return true; + } + } + return false; + } + function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean { if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) { if (name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never") { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e40fccd8bf..89794d2618 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2581,6 +2581,10 @@ "category": "Error", "code": 2748 }, + "'{0}' refers to a value, but is being used as a type here.": { + "category": "Error", + "code": 2749 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", From e1855740961320eda7fa79e45b7ec4bad73c6aab Mon Sep 17 00:00:00 2001 From: Titian Cernicova-Dragomir Date: Wed, 13 Feb 2019 17:39:06 +0200 Subject: [PATCH 03/14] Accept new baseline for Improve error message for using value as type. --- ...owImportClausesToMergeWithTypes.errors.txt | 4 ++-- .../reference/callOverloads3.errors.txt | 8 ++++---- .../reference/callOverloads4.errors.txt | 8 ++++---- .../reference/callOverloads5.errors.txt | 8 ++++---- .../constructorOverloads7.errors.txt | 8 ++++---- .../baselines/reference/intrinsics.errors.txt | 4 ++-- ...eNongenericInstantiationAttempt.errors.txt | 4 ++-- ...serAmbiguityWithBinaryOperator4.errors.txt | 8 ++++---- .../reference/typeAssertions.errors.txt | 8 ++++---- .../typeGuardFunctionErrors.errors.txt | 20 +++++++++---------- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/baselines/reference/allowImportClausesToMergeWithTypes.errors.txt b/tests/baselines/reference/allowImportClausesToMergeWithTypes.errors.txt index 684921ae12..8c4f995531 100644 --- a/tests/baselines/reference/allowImportClausesToMergeWithTypes.errors.txt +++ b/tests/baselines/reference/allowImportClausesToMergeWithTypes.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/index.ts(4,1): error TS2693: 'zzz' only refers to a type, but is being used as a value here. -tests/cases/compiler/index.ts(9,10): error TS2304: Cannot find name 'originalZZZ'. +tests/cases/compiler/index.ts(9,10): error TS2749: 'originalZZZ' refers to a value, but is being used as a type here. ==== tests/cases/compiler/b.ts (0 errors) ==== @@ -31,4 +31,4 @@ tests/cases/compiler/index.ts(9,10): error TS2304: Cannot find name 'originalZZZ const y: originalZZZ = x; ~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'originalZZZ'. \ No newline at end of file +!!! error TS2749: 'originalZZZ' refers to a value, but is being used as a type here. \ No newline at end of file diff --git a/tests/baselines/reference/callOverloads3.errors.txt b/tests/baselines/reference/callOverloads3.errors.txt index 9b14a6791a..7a38d132cb 100644 --- a/tests/baselines/reference/callOverloads3.errors.txt +++ b/tests/baselines/reference/callOverloads3.errors.txt @@ -1,8 +1,8 @@ tests/cases/compiler/callOverloads3.ts(1,10): error TS2300: Duplicate identifier 'Foo'. -tests/cases/compiler/callOverloads3.ts(1,16): error TS2304: Cannot find name 'Foo'. +tests/cases/compiler/callOverloads3.ts(1,16): error TS2749: 'Foo' refers to a value, but is being used as a type here. tests/cases/compiler/callOverloads3.ts(2,10): error TS2300: Duplicate identifier 'Foo'. tests/cases/compiler/callOverloads3.ts(2,10): error TS2391: Function implementation is missing or not immediately following the declaration. -tests/cases/compiler/callOverloads3.ts(2,24): error TS2304: Cannot find name 'Foo'. +tests/cases/compiler/callOverloads3.ts(2,24): error TS2749: 'Foo' refers to a value, but is being used as a type here. tests/cases/compiler/callOverloads3.ts(3,7): error TS2300: Duplicate identifier 'Foo'. tests/cases/compiler/callOverloads3.ts(11,10): error TS2350: Only a void function can be called with the 'new' keyword. @@ -12,14 +12,14 @@ tests/cases/compiler/callOverloads3.ts(11,10): error TS2350: Only a void functio ~~~ !!! error TS2300: Duplicate identifier 'Foo'. ~~~ -!!! error TS2304: Cannot find name 'Foo'. +!!! error TS2749: 'Foo' refers to a value, but is being used as a type here. function Foo(s:string):Foo; // error ~~~ !!! error TS2300: Duplicate identifier 'Foo'. ~~~ !!! error TS2391: Function implementation is missing or not immediately following the declaration. ~~~ -!!! error TS2304: Cannot find name 'Foo'. +!!! error TS2749: 'Foo' refers to a value, but is being used as a type here. class Foo { // error ~~~ !!! error TS2300: Duplicate identifier 'Foo'. diff --git a/tests/baselines/reference/callOverloads4.errors.txt b/tests/baselines/reference/callOverloads4.errors.txt index 04ac340c99..dcecd65666 100644 --- a/tests/baselines/reference/callOverloads4.errors.txt +++ b/tests/baselines/reference/callOverloads4.errors.txt @@ -1,8 +1,8 @@ tests/cases/compiler/callOverloads4.ts(1,10): error TS2300: Duplicate identifier 'Foo'. -tests/cases/compiler/callOverloads4.ts(1,16): error TS2304: Cannot find name 'Foo'. +tests/cases/compiler/callOverloads4.ts(1,16): error TS2749: 'Foo' refers to a value, but is being used as a type here. tests/cases/compiler/callOverloads4.ts(2,10): error TS2300: Duplicate identifier 'Foo'. tests/cases/compiler/callOverloads4.ts(2,10): error TS2391: Function implementation is missing or not immediately following the declaration. -tests/cases/compiler/callOverloads4.ts(2,24): error TS2304: Cannot find name 'Foo'. +tests/cases/compiler/callOverloads4.ts(2,24): error TS2749: 'Foo' refers to a value, but is being used as a type here. tests/cases/compiler/callOverloads4.ts(3,7): error TS2300: Duplicate identifier 'Foo'. tests/cases/compiler/callOverloads4.ts(11,10): error TS2350: Only a void function can be called with the 'new' keyword. @@ -12,14 +12,14 @@ tests/cases/compiler/callOverloads4.ts(11,10): error TS2350: Only a void functio ~~~ !!! error TS2300: Duplicate identifier 'Foo'. ~~~ -!!! error TS2304: Cannot find name 'Foo'. +!!! error TS2749: 'Foo' refers to a value, but is being used as a type here. function Foo(s:string):Foo; // error ~~~ !!! error TS2300: Duplicate identifier 'Foo'. ~~~ !!! error TS2391: Function implementation is missing or not immediately following the declaration. ~~~ -!!! error TS2304: Cannot find name 'Foo'. +!!! error TS2749: 'Foo' refers to a value, but is being used as a type here. class Foo { // error ~~~ !!! error TS2300: Duplicate identifier 'Foo'. diff --git a/tests/baselines/reference/callOverloads5.errors.txt b/tests/baselines/reference/callOverloads5.errors.txt index e521a9a907..e9ebdc8a52 100644 --- a/tests/baselines/reference/callOverloads5.errors.txt +++ b/tests/baselines/reference/callOverloads5.errors.txt @@ -1,8 +1,8 @@ tests/cases/compiler/callOverloads5.ts(1,10): error TS2300: Duplicate identifier 'Foo'. -tests/cases/compiler/callOverloads5.ts(1,16): error TS2304: Cannot find name 'Foo'. +tests/cases/compiler/callOverloads5.ts(1,16): error TS2749: 'Foo' refers to a value, but is being used as a type here. tests/cases/compiler/callOverloads5.ts(2,10): error TS2300: Duplicate identifier 'Foo'. tests/cases/compiler/callOverloads5.ts(2,10): error TS2391: Function implementation is missing or not immediately following the declaration. -tests/cases/compiler/callOverloads5.ts(2,24): error TS2304: Cannot find name 'Foo'. +tests/cases/compiler/callOverloads5.ts(2,24): error TS2749: 'Foo' refers to a value, but is being used as a type here. tests/cases/compiler/callOverloads5.ts(3,7): error TS2300: Duplicate identifier 'Foo'. tests/cases/compiler/callOverloads5.ts(13,10): error TS2350: Only a void function can be called with the 'new' keyword. @@ -12,14 +12,14 @@ tests/cases/compiler/callOverloads5.ts(13,10): error TS2350: Only a void functio ~~~ !!! error TS2300: Duplicate identifier 'Foo'. ~~~ -!!! error TS2304: Cannot find name 'Foo'. +!!! error TS2749: 'Foo' refers to a value, but is being used as a type here. function Foo(s:string):Foo; // error ~~~ !!! error TS2300: Duplicate identifier 'Foo'. ~~~ !!! error TS2391: Function implementation is missing or not immediately following the declaration. ~~~ -!!! error TS2304: Cannot find name 'Foo'. +!!! error TS2749: 'Foo' refers to a value, but is being used as a type here. class Foo { // error ~~~ !!! error TS2300: Duplicate identifier 'Foo'. diff --git a/tests/baselines/reference/constructorOverloads7.errors.txt b/tests/baselines/reference/constructorOverloads7.errors.txt index c915b8f975..81aeaaf24f 100644 --- a/tests/baselines/reference/constructorOverloads7.errors.txt +++ b/tests/baselines/reference/constructorOverloads7.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/constructorOverloads7.ts(1,15): error TS2300: Duplicate identifier 'Point'. -tests/cases/compiler/constructorOverloads7.ts(7,35): error TS2304: Cannot find name 'Point'. -tests/cases/compiler/constructorOverloads7.ts(8,14): error TS2304: Cannot find name 'Point'. +tests/cases/compiler/constructorOverloads7.ts(7,35): error TS2749: 'Point' refers to a value, but is being used as a type here. +tests/cases/compiler/constructorOverloads7.ts(8,14): error TS2749: 'Point' refers to a value, but is being used as a type here. tests/cases/compiler/constructorOverloads7.ts(15,10): error TS2300: Duplicate identifier 'Point'. tests/cases/compiler/constructorOverloads7.ts(22,18): error TS2384: Overload signatures must all be ambient or non-ambient. @@ -16,10 +16,10 @@ tests/cases/compiler/constructorOverloads7.ts(22,18): error TS2384: Overload sig add(dx: number, dy: number): Point; ~~~~~ -!!! error TS2304: Cannot find name 'Point'. +!!! error TS2749: 'Point' refers to a value, but is being used as a type here. origin: Point; ~~~~~ -!!! error TS2304: Cannot find name 'Point'. +!!! error TS2749: 'Point' refers to a value, but is being used as a type here. } diff --git a/tests/baselines/reference/intrinsics.errors.txt b/tests/baselines/reference/intrinsics.errors.txt index 5692f05790..13d61dacbc 100644 --- a/tests/baselines/reference/intrinsics.errors.txt +++ b/tests/baselines/reference/intrinsics.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/intrinsics.ts(1,21): error TS2304: Cannot find name 'hasOwnProperty'. +tests/cases/compiler/intrinsics.ts(1,21): error TS2749: 'hasOwnProperty' refers to a value, but is being used as a type here. tests/cases/compiler/intrinsics.ts(1,21): error TS4025: Exported variable 'hasOwnProperty' has or is using private name 'hasOwnProperty'. tests/cases/compiler/intrinsics.ts(10,1): error TS2304: Cannot find name '__proto__'. @@ -6,7 +6,7 @@ tests/cases/compiler/intrinsics.ts(10,1): error TS2304: Cannot find name '__prot ==== tests/cases/compiler/intrinsics.ts (3 errors) ==== var hasOwnProperty: hasOwnProperty; // Error ~~~~~~~~~~~~~~ -!!! error TS2304: Cannot find name 'hasOwnProperty'. +!!! error TS2749: 'hasOwnProperty' refers to a value, but is being used as a type here. ~~~~~~~~~~~~~~ !!! error TS4025: Exported variable 'hasOwnProperty' has or is using private name 'hasOwnProperty'. diff --git a/tests/baselines/reference/jsdocTypeNongenericInstantiationAttempt.errors.txt b/tests/baselines/reference/jsdocTypeNongenericInstantiationAttempt.errors.txt index 941e4386f9..b3298f137f 100644 --- a/tests/baselines/reference/jsdocTypeNongenericInstantiationAttempt.errors.txt +++ b/tests/baselines/reference/jsdocTypeNongenericInstantiationAttempt.errors.txt @@ -5,7 +5,7 @@ tests/cases/compiler/index4.js(2,19): error TS2315: Type 'Function' is not gener tests/cases/compiler/index5.js(2,19): error TS2315: Type 'String' is not generic. tests/cases/compiler/index6.js(2,19): error TS2315: Type 'Number' is not generic. tests/cases/compiler/index7.js(2,19): error TS2315: Type 'Object' is not generic. -tests/cases/compiler/index8.js(4,12): error TS2304: Cannot find name 'fn'. +tests/cases/compiler/index8.js(4,12): error TS2749: 'fn' refers to a value, but is being used as a type here. tests/cases/compiler/index8.js(4,15): error TS2304: Cannot find name 'T'. @@ -90,7 +90,7 @@ tests/cases/compiler/index8.js(4,15): error TS2304: Cannot find name 'T'. /** * @param {fn} somebody ~~ -!!! error TS2304: Cannot find name 'fn'. +!!! error TS2749: 'fn' refers to a value, but is being used as a type here. ~ !!! error TS2304: Cannot find name 'T'. */ diff --git a/tests/baselines/reference/parserAmbiguityWithBinaryOperator4.errors.txt b/tests/baselines/reference/parserAmbiguityWithBinaryOperator4.errors.txt index 41147305ce..a94b60e5f9 100644 --- a/tests/baselines/reference/parserAmbiguityWithBinaryOperator4.errors.txt +++ b/tests/baselines/reference/parserAmbiguityWithBinaryOperator4.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,9): error TS2347: Untyped function calls may not accept type arguments. -tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,11): error TS2304: Cannot find name 'b'. -tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,14): error TS2304: Cannot find name 'b'. +tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,11): error TS2749: 'b' refers to a value, but is being used as a type here. +tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,14): error TS2749: 'b' refers to a value, but is being used as a type here. ==== tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts (3 errors) ==== @@ -10,7 +10,7 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOpe ~~~~~~~~~~~~~~ !!! error TS2347: Untyped function calls may not accept type arguments. ~ -!!! error TS2304: Cannot find name 'b'. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. ~ -!!! error TS2304: Cannot find name 'b'. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. } \ No newline at end of file diff --git a/tests/baselines/reference/typeAssertions.errors.txt b/tests/baselines/reference/typeAssertions.errors.txt index 27de59a764..ef9a23b8d8 100644 --- a/tests/baselines/reference/typeAssertions.errors.txt +++ b/tests/baselines/reference/typeAssertions.errors.txt @@ -7,7 +7,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(37,13): err Property 'q' is missing in type 'SomeDerived' but required in type 'SomeOther'. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(38,13): error TS2352: Conversion of type 'SomeBase' to type 'SomeOther' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Property 'q' is missing in type 'SomeBase' but required in type 'SomeOther'. -tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,5): error TS2304: Cannot find name 'numOrStr'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,5): error TS2749: 'numOrStr' refers to a value, but is being used as a type here. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,14): error TS1005: '>' expected. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,14): error TS2304: Cannot find name 'is'. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,17): error TS1005: ')' expected. @@ -15,7 +15,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,17): err tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,48): error TS1005: ';' expected. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(45,2): error TS2322: Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,32): error TS2304: Cannot find name 'numOrStr'. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,32): error TS2749: 'numOrStr' refers to a value, but is being used as a type here. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,41): error TS1005: ')' expected. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,41): error TS2304: Cannot find name 'is'. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,44): error TS1005: ';' expected. @@ -86,7 +86,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,50): err var str: string; if((numOrStr === undefined)) { // Error ~~~~~~~~ -!!! error TS2304: Cannot find name 'numOrStr'. +!!! error TS2749: 'numOrStr' refers to a value, but is being used as a type here. ~~ !!! error TS1005: '>' expected. ~~ @@ -105,7 +105,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,50): err if((numOrStr === undefined) as numOrStr is string) { // Error ~~~~~~~~ -!!! error TS2304: Cannot find name 'numOrStr'. +!!! error TS2749: 'numOrStr' refers to a value, but is being used as a type here. ~~ !!! error TS1005: ')' expected. ~~ diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt index a6ea9961c5..6f24585a85 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(1,7): error TS2300: Duplicate identifier 'A'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(14,5): error TS2322: Type '""' is not assignable to type 'boolean'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,55): error TS2304: Cannot find name 'x'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,55): error TS2749: 'x' refers to a value, but is being used as a type here. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,57): error TS1144: '{' or ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,60): error TS1005: ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,62): error TS1005: ';' expected. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(21,33): error TS2304: Cannot find name 'x'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(21,33): error TS2749: 'x' refers to a value, but is being used as a type here. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(25,33): error TS1225: Cannot find parameter 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(29,10): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,5): error TS1131: Property or signature expected. @@ -28,14 +28,14 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(84,1): Type predicate 'p2 is A' is not assignable to 'p1 is A'. Parameter 'p2' is not in the same position as parameter 'p1'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(90,1): error TS2322: Type '(p1: any, p2: any, p3: any) => p1 is A' is not assignable to type '(p1: any, p2: any) => p1 is A'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,9): error TS2304: Cannot find name 'b'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,9): error TS2749: 'b' refers to a value, but is being used as a type here. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,11): error TS1005: ',' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,14): error TS1005: ',' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,14): error TS2300: Duplicate identifier 'A'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,16): error TS2304: Cannot find name 'b'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,16): error TS2749: 'b' refers to a value, but is being used as a type here. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,18): error TS1005: ',' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,21): error TS1005: ',' expected. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,20): error TS2304: Cannot find name 'b'. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,20): error TS2749: 'b' refers to a value, but is being used as a type here. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,22): error TS1144: '{' or ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,25): error TS1005: ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,27): error TS1005: ';' expected. @@ -91,7 +91,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { ~ -!!! error TS2304: Cannot find name 'x'. +!!! error TS2749: 'x' refers to a value, but is being used as a type here. ~~ !!! error TS1144: '{' or ';' expected. ~ @@ -103,7 +103,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 function hasMissingIsKeyword(): x { ~ -!!! error TS2304: Cannot find name 'x'. +!!! error TS2749: 'x' refers to a value, but is being used as a type here. return true; } @@ -222,7 +222,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 // Type predicates in non-return type positions var b1: b is A; ~ -!!! error TS2304: Cannot find name 'b'. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. ~~ !!! error TS1005: ',' expected. ~ @@ -231,14 +231,14 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 !!! error TS2300: Duplicate identifier 'A'. function b2(a: b is A) {}; ~ -!!! error TS2304: Cannot find name 'b'. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. ~~ !!! error TS1005: ',' expected. ~ !!! error TS1005: ',' expected. function b3(): A | b is A { ~ -!!! error TS2304: Cannot find name 'b'. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. ~~ !!! error TS1144: '{' or ';' expected. ~ From c358b0b4a547866b1fd8fba15dcb8ff31b812ea1 Mon Sep 17 00:00:00 2001 From: Titian Cernicova-Dragomir Date: Thu, 14 Feb 2019 07:23:11 +0200 Subject: [PATCH 04/14] Fixed tslint error. --- 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 a1248d536a..0dce8cf8ec 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1518,7 +1518,7 @@ namespace ts { !checkAndReportErrorForExtendingInterface(errorLocation) && !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) && !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) && - !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) && + !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) && !checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) { let suggestion: Symbol | undefined; if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) { From b57956673e95884023e4bfe6ab308837b3e300c9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 14 Feb 2019 14:42:55 -0800 Subject: [PATCH 05/14] Move TypeFlags.PropapatingFlags to ObjectFlags to free up 3 flags --- src/compiler/checker.ts | 143 +++++++++++++++++++------------------- src/compiler/types.ts | 105 ++++++++++++++++------------ src/compiler/utilities.ts | 2 +- 3 files changed, 133 insertions(+), 117 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9021a50ef8..f76505ad4a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -390,10 +390,10 @@ namespace ts { const wildcardType = createIntrinsicType(TypeFlags.Any, "any"); const errorType = createIntrinsicType(TypeFlags.Any, "error"); const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); - const undefinedType = createIntrinsicType(TypeFlags.Undefined, "undefined"); - const undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(TypeFlags.Undefined | TypeFlags.ContainsWideningType, "undefined"); - const nullType = createIntrinsicType(TypeFlags.Null, "null"); - const nullWideningType = strictNullChecks ? nullType : createIntrinsicType(TypeFlags.Null | TypeFlags.ContainsWideningType, "null"); + const undefinedType = createNullableType(TypeFlags.Undefined, "undefined", 0); + const undefinedWideningType = strictNullChecks ? undefinedType : createNullableType(TypeFlags.Undefined, "undefined", ObjectFlags.ContainsWideningType); + const nullType = createNullableType(TypeFlags.Null, "null", 0); + const nullWideningType = strictNullChecks ? nullType : createNullableType(TypeFlags.Null, "null", ObjectFlags.ContainsWideningType); const stringType = createIntrinsicType(TypeFlags.String, "string"); const numberType = createIntrinsicType(TypeFlags.Number, "number"); const bigintType = createIntrinsicType(TypeFlags.BigInt, "bigint"); @@ -439,7 +439,7 @@ namespace ts { const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes. - anyFunctionType.flags |= TypeFlags.ContainsAnyFunctionType; + anyFunctionType.objectFlags |= ObjectFlags.ContainsAnyFunctionType; const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -2741,6 +2741,12 @@ namespace ts { return type; } + function createNullableType(kind: TypeFlags, intrinsicName: string, objectFlags: ObjectFlags): NullableType { + const type = createIntrinsicType(kind, intrinsicName); + type.objectFlags = objectFlags; + return type; + } + function createBooleanType(trueFalseTypes: ReadonlyArray): IntrinsicType & UnionType { const type = getUnionType(trueFalseTypes); type.flags |= TypeFlags.Boolean; @@ -5128,7 +5134,7 @@ namespace ts { definedInConstructor = true; } } - const sourceTypes = some(constructorTypes, t => !!(t.flags & ~(TypeFlags.Nullable | TypeFlags.ContainsWideningType))) ? constructorTypes : types; // TODO: GH#18217 + const sourceTypes = some(constructorTypes, t => !!(t.flags & ~TypeFlags.Nullable)) ? constructorTypes : types; // TODO: GH#18217 type = getUnionType(sourceTypes!, UnionReduction.Subtype); } const widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor)); @@ -5293,7 +5299,7 @@ namespace ts { function getTypeFromObjectBindingPattern(pattern: ObjectBindingPattern, includePatternInType: boolean, reportErrors: boolean): Type { const members = createSymbolTable(); let stringIndexInfo: IndexInfo | undefined; - let objectFlags = ObjectFlags.ObjectLiteral; + let objectFlags = ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral; forEach(pattern.elements, e => { const name = e.propertyName || e.name; if (e.dotDotDotToken) { @@ -5315,7 +5321,6 @@ namespace ts { members.set(symbol.escapedName, symbol); }); const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, undefined); - result.flags |= TypeFlags.ContainsObjectLiteral; result.objectFlags |= objectFlags; if (includePatternInType) { result.pattern = pattern; @@ -8540,14 +8545,14 @@ namespace ts { // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type // of an object literal or the anyFunctionType. This is because there are operations in the type checker // that care about the presence of such types at arbitrary depth in a containing type. - function getPropagatingFlagsOfTypes(types: ReadonlyArray, excludeKinds: TypeFlags): TypeFlags { - let result: TypeFlags = 0; + function getPropagatingFlagsOfTypes(types: ReadonlyArray, excludeKinds: TypeFlags): ObjectFlags { + let result: ObjectFlags = 0; for (const type of types) { if (!(type.flags & excludeKinds)) { - result |= type.flags; + result |= getObjectFlags(type); } } - return result & TypeFlags.PropagatingFlags; + return result & ObjectFlags.PropagatingFlags; } function createTypeReference(target: GenericType, typeArguments: ReadonlyArray | undefined): TypeReference { @@ -8556,7 +8561,7 @@ namespace ts { if (!type) { type = createObjectType(ObjectFlags.Reference, target.symbol); target.instantiations.set(id, type); - type.flags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0; + type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0; type.target = target; type.typeArguments = typeArguments; } @@ -9235,10 +9240,11 @@ namespace ts { // intersections of unit types into 'never' upon construction, but deferring the reduction makes it // easier to reason about their origin. if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(type))) { - includes |= flags & ~TypeFlags.ConstructionFlags; - if (type === wildcardType) includes |= TypeFlags.Wildcard; + includes |= flags & TypeFlags.IncludesMask; + if (flags & TypeFlags.StructuredOrInstantiable) includes |= TypeFlags.IncludesStructuredOrInstantiable; + if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; if (!strictNullChecks && flags & TypeFlags.Nullable) { - if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeFlags.NonWideningType; + if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) includes |= TypeFlags.IncludesNonWideningType; } else { const len = typeSet.length; @@ -9349,7 +9355,7 @@ namespace ts { const includes = addTypesToUnion(typeSet, 0, types); if (unionReduction !== UnionReduction.None) { if (includes & TypeFlags.AnyOrUnknown) { - return includes & TypeFlags.Any ? includes & TypeFlags.Wildcard ? wildcardType : anyType : unknownType; + return includes & TypeFlags.Any ? includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : unknownType; } switch (unionReduction) { case UnionReduction.Literal: @@ -9358,18 +9364,18 @@ namespace ts { } break; case UnionReduction.Subtype: - if (!removeSubtypes(typeSet, !(includes & TypeFlags.StructuredOrInstantiable))) { + if (!removeSubtypes(typeSet, !(includes & TypeFlags.IncludesStructuredOrInstantiable))) { return errorType; } break; } if (typeSet.length === 0) { - return includes & TypeFlags.Null ? includes & TypeFlags.NonWideningType ? nullType : nullWideningType : - includes & TypeFlags.Undefined ? includes & TypeFlags.NonWideningType ? undefinedType : undefinedWideningType : + return includes & TypeFlags.Null ? includes & TypeFlags.IncludesNonWideningType ? nullType : nullWideningType : + includes & TypeFlags.Undefined ? includes & TypeFlags.IncludesNonWideningType ? undefinedType : undefinedWideningType : neverType; } } - return getUnionTypeFromSortedList(typeSet, !(includes & TypeFlags.NotPrimitiveUnion), aliasSymbol, aliasTypeArguments); + return getUnionTypeFromSortedList(typeSet, includes & TypeFlags.NotPrimitiveUnion ? 0 : ObjectFlags.PrimitiveUnion, aliasSymbol, aliasTypeArguments); } function getUnionTypePredicate(signatures: ReadonlyArray): TypePredicate | undefined { @@ -9409,7 +9415,7 @@ namespace ts { } // This function assumes the constituent type list is sorted and deduplicated. - function getUnionTypeFromSortedList(types: Type[], primitiveTypesOnly: boolean, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray): Type { + function getUnionTypeFromSortedList(types: Type[], objectFlags: ObjectFlags, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray): Type { if (types.length === 0) { return neverType; } @@ -9419,11 +9425,10 @@ namespace ts { const id = getTypeListId(types); let type = unionTypes.get(id); if (!type) { - const propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable); - type = createType(TypeFlags.Union | propagatedFlags); + type = createType(TypeFlags.Union); unionTypes.set(id, type); + type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable); type.types = types; - type.primitiveTypesOnly = primitiveTypesOnly; /* Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type. For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol. @@ -9452,15 +9457,15 @@ namespace ts { return addTypesToIntersection(typeSet, includes, (type).types); } if (isEmptyAnonymousObjectType(type)) { - if (!(includes & TypeFlags.EmptyObject)) { - includes |= TypeFlags.EmptyObject; + if (!(includes & TypeFlags.IncludesEmptyObject)) { + includes |= TypeFlags.IncludesEmptyObject; typeSet.push(type); } } else { - includes |= flags & ~TypeFlags.ConstructionFlags; + includes |= flags & TypeFlags.IncludesMask; if (flags & TypeFlags.AnyOrUnknown) { - if (type === wildcardType) includes |= TypeFlags.Wildcard; + if (type === wildcardType) includes |= TypeFlags.IncludesWildcard; } else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { typeSet.push(type); @@ -9518,7 +9523,7 @@ namespace ts { // other unions and return true. Otherwise, do nothing and return false. function intersectUnionsOfPrimitiveTypes(types: Type[]) { let unionTypes: UnionType[] | undefined; - const index = findIndex(types, t => !!(t.flags & TypeFlags.Union) && (t).primitiveTypesOnly); + const index = findIndex(types, t => !!(getObjectFlags(t) & ObjectFlags.PrimitiveUnion)); if (index < 0) { return false; } @@ -9527,7 +9532,7 @@ namespace ts { // the unionTypes array. while (i < types.length) { const t = types[i]; - if (t.flags & TypeFlags.Union && (t).primitiveTypesOnly) { + if (getObjectFlags(t) & ObjectFlags.PrimitiveUnion) { (unionTypes || (unionTypes = [types[index]])).push(t); orderedRemoveItemAt(types, i); } @@ -9554,7 +9559,7 @@ namespace ts { } } // Finally replace the first union with the result - types[index] = getUnionTypeFromSortedList(result, /*primitiveTypesOnly*/ true); + types[index] = getUnionTypeFromSortedList(result, ObjectFlags.PrimitiveUnion); return true; } @@ -9575,7 +9580,7 @@ namespace ts { return neverType; } if (includes & TypeFlags.Any) { - return includes & TypeFlags.Wildcard ? wildcardType : anyType; + return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType; } if (!strictNullChecks && includes & TypeFlags.Nullable) { return includes & TypeFlags.Undefined ? undefinedType : nullType; @@ -9586,7 +9591,7 @@ namespace ts { includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) { removeRedundantPrimitiveTypes(typeSet, includes); } - if (includes & TypeFlags.EmptyObject && includes & TypeFlags.Object) { + if (includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.Object) { orderedRemoveItemAt(typeSet, findIndex(typeSet, isEmptyAnonymousObjectType)); } if (typeSet.length === 0) { @@ -9612,9 +9617,9 @@ namespace ts { const id = getTypeListId(typeSet); let type = intersectionTypes.get(id); if (!type) { - const propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable); - type = createType(TypeFlags.Intersection | propagatedFlags); + type = createType(TypeFlags.Intersection); intersectionTypes.set(id, type); + type.objectFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ TypeFlags.Nullable); type.types = typeSet; type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`. type.aliasTypeArguments = aliasTypeArguments; @@ -10273,7 +10278,7 @@ namespace ts { * this function should be called in a left folding style, with left = previous result of getSpreadType * and right = the new element to be spread. */ - function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, typeFlags: TypeFlags, objectFlags: ObjectFlags, readonly: boolean): Type { + function getSpreadType(left: Type, right: Type, symbol: Symbol | undefined, objectFlags: ObjectFlags, readonly: boolean): Type { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } @@ -10287,10 +10292,10 @@ namespace ts { return left; } if (left.flags & TypeFlags.Union) { - return mapType(left, t => getSpreadType(t, right, symbol, typeFlags, objectFlags, readonly)); + return mapType(left, t => getSpreadType(t, right, symbol, objectFlags, readonly)); } if (right.flags & TypeFlags.Union) { - return mapType(right, t => getSpreadType(left, t, symbol, typeFlags, objectFlags, readonly)); + return mapType(right, t => getSpreadType(left, t, symbol, objectFlags, readonly)); } if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) { return left; @@ -10307,7 +10312,7 @@ namespace ts { const types = (left).types; const lastLeft = types[types.length - 1]; if (isNonGenericObjectType(lastLeft) && isNonGenericObjectType(right)) { - return getIntersectionType(concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, typeFlags, objectFlags, readonly)])); + return getIntersectionType(concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, objectFlags, readonly)])); } } return getIntersectionType([left, right]); @@ -10367,8 +10372,7 @@ namespace ts { emptyArray, getIndexInfoWithReadonly(stringIndexInfo, readonly), getIndexInfoWithReadonly(numberIndexInfo, readonly)); - spread.flags |= TypeFlags.ContainsObjectLiteral | typeFlags; - spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsSpread | objectFlags; + spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral | ObjectFlags.ContainsSpread | objectFlags; return spread; } @@ -13853,7 +13857,7 @@ namespace ts { resolved.stringIndexInfo, resolved.numberIndexInfo); regularNew.flags = resolved.flags; - regularNew.objectFlags |= ObjectFlags.ObjectLiteral | (getObjectFlags(resolved) & ObjectFlags.JSLiteral); + regularNew.objectFlags |= resolved.objectFlags & ~ObjectFlags.FreshLiteral; (type).regularType = regularNew; return regularNew; } @@ -13944,7 +13948,7 @@ namespace ts { } function getWidenedTypeWithContext(type: Type, context: WideningContext | undefined): Type { - if (type.flags & TypeFlags.RequiresWidening) { + if (getObjectFlags(type) & ObjectFlags.RequiresWidening) { if (type.flags & TypeFlags.Nullable) { return anyType; } @@ -13982,7 +13986,7 @@ namespace ts { */ function reportWideningErrorsInType(type: Type): boolean { let errorReported = false; - if (type.flags & TypeFlags.ContainsWideningType) { + if (getObjectFlags(type) & ObjectFlags.ContainsWideningType) { if (type.flags & TypeFlags.Union) { if (some((type).types, isEmptyObjectType)) { errorReported = true; @@ -14005,7 +14009,7 @@ namespace ts { if (isObjectLiteralType(type)) { for (const p of getPropertiesOfObjectType(type)) { const t = getTypeOfSymbol(p); - if (t.flags & TypeFlags.ContainsWideningType) { + if (getObjectFlags(t) & ObjectFlags.ContainsWideningType) { if (!reportWideningErrorsInType(t)) { error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), typeToString(getWidenedType(t))); } @@ -14080,7 +14084,7 @@ namespace ts { } function reportErrorsFromWidening(declaration: Declaration, type: Type) { - if (produceDiagnostics && noImplicitAny && type.flags & TypeFlags.ContainsWideningType) { + if (produceDiagnostics && noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType) { // Report implicit any error within type if possible, otherwise report error on declaration if (!reportWideningErrorsInType(type)) { reportImplicitAny(declaration, type); @@ -14225,7 +14229,7 @@ namespace ts { // If any property contains context sensitive functions that have been skipped, the source type // is incomplete and we can't infer a meaningful input type. for (const prop of properties) { - if (getTypeOfSymbol(prop).flags & TypeFlags.ContainsAnyFunctionType) { + if (getObjectFlags(getTypeOfSymbol(prop)) & ObjectFlags.ContainsAnyFunctionType) { return undefined; } } @@ -14383,7 +14387,7 @@ namespace ts { // not contain anyFunctionType when we come back to this argument for its second round // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard // when constructing types from type parameters that had no inference candidates). - if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) { + if (getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType || source === silentNeverType || (priority & InferencePriority.ReturnType && (source === autoType || source === autoArrayType))) { return; } const inference = getInferenceInfoForType(target); @@ -14686,7 +14690,7 @@ namespace ts { const sourceLen = sourceSignatures.length; const targetLen = targetSignatures.length; const len = sourceLen < targetLen ? sourceLen : targetLen; - const skipParameters = !!(source.flags & TypeFlags.ContainsAnyFunctionType); + const skipParameters = !!(getObjectFlags(source) & ObjectFlags.ContainsAnyFunctionType); for (let i = 0; i < len; i++) { inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]), skipParameters); } @@ -15444,7 +15448,7 @@ namespace ts { if (type.flags & TypeFlags.Union) { const types = (type).types; const filtered = filter(types, f); - return filtered === types ? type : getUnionTypeFromSortedList(filtered, (type).primitiveTypesOnly); + return filtered === types ? type : getUnionTypeFromSortedList(filtered, (type).objectFlags); } return f(type) ? type : neverType; } @@ -18350,7 +18354,7 @@ namespace ts { let propertiesTable: SymbolTable; let propertiesArray: Symbol[] = []; let spread: Type = emptyObjectType; - let propagatedFlags: TypeFlags = 0; + let propagatedFlags: ObjectFlags = 0; const contextualType = getApparentTypeOfContextualType(node); const contextualTypeHasPattern = contextualType && contextualType.pattern && @@ -18360,7 +18364,7 @@ namespace ts { const isInJavascript = isInJSFile(node) && !isInJsonFile(node); const enumTag = getJSDocEnumTag(node); const isJSObjectLiteral = !contextualType && isInJavascript && !enumTag; - let typeFlags: TypeFlags = 0; + let objectFlags: ObjectFlags = 0; let patternWithComputedProperties = false; let hasComputedStringProperty = false; let hasComputedNumberProperty = false; @@ -18388,7 +18392,7 @@ namespace ts { checkTypeAssignableTo(type, getTypeFromTypeNode(enumTag.typeExpression), memberDecl); } } - typeFlags |= type.flags; + objectFlags |= getObjectFlags(type); const nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined; const prop = nameType ? createSymbol(SymbolFlags.Property | member.flags, getPropertyNameFromType(nameType), checkFlags | CheckFlags.Late) : @@ -18436,19 +18440,19 @@ namespace ts { checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign); } if (propertiesArray.length > 0) { - spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext); + spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags | ObjectFlags.FreshLiteral, inConstContext); propertiesArray = []; propertiesTable = createSymbolTable(); hasComputedStringProperty = false; hasComputedNumberProperty = false; - typeFlags = 0; + objectFlags = 0; } const type = checkExpression(memberDecl.expression); if (!isValidSpreadType(type)) { error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return errorType; } - spread = getSpreadType(spread, type, node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext); + spread = getSpreadType(spread, type, node.symbol, propagatedFlags | ObjectFlags.FreshLiteral, inConstContext); offset = i + 1; continue; } @@ -18498,7 +18502,7 @@ namespace ts { if (spread !== emptyObjectType) { if (propertiesArray.length > 0) { - spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags, ObjectFlags.FreshLiteral, inConstContext); + spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags | ObjectFlags.FreshLiteral, inConstContext); } return spread; } @@ -18509,8 +18513,7 @@ namespace ts { const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.String) : undefined; const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.Number) : undefined; const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); - result.flags |= TypeFlags.ContainsObjectLiteral | typeFlags & TypeFlags.PropagatingFlags; - result.objectFlags |= ObjectFlags.ObjectLiteral | freshObjectLiteralFlag; + result.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral | freshObjectLiteralFlag | objectFlags & ObjectFlags.PropagatingFlags; if (isJSObjectLiteral) { result.objectFlags |= ObjectFlags.JSLiteral; } @@ -18520,7 +18523,7 @@ namespace ts { if (inDestructuringPattern) { result.pattern = node; } - propagatedFlags |= result.flags & TypeFlags.PropagatingFlags; + propagatedFlags |= result.objectFlags & ObjectFlags.PropagatingFlags; return result; } } @@ -18611,7 +18614,6 @@ namespace ts { let hasSpreadAnyType = false; let typeToIntersect: Type | undefined; let explicitlySpecifyChildrenAttribute = false; - let typeFlags: TypeFlags = 0; let objectFlags: ObjectFlags = ObjectFlags.JsxAttributes; const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement)); @@ -18619,7 +18621,7 @@ namespace ts { const member = attributeDecl.symbol; if (isJsxAttribute(attributeDecl)) { const exprType = checkJsxAttribute(attributeDecl, checkMode); - typeFlags |= exprType.flags & TypeFlags.PropagatingFlags; + objectFlags |= getObjectFlags(exprType) & ObjectFlags.PropagatingFlags; const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.escapedName); attributeSymbol.declarations = member.declarations; @@ -18637,7 +18639,7 @@ namespace ts { else { Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute); if (attributesTable.size > 0) { - spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, typeFlags, objectFlags, /*readonly*/ false); + spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false); attributesTable = createSymbolTable(); } const exprType = checkExpressionCached(attributeDecl.expression, checkMode); @@ -18645,7 +18647,7 @@ namespace ts { hasSpreadAnyType = true; } if (isValidSpreadType(exprType)) { - spread = getSpreadType(spread, exprType, attributes.symbol, typeFlags, objectFlags, /*readonly*/ false); + spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false); } else { typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType; @@ -18655,7 +18657,7 @@ namespace ts { if (!hasSpreadAnyType) { if (attributesTable.size > 0) { - spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, typeFlags, objectFlags, /*readonly*/ false); + spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false); } } @@ -18687,7 +18689,7 @@ namespace ts { const childPropMap = createSymbolTable(); childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol); spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), - attributes.symbol, typeFlags, objectFlags, /*readonly*/ false); + attributes.symbol, objectFlags, /*readonly*/ false); } } @@ -18708,8 +18710,7 @@ namespace ts { function createJsxAttributesType() { objectFlags |= freshObjectLiteralFlag; const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); - result.flags |= TypeFlags.ContainsObjectLiteral | typeFlags; - result.objectFlags |= ObjectFlags.ObjectLiteral | objectFlags; + result.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral | objectFlags; return result; } } @@ -21374,7 +21375,7 @@ namespace ts { const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); anonymousSymbol.type = defaultContainingObject; - synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*typeFLags*/ 0, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject; + synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject; } else { synthType.syntheticType = type; @@ -22052,7 +22053,7 @@ namespace ts { const returnType = getReturnTypeFromBody(node, checkMode); const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined); - returnOnlyType.flags |= TypeFlags.ContainsAnyFunctionType; + returnOnlyType.objectFlags |= ObjectFlags.ContainsAnyFunctionType; return links.contextFreeType = returnOnlyType; } return anyFunctionType; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a524ce13cb..c0ae3b99c4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3817,39 +3817,33 @@ namespace ts { } export const enum TypeFlags { - Any = 1 << 0, - Unknown = 1 << 1, - String = 1 << 2, - Number = 1 << 3, - Boolean = 1 << 4, - Enum = 1 << 5, - BigInt = 1 << 6, - StringLiteral = 1 << 7, - NumberLiteral = 1 << 8, - BooleanLiteral = 1 << 9, - EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union - BigIntLiteral = 1 << 11, - ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6 - UniqueESSymbol = 1 << 13, // unique symbol - Void = 1 << 14, - Undefined = 1 << 15, - Null = 1 << 16, - Never = 1 << 17, // Never type - TypeParameter = 1 << 18, // Type parameter - Object = 1 << 19, // Object type - Union = 1 << 20, // Union (T | U) - Intersection = 1 << 21, // Intersection (T & U) - Index = 1 << 22, // keyof T - IndexedAccess = 1 << 23, // T[K] - Conditional = 1 << 24, // T extends U ? X : Y - Substitution = 1 << 25, // Type parameter substitution - NonPrimitive = 1 << 26, // intrinsic object type - /* @internal */ - ContainsWideningType = 1 << 27, // Type is or contains undefined or null widening type - /* @internal */ - ContainsObjectLiteral = 1 << 28, // Type is or contains object literal type - /* @internal */ - ContainsAnyFunctionType = 1 << 29, // Type is or contains the anyFunctionType + Any = 1 << 0, + Unknown = 1 << 1, + String = 1 << 2, + Number = 1 << 3, + Boolean = 1 << 4, + Enum = 1 << 5, + BigInt = 1 << 6, + StringLiteral = 1 << 7, + NumberLiteral = 1 << 8, + BooleanLiteral = 1 << 9, + EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union + BigIntLiteral = 1 << 11, + ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6 + UniqueESSymbol = 1 << 13, // unique symbol + Void = 1 << 14, + Undefined = 1 << 15, + Null = 1 << 16, + Never = 1 << 17, // Never type + TypeParameter = 1 << 18, // Type parameter + Object = 1 << 19, // Object type + Union = 1 << 20, // Union (T | U) + Intersection = 1 << 21, // Intersection (T & U) + Index = 1 << 22, // keyof T + IndexedAccess = 1 << 23, // T[K] + Conditional = 1 << 24, // T extends U ? X : Y + Substitution = 1 << 25, // Type parameter substitution + NonPrimitive = 1 << 26, // intrinsic object type /* @internal */ AnyOrUnknown = Any | Unknown, @@ -3883,29 +3877,29 @@ namespace ts { InstantiablePrimitive = Index, Instantiable = InstantiableNonPrimitive | InstantiablePrimitive, StructuredOrInstantiable = StructuredType | Instantiable, - + /* @internal */ + ObjectFlagsType = Nullable | Object | Union | Intersection, // 'Narrowable' types are types where narrowing actually narrows. // This *should* be every type other than null, undefined, void, and never Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, NotUnionOrUnit = Any | Unknown | ESSymbol | Object | NonPrimitive, /* @internal */ NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable, + // The following flags are aggregated during union and intersection type construction /* @internal */ - RequiresWidening = ContainsWideningType | ContainsObjectLiteral, - /* @internal */ - PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType, + IncludesMask = Any | Unknown | Primitive | Never | Object | Union, // The following flags are used for different purposes during union and intersection type construction /* @internal */ - NonWideningType = ContainsWideningType, + IncludesStructuredOrInstantiable = TypeParameter, /* @internal */ - Wildcard = ContainsObjectLiteral, + IncludesNonWideningType = Intersection, /* @internal */ - EmptyObject = ContainsAnyFunctionType, + IncludesWildcard = Index, /* @internal */ - ConstructionFlags = NonWideningType | Wildcard | EmptyObject, + IncludesEmptyObject = IndexedAccess, // The following flag is used for different purposes by maybeTypeOfKind /* @internal */ - GenericMappedType = ContainsWideningType + GenericMappedType = Never, } export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; @@ -3932,6 +3926,12 @@ namespace ts { // Intrinsic types (TypeFlags.Intrinsic) export interface IntrinsicType extends Type { intrinsicName: string; // Name of intrinsic type + objectFlags: ObjectFlags; + } + + /* @internal */ + export interface NullableType extends IntrinsicType { + objectFlags: ObjectFlags; } /* @internal */ @@ -3991,9 +3991,24 @@ namespace ts { MarkerType = 1 << 13, // Marker type used for variance probing JSLiteral = 1 << 14, // Object type declared in JS - disables errors on read/write of nonexisting members FreshLiteral = 1 << 15, // Fresh object literal - ClassOrInterface = Class | Interface + /* @internal */ + PrimitiveUnion = 1 << 16, // Union of only primitive types + /* @internal */ + ContainsWideningType = 1 << 17, // Type is or contains undefined or null widening type + /* @internal */ + ContainsObjectLiteral = 1 << 18, // Type is or contains object literal type + /* @internal */ + ContainsAnyFunctionType = 1 << 19, // Type is or contains the anyFunctionType + ClassOrInterface = Class | Interface, + /* @internal */ + RequiresWidening = ContainsWideningType | ContainsObjectLiteral, + /* @internal */ + PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType } + /* @internal */ + export type ObjectFlagsType = NullableType | ObjectType | UnionType | IntersectionType; + // Object types (TypeFlags.ObjectType) export interface ObjectType extends Type { objectFlags: ObjectFlags; @@ -4074,6 +4089,8 @@ namespace ts { export interface UnionOrIntersectionType extends Type { types: Type[]; // Constituent types /* @internal */ + objectFlags: ObjectFlags; + /* @internal */ propertyCache: SymbolTable; // Cache of resolved properties /* @internal */ resolvedProperties: Symbol[]; @@ -4088,8 +4105,6 @@ namespace ts { } export interface UnionType extends UnionOrIntersectionType { - /* @internal */ - primitiveTypesOnly: boolean; } export interface IntersectionType extends UnionOrIntersectionType { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 29d2ebfa59..aa2ebe3d60 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4515,7 +4515,7 @@ namespace ts { } export function getObjectFlags(type: Type): ObjectFlags { - return type.flags & TypeFlags.Object ? (type).objectFlags : 0; + return type.flags & TypeFlags.ObjectFlagsType ? (type).objectFlags : 0; } export function typeHasCallOrConstructSignatures(type: Type, checker: TypeChecker) { From ed8c81a5638c7d745cb8541137ad6990da045467 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 14 Feb 2019 14:56:22 -0800 Subject: [PATCH 06/14] Update lodash dependency (#29903) For security reasons --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4f4f7db571..f891f99be5 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "gulp-sourcemaps": "latest", "istanbul": "latest", "jake": "latest", - "lodash": "4.17.10", + "lodash": "^4.17.11", "merge2": "latest", "minimist": "latest", "mkdirp": "latest", From 3e745e65cda9a0879741fe1ef6afcf395fced8e6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 14 Feb 2019 15:22:19 -0800 Subject: [PATCH 07/14] Simplify flags propagation logic --- src/compiler/checker.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f76505ad4a..579e27a848 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18354,7 +18354,6 @@ namespace ts { let propertiesTable: SymbolTable; let propertiesArray: Symbol[] = []; let spread: Type = emptyObjectType; - let propagatedFlags: ObjectFlags = 0; const contextualType = getApparentTypeOfContextualType(node); const contextualTypeHasPattern = contextualType && contextualType.pattern && @@ -18364,7 +18363,7 @@ namespace ts { const isInJavascript = isInJSFile(node) && !isInJsonFile(node); const enumTag = getJSDocEnumTag(node); const isJSObjectLiteral = !contextualType && isInJavascript && !enumTag; - let objectFlags: ObjectFlags = 0; + let objectFlags: ObjectFlags = freshObjectLiteralFlag; let patternWithComputedProperties = false; let hasComputedStringProperty = false; let hasComputedNumberProperty = false; @@ -18392,7 +18391,7 @@ namespace ts { checkTypeAssignableTo(type, getTypeFromTypeNode(enumTag.typeExpression), memberDecl); } } - objectFlags |= getObjectFlags(type); + objectFlags |= getObjectFlags(type) & ObjectFlags.PropagatingFlags; const nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined; const prop = nameType ? createSymbol(SymbolFlags.Property | member.flags, getPropertyNameFromType(nameType), checkFlags | CheckFlags.Late) : @@ -18440,19 +18439,18 @@ namespace ts { checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign); } if (propertiesArray.length > 0) { - spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags | ObjectFlags.FreshLiteral, inConstContext); + spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext); propertiesArray = []; propertiesTable = createSymbolTable(); hasComputedStringProperty = false; hasComputedNumberProperty = false; - objectFlags = 0; } const type = checkExpression(memberDecl.expression); if (!isValidSpreadType(type)) { error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return errorType; } - spread = getSpreadType(spread, type, node.symbol, propagatedFlags | ObjectFlags.FreshLiteral, inConstContext); + spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext); offset = i + 1; continue; } @@ -18502,7 +18500,7 @@ namespace ts { if (spread !== emptyObjectType) { if (propertiesArray.length > 0) { - spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags | ObjectFlags.FreshLiteral, inConstContext); + spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext); } return spread; } @@ -18513,7 +18511,7 @@ namespace ts { const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.String) : undefined; const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.Number) : undefined; const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); - result.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral | freshObjectLiteralFlag | objectFlags & ObjectFlags.PropagatingFlags; + result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral; if (isJSObjectLiteral) { result.objectFlags |= ObjectFlags.JSLiteral; } @@ -18523,7 +18521,6 @@ namespace ts { if (inDestructuringPattern) { result.pattern = node; } - propagatedFlags |= result.objectFlags & ObjectFlags.PropagatingFlags; return result; } } @@ -18710,7 +18707,7 @@ namespace ts { function createJsxAttributesType() { objectFlags |= freshObjectLiteralFlag; const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); - result.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral | objectFlags; + result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectLiteral; return result; } } From 8f52f21f0d13be285e7d2a9f8d7de1604c619d54 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 15 Feb 2019 06:22:17 -0800 Subject: [PATCH 08/14] Fix broken check in getUnionType (check was always true) --- 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 579e27a848..718c7e541b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9359,7 +9359,7 @@ namespace ts { } switch (unionReduction) { case UnionReduction.Literal: - if (includes & TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.BooleanLiteral) { + if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol)) { removeRedundantLiteralTypes(typeSet, includes); } break; From 7983813be0cfc1500f2f4c83793c784a3433e173 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 15 Feb 2019 09:03:15 -0800 Subject: [PATCH 09/14] Use sha256 to hash file contents --- src/compiler/sys.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 35e9a9ec35..33283c9380 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -632,7 +632,7 @@ namespace ts { getModifiedTime, setModifiedTime, deleteFile, - createHash: _crypto ? createMD5HashUsingNativeCrypto : generateDjb2Hash, + createHash: _crypto ? createSHA256Hash : generateDjb2Hash, createSHA256Hash: _crypto ? createSHA256Hash : undefined, getMemoryUsage() { if (global.gc) { @@ -1125,12 +1125,6 @@ namespace ts { } } - function createMD5HashUsingNativeCrypto(data: string): string { - const hash = _crypto!.createHash("md5"); - hash.update(data); - return hash.digest("hex"); - } - function createSHA256Hash(data: string): string { const hash = _crypto!.createHash("sha256"); hash.update(data); From 540aeb6073dec5e1669f84468c7e76310895249a Mon Sep 17 00:00:00 2001 From: Tom J Date: Sun, 17 Feb 2019 18:28:32 +0000 Subject: [PATCH 10/14] update docs: dated build cmd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hopefully I didn't miss something obvious. Running `gulp build` as suggested causes the following: ``` $ gulp build [18:26:11] Using gulpfile ~/git/TypeScript/Gulpfile.js [18:26:11] Task never defined: build [18:26:11] To list available tasks, try running: gulp --tasks ``` ``` $ gulp --tasks gulp --tasks [18:21:26] Tasks for ~/git/TypeScript/Gulpfile.js [18:21:26] ├── lib Builds the library targets ... ... [18:21:27] ├─┬ default Runs 'local' [18:21:27] │ └─┬ [18:21:27] │ └─┬ local [18:21:27] │ └─┬ [18:21:27] │ ├── buildFoldStart [18:21:27] │ ├─┬ [18:21:27] │ │ ├── generateLibs [18:21:27] │ │ └─┬ [18:21:27] │ │ ├── buildScripts [18:21:27] │ │ └── generateDiagnostics [18:21:27] │ ├─┬ [18:21:27] │ │ ├── localize [18:21:27] │ │ ├── buildTsc [18:21:27] │ │ ├── buildServer [18:21:27] │ │ ├─┬ [18:21:27] │ │ │ ├── flattenServicesConfig [18:21:27] │ │ │ ├── buildTypescriptServicesOut [18:21:27] │ │ │ ├── createTypescriptServicesJs [18:21:27] │ │ │ ├── createTypescriptServicesDts [18:21:27] │ │ │ ├── createTypescriptJs [18:21:27] │ │ │ ├── createTypescriptDts [18:21:27] │ │ │ └── createTypescriptStandaloneDts [18:21:27] │ │ └─┬ [18:21:27] │ │ ├── flattenTsServerProject [18:21:27] │ │ ├── buildServerLibraryOut [18:21:27] │ │ ├── createServerLibraryJs [18:21:27] │ │ └── createServerLibraryDts [18:21:27] │ └── buildFoldEnd [18:21:27] └── help Prints the top-level tasks. ``` The default task seems to do something useful: ``` $ gulp [18:21:49] Using gulpfile ~/git/TypeScript/Gulpfile.js [18:21:49] Starting 'default'... [18:21:49] Starting 'local'... [18:21:49] Starting 'buildFoldStart'... [18:21:49] Finished 'buildFoldStart' after 726 μs [18:21:49] Starting 'generateLibs'... [18:21:49] Starting 'buildScripts'... [18:21:49] Finished 'generateLibs' after 207 ms [18:21:49] Finished 'buildScripts' after 686 ms [18:21:49] Starting 'generateDiagnostics'... [18:21:49] Finished 'generateDiagnostics' after 700 μs [18:21:49] Starting 'localize'... [18:21:49] Starting 'buildTsc'... [18:21:49] Starting 'buildServer'... [18:21:49] > /usr/bin/node scripts/generateLocalizedDiagnosticMessages.js src/loc/lcl built/local src/compiler/diagnosticMessages.generated.json [18:21:49] Starting 'flattenServicesConfig'... [18:21:49] Starting 'flattenTsServerProject'... [18:21:49] Finished 'flattenServicesConfig' after 54 ms [18:21:49] Starting 'buildTypescriptServicesOut'... [18:21:49] Finished 'flattenTsServerProject' after 54 ms [18:21:49] Starting 'buildServerLibraryOut'... [18:21:53] Finished 'localize' after 3.38 s [18:23:17] Finished 'buildTsc' after 1.45 min [18:23:17] Finished 'buildServer' after 1.45 min [18:23:17] Finished 'buildTypescriptServicesOut' after 1.45 min [18:23:17] Starting 'createTypescriptServicesJs'... [18:23:17] Finished 'buildServerLibraryOut' after 1.45 min [18:23:17] Starting 'createServerLibraryJs'... [18:23:17] Finished 'createServerLibraryJs' after 635 ms [18:23:17] Starting 'createServerLibraryDts'... [18:23:18] Finished 'createTypescriptServicesJs' after 642 ms [18:23:18] Starting 'createTypescriptServicesDts'... [18:23:18] Finished 'createTypescriptServicesDts' after 20 ms [18:23:18] Starting 'createTypescriptJs'... [18:23:18] Finished 'createServerLibraryDts' after 30 ms [18:23:18] Finished 'createTypescriptJs' after 260 ms [18:23:18] Starting 'createTypescriptDts'... [18:23:18] Finished 'createTypescriptDts' after 4.47 ms [18:23:18] Starting 'createTypescriptStandaloneDts'... [18:23:18] Finished 'createTypescriptStandaloneDts' after 5.59 ms [18:23:18] Starting 'buildFoldEnd'... [18:23:18] Finished 'buildFoldEnd' after 350 μs [18:23:18] Finished 'local' after 1.48 min [18:23:18] Finished 'default' after 1.48 min ``` I'm I'm guessing wrongly, please reject & correct the docs to whatever the right way to run builds is. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 980f84a380..31cfb85808 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,7 +55,7 @@ The TypeScript repository is relatively large. To save some time, you might want ### Using local builds -Run `gulp build` to build a version of the compiler/language service that reflects changes you've made. You can then run `node /built/local/tsc.js` in place of `tsc` in your project. For example, to run `tsc --watch` from within the root of the repository on a file called `test.ts`, you can run `node ./built/local/tsc.js --watch test.ts`. +Run `gulp` to build a version of the compiler/language service that reflects changes you've made. You can then run `node /built/local/tsc.js` in place of `tsc` in your project. For example, to run `tsc --watch` from within the root of the repository on a file called `test.ts`, you can run `node ./built/local/tsc.js --watch test.ts`. ## Contributing bug fixes From 059fd2d42eef48cafafe5569b4313aace312e190 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 18 Feb 2019 07:25:08 -1000 Subject: [PATCH 11/14] Never overwrite resolved type of symbol --- src/compiler/checker.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3bd089aff6..47ed48b5dd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5425,7 +5425,16 @@ namespace ts { function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type { const links = getSymbolLinks(symbol); - return links.type || (links.type = getTypeOfVariableOrParameterOrPropertyWorker(symbol)); + if (!links.type) { + const type = getTypeOfVariableOrParameterOrPropertyWorker(symbol); + // For a contextually typed parameter it is possible that a type has already + // been assigned (in assignTypeToParameterAndFixTypeParameters), and we want + // to preserve this type. + if (!links.type) { + links.type = type; + } + } + return links.type; } function getTypeOfVariableOrParameterOrPropertyWorker(symbol: Symbol) { @@ -5469,7 +5478,7 @@ namespace ts { if (symbol.flags & SymbolFlags.ValueModule) { return getTypeOfFuncClassEnumModule(symbol); } - return errorType; + return reportCircularityError(symbol); } let type: Type | undefined; if (isInJSFile(declaration) && @@ -5528,7 +5537,7 @@ namespace ts { if (symbol.flags & SymbolFlags.ValueModule) { return getTypeOfFuncClassEnumModule(symbol); } - type = reportCircularityError(symbol); + return reportCircularityError(symbol); } return type; } From ecfd40891ff3394834df89594a2fd8a563d51343 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 18 Feb 2019 07:25:22 -1000 Subject: [PATCH 12/14] Accept new baselines --- .../reference/jsFileClassSelfReferencedProperty.types | 4 ++-- tests/baselines/reference/parserES5ForOfStatement18.types | 2 +- tests/baselines/reference/parserES5ForOfStatement19.types | 2 +- tests/baselines/reference/parserForOfStatement18.types | 2 +- tests/baselines/reference/parserForOfStatement19.types | 2 +- tests/baselines/reference/recur1.types | 2 +- .../recursiveExportAssignmentAndFindAliasedType7.types | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/jsFileClassSelfReferencedProperty.types b/tests/baselines/reference/jsFileClassSelfReferencedProperty.types index d5c2fe39c9..204eee67c9 100644 --- a/tests/baselines/reference/jsFileClassSelfReferencedProperty.types +++ b/tests/baselines/reference/jsFileClassSelfReferencedProperty.types @@ -4,11 +4,11 @@ export class StackOverflowTest { constructor () { this.testStackOverflow = this.testStackOverflow.bind(this) ->this.testStackOverflow = this.testStackOverflow.bind(this) : error +>this.testStackOverflow = this.testStackOverflow.bind(this) : any >this.testStackOverflow : any >this : this >testStackOverflow : any ->this.testStackOverflow.bind(this) : error +>this.testStackOverflow.bind(this) : any >this.testStackOverflow.bind : any >this.testStackOverflow : any >this : this diff --git a/tests/baselines/reference/parserES5ForOfStatement18.types b/tests/baselines/reference/parserES5ForOfStatement18.types index 156ed2c68f..f9544e39a3 100644 --- a/tests/baselines/reference/parserES5ForOfStatement18.types +++ b/tests/baselines/reference/parserES5ForOfStatement18.types @@ -1,5 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/Statements/parserES5ForOfStatement18.ts === for (var of of of) { } >of : any ->of : error +>of : any diff --git a/tests/baselines/reference/parserES5ForOfStatement19.types b/tests/baselines/reference/parserES5ForOfStatement19.types index cc3a1ed01b..13abc7ae75 100644 --- a/tests/baselines/reference/parserES5ForOfStatement19.types +++ b/tests/baselines/reference/parserES5ForOfStatement19.types @@ -1,5 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/Statements/parserES5ForOfStatement19.ts === for (var of in of) { } >of : any ->of : error +>of : any diff --git a/tests/baselines/reference/parserForOfStatement18.types b/tests/baselines/reference/parserForOfStatement18.types index 3fe8de5b6c..8e3b52ac87 100644 --- a/tests/baselines/reference/parserForOfStatement18.types +++ b/tests/baselines/reference/parserForOfStatement18.types @@ -1,5 +1,5 @@ === tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement18.ts === for (var of of of) { } >of : any ->of : error +>of : any diff --git a/tests/baselines/reference/parserForOfStatement19.types b/tests/baselines/reference/parserForOfStatement19.types index 04104a9667..6fcc5e8f79 100644 --- a/tests/baselines/reference/parserForOfStatement19.types +++ b/tests/baselines/reference/parserForOfStatement19.types @@ -1,5 +1,5 @@ === tests/cases/conformance/parser/ecmascript6/Iterators/parserForOfStatement19.ts === for (var of in of) { } >of : any ->of : error +>of : any diff --git a/tests/baselines/reference/recur1.types b/tests/baselines/reference/recur1.types index d4893d27b8..83b4dbd598 100644 --- a/tests/baselines/reference/recur1.types +++ b/tests/baselines/reference/recur1.types @@ -15,7 +15,7 @@ salt.pepper = function() {} var cobalt = new cobalt.pitch(); >cobalt : any ->new cobalt.pitch() : error +>new cobalt.pitch() : any >cobalt.pitch : any >cobalt : any >pitch : any diff --git a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.types b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.types index 939e7beb79..a5675737c2 100644 --- a/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.types +++ b/tests/baselines/reference/recursiveExportAssignmentAndFindAliasedType7.types @@ -14,7 +14,7 @@ import self = require("recursiveExportAssignmentAndFindAliasedType7_moduleD"); var selfVar = self; >selfVar : any ->self : error +>self : any export = selfVar; >selfVar : any From eafff75c2a334b6bf6f84530c581086e821722fa Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 19 Feb 2019 11:39:16 -0800 Subject: [PATCH 13/14] Remove diagnostic dependent output in `structuredTypeRelatedTo` (#29817) * Unify variance probing error exceptions between interfaces/aliases * Consistiently return false on variance probe failure * Remove strictFunctionTypes early bail from getVariances so independent type parameters are correctly measured * Fix lint, remove now-redundant change from covariant void check function --- src/compiler/checker.ts | 86 +++--- ...eckInfiniteExpansionTermination.errors.txt | 32 +++ .../complexRecursiveCollections.types | 2 +- .../reference/conditionalTypes1.errors.txt | 8 + .../mappedTypeRelationships.errors.txt | 4 + .../reference/mappedTypes5.errors.txt | 2 + .../recursiveTypeComparison.errors.txt | 27 ++ .../strictFunctionTypesErrors.errors.txt | 82 ++---- ...unionTypeErrorMessageTypeRefs01.errors.txt | 18 +- ...derIndexSignatureRelationsAlign.errors.txt | 82 ++++++ ...ndZeroOrderIndexSignatureRelationsAlign.js | 146 +++++++++++ ...oOrderIndexSignatureRelationsAlign.symbols | 246 ++++++++++++++++++ ...eroOrderIndexSignatureRelationsAlign.types | 168 ++++++++++++ ...erIndexSignatureRelationsAlign2.errors.txt | 79 ++++++ ...dZeroOrderIndexSignatureRelationsAlign2.js | 146 +++++++++++ ...OrderIndexSignatureRelationsAlign2.symbols | 244 +++++++++++++++++ ...roOrderIndexSignatureRelationsAlign2.types | 165 ++++++++++++ ...ndZeroOrderIndexSignatureRelationsAlign.ts | 67 +++++ ...dZeroOrderIndexSignatureRelationsAlign2.ts | 67 +++++ 19 files changed, 1564 insertions(+), 107 deletions(-) create mode 100644 tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt create mode 100644 tests/baselines/reference/recursiveTypeComparison.errors.txt create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.errors.txt create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.symbols create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.types create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.errors.txt create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.symbols create mode 100644 tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.types create mode 100644 tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts create mode 100644 tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3bd089aff6..1cce639a78 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12586,6 +12586,7 @@ namespace ts { let result: Ternary; let originalErrorInfo: DiagnosticMessageChain | undefined; + let varianceCheckFailed = false; const saveErrorInfo = errorInfo; // We limit alias variance probing to only object and conditional types since their alias behavior @@ -12595,11 +12596,10 @@ namespace ts { source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol && !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) { const variances = getAliasVariances(source.aliasSymbol); - if (result = typeArgumentsRelatedTo(source.aliasTypeArguments, target.aliasTypeArguments, variances, reportErrors)) { - return result; + const varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances); + if (varianceResult !== undefined) { + return varianceResult; } - originalErrorInfo = errorInfo; - errorInfo = saveErrorInfo; } if (target.flags & TypeFlags.TypeParameter) { @@ -12764,31 +12764,9 @@ namespace ts { // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. const variances = getVariances((source).target); - if (result = typeArgumentsRelatedTo((source).typeArguments, (target).typeArguments, variances, reportErrors)) { - return result; - } - // The type arguments did not relate appropriately, but it may be because we have no variance - // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type - // arguments). It might also be the case that the target type has a 'void' type argument for - // a covariant type parameter that is only used in return positions within the generic type - // (in which case any type argument is permitted on the source side). In those cases we proceed - // with a structural comparison. Otherwise, we know for certain the instantiations aren't - // related and we can return here. - if (variances !== emptyArray && !hasCovariantVoidArgument(target, variances)) { - // In some cases generic types that are covariant in regular type checking mode become - // invariant in --strictFunctionTypes mode because one or more type parameters are used in - // both co- and contravariant positions. In order to make it easier to diagnose *why* such - // types are invariant, if any of the type parameters are invariant we reset the reported - // errors and instead force a structural comparison (which will include elaborations that - // reveal the reason). - if (!(reportErrors && some(variances, v => v === Variance.Invariant))) { - return Ternary.False; - } - // We remember the original error information so we can restore it in case the structural - // 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; + const varianceResult = relateVariances((source).typeArguments, (target).typeArguments, variances); + if (varianceResult !== undefined) { + return varianceResult; } } else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) { @@ -12815,16 +12793,48 @@ namespace ts { } } } - if (result) { - if (!originalErrorInfo) { - errorInfo = saveErrorInfo; - return result; - } - errorInfo = originalErrorInfo; + if (varianceCheckFailed && result) { + errorInfo = originalErrorInfo || errorInfo || saveErrorInfo; // Use variance error (there is no structural one) and return false + } + else if (result) { + return result; } } } return Ternary.False; + + function relateVariances(sourceTypeArguments: ReadonlyArray | undefined, targetTypeArguments: ReadonlyArray | undefined, variances: Variance[]) { + if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors)) { + return result; + } + const isCovariantVoid = targetTypeArguments && hasCovariantVoidArgument(targetTypeArguments, variances); + varianceCheckFailed = !isCovariantVoid; + // The type arguments did not relate appropriately, but it may be because we have no variance + // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type + // arguments). It might also be the case that the target type has a 'void' type argument for + // a covariant type parameter that is only used in return positions within the generic type + // (in which case any type argument is permitted on the source side). In those cases we proceed + // with a structural comparison. Otherwise, we know for certain the instantiations aren't + // related and we can return here. + if (variances !== emptyArray && !isCovariantVoid) { + // In some cases generic types that are covariant in regular type checking mode become + // invariant in --strictFunctionTypes mode because one or more type parameters are used in + // both co- and contravariant positions. In order to make it easier to diagnose *why* such + // types are invariant, if any of the type parameters are invariant we reset the reported + // errors and instead force a structural comparison (which will include elaborations that + // reveal the reason). + // We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`, + // we can return `False` early here to skip calculating the structural error message we don't need. + if (varianceCheckFailed && !(reportErrors && some(variances, v => v === Variance.Invariant))) { + return Ternary.False; + } + // We remember the original error information so we can restore it in case the structural + // 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; + } + } } // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is @@ -13333,7 +13343,7 @@ namespace ts { function getVariances(type: GenericType): Variance[] { // Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters) - if (!strictFunctionTypes || type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) { + if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) { return emptyArray; } return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference); @@ -13341,9 +13351,9 @@ namespace ts { // Return true if the given type reference has a 'void' type argument for a covariant type parameter. // See comment at call in recursiveTypeRelatedTo for when this case matters. - function hasCovariantVoidArgument(type: TypeReference, variances: Variance[]): boolean { + function hasCovariantVoidArgument(typeArguments: ReadonlyArray, variances: Variance[]): boolean { for (let i = 0; i < variances.length; i++) { - if (variances[i] === Variance.Covariant && type.typeArguments![i].flags & TypeFlags.Void) { + if (variances[i] === Variance.Covariant && typeArguments[i].flags & TypeFlags.Void) { return true; } } diff --git a/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt b/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt new file mode 100644 index 0000000000..014087ff62 --- /dev/null +++ b/tests/baselines/reference/checkInfiniteExpansionTermination.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/checkInfiniteExpansionTermination.ts(16,1): error TS2322: Type 'ISubject' is not assignable to type 'IObservable'. + Types of property 'n' are incompatible. + Type 'IObservable' is not assignable to type 'IObservable'. + Type 'Bar[]' is not assignable to type 'Foo[]'. + Property 'x' is missing in type 'Bar' but required in type 'Foo'. + + +==== tests/cases/compiler/checkInfiniteExpansionTermination.ts (1 errors) ==== + // Regression test for #1002 + // Before fix this code would cause infinite loop + + interface IObservable { + n: IObservable; // Needed, must be T[] + } + + // Needed + interface ISubject extends IObservable { } + + interface Foo { x } + interface Bar { y } + + var values: IObservable; + var values2: ISubject; + values = values2; + ~~~~~~ +!!! error TS2322: Type 'ISubject' is not assignable to type 'IObservable'. +!!! error TS2322: Types of property 'n' are incompatible. +!!! error TS2322: Type 'IObservable' is not assignable to type 'IObservable'. +!!! error TS2322: Type 'Bar[]' is not assignable to type 'Foo[]'. +!!! error TS2322: Property 'x' is missing in type 'Bar' but required in type 'Foo'. +!!! related TS2728 tests/cases/compiler/checkInfiniteExpansionTermination.ts:11:17: 'x' is declared here. + \ No newline at end of file diff --git a/tests/baselines/reference/complexRecursiveCollections.types b/tests/baselines/reference/complexRecursiveCollections.types index a9fc13e7d1..feaff62048 100644 --- a/tests/baselines/reference/complexRecursiveCollections.types +++ b/tests/baselines/reference/complexRecursiveCollections.types @@ -1137,7 +1137,7 @@ declare module Immutable { >Seq : typeof Seq function isSeq(maybeSeq: any): maybeSeq is Seq.Indexed | Seq.Keyed; ->isSeq : (maybeSeq: any) => maybeSeq is Keyed | Indexed +>isSeq : (maybeSeq: any) => maybeSeq is Indexed | Keyed >maybeSeq : any >Seq : any >Seq : any diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index 62239eca7b..ec35f89161 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -17,8 +17,12 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(103,5): error TS2 tests/cases/conformance/types/conditional/conditionalTypes1.ts(104,5): error TS2322: Type 'Pick' is not assignable to type 'T'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(106,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'never'. + Type 'string | number | symbol' is not assignable to type 'never'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(108,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. @@ -183,11 +187,15 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS ~ !!! error TS2322: Type 'Pick' is not assignable to type 'Pick'. !!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. z = x; z = y; // Error ~ !!! error TS2322: Type 'Pick' is not assignable to type 'Pick'. !!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. } function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index 60a06e000c..3d63765407 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -34,7 +34,9 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(72,5): error TS2322: Type 'Partial' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(78,5): error TS2322: Type 'Partial' is not assignable to type 'Partial'. + Type 'Thing' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(88,5): error TS2322: Type 'Readonly' is not assignable to type 'Readonly'. + Type 'Thing' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(127,5): error TS2322: Type 'Partial' is not assignable to type 'Identity'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(143,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. @@ -197,6 +199,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y = x; // Error ~ !!! error TS2322: Type 'Partial' is not assignable to type 'Partial'. +!!! error TS2322: Type 'Thing' is not assignable to type 'T'. } function f40(x: T, y: Readonly) { @@ -209,6 +212,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y = x; // Error ~ !!! error TS2322: Type 'Readonly' is not assignable to type 'Readonly'. +!!! error TS2322: Type 'Thing' is not assignable to type 'T'. } type Item = { diff --git a/tests/baselines/reference/mappedTypes5.errors.txt b/tests/baselines/reference/mappedTypes5.errors.txt index d0c32cd1dd..21d6f98964 100644 --- a/tests/baselines/reference/mappedTypes5.errors.txt +++ b/tests/baselines/reference/mappedTypes5.errors.txt @@ -1,6 +1,7 @@ tests/cases/conformance/types/mapped/mappedTypes5.ts(6,9): error TS2322: Type 'Partial' is not assignable to type 'Readonly'. tests/cases/conformance/types/mapped/mappedTypes5.ts(8,9): error TS2322: Type 'Partial>' is not assignable to type 'Readonly'. tests/cases/conformance/types/mapped/mappedTypes5.ts(9,9): error TS2322: Type 'Readonly>' is not assignable to type 'Readonly'. + Type 'Partial' is not assignable to type 'T'. ==== tests/cases/conformance/types/mapped/mappedTypes5.ts (3 errors) ==== @@ -19,6 +20,7 @@ tests/cases/conformance/types/mapped/mappedTypes5.ts(9,9): error TS2322: Type 'R let b4: Readonly = rp; // Error ~~ !!! error TS2322: Type 'Readonly>' is not assignable to type 'Readonly'. +!!! error TS2322: Type 'Partial' is not assignable to type 'T'. let c1: Partial> = p; let c2: Partial> = r; let c3: Partial> = pr; diff --git a/tests/baselines/reference/recursiveTypeComparison.errors.txt b/tests/baselines/reference/recursiveTypeComparison.errors.txt new file mode 100644 index 0000000000..f647763b2e --- /dev/null +++ b/tests/baselines/reference/recursiveTypeComparison.errors.txt @@ -0,0 +1,27 @@ +tests/cases/compiler/recursiveTypeComparison.ts(14,5): error TS2322: Type 'Observable<{}>' is not assignable to type 'Property'. + Types of property 'needThisOne' are incompatible. + Type 'Observable<{}>' is not assignable to type 'Observable'. + Type '{}' is not assignable to type 'number'. + + +==== tests/cases/compiler/recursiveTypeComparison.ts (1 errors) ==== + // Before fix this would take an exceeding long time to complete (#1170) + + interface Observable { + // This member can't be of type T, Property, or Observable + needThisOne: Observable; + // Add more to make it slower + expo1: Property; // 0.31 seconds in check + expo2: Property; // 3.11 seconds + expo3: Property; // 82.28 seconds + } + interface Property extends Observable { } + + var p: Observable<{}>; + var stuck: Property = p; + ~~~~~ +!!! error TS2322: Type 'Observable<{}>' is not assignable to type 'Property'. +!!! error TS2322: Types of property 'needThisOne' are incompatible. +!!! error TS2322: Type 'Observable<{}>' is not assignable to type 'Observable'. +!!! error TS2322: Type '{}' is not assignable to type 'number'. + \ No newline at end of file diff --git a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt index 369919850f..3ff04c44fb 100644 --- a/tests/baselines/reference/strictFunctionTypesErrors.errors.txt +++ b/tests/baselines/reference/strictFunctionTypesErrors.errors.txt @@ -17,19 +17,15 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(21,1): error TS2322: Type '(x: tests/cases/compiler/strictFunctionTypesErrors.ts(23,1): error TS2322: Type '(x: string) => Object' is not assignable to type '(x: string) => string'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(33,1): error TS2322: Type 'Func' is not assignable to type 'Func'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(34,1): error TS2322: Type 'Func' is not assignable to type 'Func'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(36,1): error TS2322: Type 'Func' is not assignable to type 'Func'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(37,1): error TS2322: Type 'Func' is not assignable to type 'Func'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(38,1): error TS2322: Type 'Func' is not assignable to type 'Func'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(44,1): error TS2322: Type 'Func' is not assignable to type 'Func'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(46,1): error TS2322: Type 'Func' is not assignable to type 'Func'. @@ -39,37 +35,26 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(57,1): error TS2322: Type 'Fun tests/cases/compiler/strictFunctionTypesErrors.ts(58,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(61,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, Object>'. - Types of parameters 'x' and 'x' are incompatible. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Func' is not assignable to type 'Func'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(62,1): error TS2322: Type 'Func, string>' is not assignable to type 'Func, Object>'. - Types of parameters 'x' and 'x' are incompatible. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(65,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. - Types of parameters 'x' and 'x' are incompatible. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(66,1): error TS2322: Type 'Func, string>' is not assignable to type 'Func, string>'. - Types of parameters 'x' and 'x' are incompatible. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(67,1): error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(74,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(75,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(76,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(79,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(80,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. - Types of parameters 'x' and 'x' are incompatible. - Type 'Object' is not assignable to type 'string'. + Type 'Object' is not assignable to type 'string'. tests/cases/compiler/strictFunctionTypesErrors.ts(83,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. Type 'Func' is not assignable to type 'Func'. tests/cases/compiler/strictFunctionTypesErrors.ts(84,1): error TS2322: Type 'Func>' is not assignable to type 'Func>'. @@ -162,13 +147,11 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c g1 = g3; // Error ~~ !!! error TS2322: Type 'Func' is not assignable to type 'Func'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. g1 = g4; // Error ~~ !!! error TS2322: Type 'Func' is not assignable to type 'Func'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. g2 = g1; // Error ~~ @@ -177,13 +160,11 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c g2 = g3; // Error ~~ !!! error TS2322: Type 'Func' is not assignable to type 'Func'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. g2 = g4; // Error ~~ !!! error TS2322: Type 'Func' is not assignable to type 'Func'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. g3 = g1; // Ok g3 = g2; // Ok @@ -221,29 +202,22 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c h3 = h1; // Error ~~ !!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, Object>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. h3 = h2; // Error ~~ !!! error TS2322: Type 'Func, string>' is not assignable to type 'Func, Object>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. h3 = h4; // Ok h4 = h1; // Error ~~ !!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. h4 = h2; // Error ~~ !!! error TS2322: Type 'Func, string>' is not assignable to type 'Func, string>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Func' is not assignable to type 'Func'. h4 = h3; // Error ~~ !!! error TS2322: Type 'Func, Object>' is not assignable to type 'Func, string>'. @@ -261,25 +235,21 @@ tests/cases/compiler/strictFunctionTypesErrors.ts(155,5): error TS2322: Type '(c i1 = i3; // Error ~~ !!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. i1 = i4; // Error ~~ !!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. i2 = i1; // Ok i2 = i3; // Error ~~ !!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. i2 = i4; // Error ~~ !!! error TS2322: Type 'Func>' is not assignable to type 'Func>'. -!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2322: Type 'Object' is not assignable to type 'string'. +!!! error TS2322: Type 'Object' is not assignable to type 'string'. i3 = i1; // Ok i3 = i2; // Error diff --git a/tests/baselines/reference/unionTypeErrorMessageTypeRefs01.errors.txt b/tests/baselines/reference/unionTypeErrorMessageTypeRefs01.errors.txt index 5fdeab5861..ab661b6fee 100644 --- a/tests/baselines/reference/unionTypeErrorMessageTypeRefs01.errors.txt +++ b/tests/baselines/reference/unionTypeErrorMessageTypeRefs01.errors.txt @@ -9,16 +9,13 @@ tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(27,1): error TS2322: Typ Property 'kwah' is missing in type 'Foo' but required in type 'Kwah'. tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(48,1): error TS2322: Type 'X' is not assignable to type 'X | Y | Z'. Type 'X' is not assignable to type 'X'. - Types of property 'xProp' are incompatible. - Type 'Foo' is not assignable to type 'Bar'. + Type 'Foo' is not assignable to type 'Bar'. tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(49,1): error TS2322: Type 'Y' is not assignable to type 'X | Y | Z'. Type 'Y' is not assignable to type 'Y'. - Types of property 'yProp' are incompatible. - Type 'Foo' is not assignable to type 'Baz'. + Type 'Foo' is not assignable to type 'Baz'. tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(50,1): error TS2322: Type 'Z' is not assignable to type 'X | Y | Z'. Type 'Z' is not assignable to type 'Z'. - Types of property 'zProp' are incompatible. - Type 'Foo' is not assignable to type 'Kwah'. + Type 'Foo' is not assignable to type 'Kwah'. ==== tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts (6 errors) ==== @@ -88,17 +85,14 @@ tests/cases/compiler/unionTypeErrorMessageTypeRefs01.ts(50,1): error TS2322: Typ ~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'X' is not assignable to type 'X | Y | Z'. !!! error TS2322: Type 'X' is not assignable to type 'X'. -!!! error TS2322: Types of property 'xProp' are incompatible. -!!! error TS2322: Type 'Foo' is not assignable to type 'Bar'. +!!! error TS2322: Type 'Foo' is not assignable to type 'Bar'. thingOfTypeAliases = y; ~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'Y' is not assignable to type 'X | Y | Z'. !!! error TS2322: Type 'Y' is not assignable to type 'Y'. -!!! error TS2322: Types of property 'yProp' are incompatible. -!!! error TS2322: Type 'Foo' is not assignable to type 'Baz'. +!!! error TS2322: Type 'Foo' is not assignable to type 'Baz'. thingOfTypeAliases = z; ~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'Z' is not assignable to type 'X | Y | Z'. !!! error TS2322: Type 'Z' is not assignable to type 'Z'. -!!! error TS2322: Types of property 'zProp' are incompatible. -!!! error TS2322: Type 'Foo' is not assignable to type 'Kwah'. \ No newline at end of file +!!! error TS2322: Type 'Foo' is not assignable to type 'Kwah'. \ No newline at end of file diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.errors.txt b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.errors.txt new file mode 100644 index 0000000000..47f97958f0 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.errors.txt @@ -0,0 +1,82 @@ +tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts(63,6): error TS2345: Argument of type 'NeededInfo>' is not assignable to parameter of type 'NeededInfo<{}>'. + Types of property 'ASchema' are incompatible. + Type 'ToA>' is not assignable to type 'ToA<{}>'. + Type '{}' is not assignable to type 'ToB<{ initialize: any; }>'. +tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts(66,38): error TS2344: Type 'NeededInfo>' does not satisfy the constraint 'NeededInfo<{}>'. + + +==== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts (2 errors) ==== + type Either = Left | Right; + + class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } + } + + class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } + } + + class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } + } + + interface Any extends Type {} + + type TypeOf = C["_A"]; + + type ToB = { [k in keyof S]: TypeOf }; + type ToA = { [k in keyof S]: Type }; + + type NeededInfo = { + ASchema: ToA; + }; + + export type MyInfo = NeededInfo>; + + const tmp1: MyInfo = null!; + function tmp2(n: N) {} + tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? + ~~~~ +!!! error TS2345: Argument of type 'NeededInfo>' is not assignable to parameter of type 'NeededInfo<{}>'. +!!! error TS2345: Types of property 'ASchema' are incompatible. +!!! error TS2345: Type 'ToA>' is not assignable to type 'ToA<{}>'. +!!! error TS2345: Type '{}' is not assignable to type 'ToB<{ initialize: any; }>'. +!!! related TS2728 tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts:59:39: 'initialize' is declared here. + + class Server {} + export class MyServer extends Server {} // not assignable error at `MyInfo` + ~~~~~~ +!!! error TS2344: Type 'NeededInfo>' does not satisfy the constraint 'NeededInfo<{}>'. \ No newline at end of file diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js new file mode 100644 index 0000000000..cbac03d7a8 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.js @@ -0,0 +1,146 @@ +//// [varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts] +type Either = Left | Right; + +class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } +} + +class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } +} + +class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; + +type ToB = { [k in keyof S]: TypeOf }; +type ToA = { [k in keyof S]: Type }; + +type NeededInfo = { + ASchema: ToA; +}; + +export type MyInfo = NeededInfo>; + +const tmp1: MyInfo = null!; +function tmp2(n: N) {} +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? + +class Server {} +export class MyServer extends Server {} // not assignable error at `MyInfo` + +//// [varianceProblingAndZeroOrderIndexSignatureRelationsAlign.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; +var Left = /** @class */ (function () { + function Left(value) { + this.value = value; + this._tag = 'Left'; + } + /** The given function is applied if this is a `Right` */ + Left.prototype.map = function (f) { + return this; + }; + Left.prototype.ap = function (fab) { + return null; + }; + return Left; +}()); +var Right = /** @class */ (function () { + function Right(value) { + this.value = value; + this._tag = 'Right'; + } + Right.prototype.map = function (f) { + return new Right(f(this.value)); + }; + Right.prototype.ap = function (fab) { + return null; + }; + return Right; +}()); +var Type = /** @class */ (function () { + function Type( + /** a unique name for this codec */ + name, + /** a custom type guard */ + is, + /** succeeds if a value of type I can be decoded to a value of type A */ + validate, + /** converts a value of type A to a value of type O */ + encode) { + this.name = name; + this.is = is; + this.validate = validate; + this.encode = encode; + } + /** a version of `validate` with a default context */ + Type.prototype.decode = function (i) { return null; }; + return Type; +}()); +var tmp1 = null; +function tmp2(n) { } +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? +var Server = /** @class */ (function () { + function Server() { + } + return Server; +}()); +var MyServer = /** @class */ (function (_super) { + __extends(MyServer, _super); + function MyServer() { + return _super !== null && _super.apply(this, arguments) || this; + } + return MyServer; +}(Server)); // not assignable error at `MyInfo` +exports.MyServer = MyServer; diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.symbols b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.symbols new file mode 100644 index 0000000000..bd97928406 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.symbols @@ -0,0 +1,246 @@ +=== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts === +type Either = Left | Right; +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 14)) +>Left : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 45)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 14)) +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 14, 1)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 14)) + +class Left { +>Left : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 45)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 13)) + + readonly _tag: 'Left' = 'Left' +>_tag : Symbol(Left._tag, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 18)) + + readonly _A!: A +>_A : Symbol(Left._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 3, 34)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 13)) + + readonly _L!: L +>_L : Symbol(Left._L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 4, 19)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) + + constructor(readonly value: L) {} +>value : Symbol(Left.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 6, 16)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) + + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { +>map : Symbol(Left.map, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 6, 37)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 8)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 15)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 13)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 8)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 8, 8)) + + return this as any +>this : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 45)) + } + ap(fab: Either B>): Either { +>ap : Symbol(Left.ap, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 10, 5)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 7)) +>fab : Symbol(fab, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 10)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 26)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 13)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 7)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 2, 11)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 11, 7)) + + return null as any + } +} + +class Right { +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 14, 1)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) + + readonly _tag: 'Right' = 'Right' +>_tag : Symbol(Right._tag, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 19)) + + readonly _A!: A +>_A : Symbol(Right._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 17, 36)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) + + readonly _L!: L +>_L : Symbol(Right._L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 18, 19)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) + + constructor(readonly value: A) {} +>value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 20, 16)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) + + map(f: (a: A) => B): Either { +>map : Symbol(Right.map, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 20, 37)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 8)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 15)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 8)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 8)) + + return new Right(f(this.value)) +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 14, 1)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 21, 11)) +>this.value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 20, 16)) +>this : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 14, 1)) +>value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 20, 16)) + } + ap(fab: Either B>): Either { +>ap : Symbol(Right.ap, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 23, 5)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 7)) +>fab : Symbol(fab, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 10)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 26)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 14)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 7)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 16, 12)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 24, 7)) + + return null as any; + } +} + +class Type { +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 27, 1)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 13)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 20)) + + readonly _A!: A; +>_A : Symbol(Type._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 35)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) + + readonly _O!: O; +>_O : Symbol(Type._O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 30, 18)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 13)) + + readonly _I!: I; +>_I : Symbol(Type._I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 31, 18)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 20)) + + constructor( + /** a unique name for this codec */ + readonly name: string, +>name : Symbol(Type.name, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 33, 14)) + + /** a custom type guard */ + readonly is: (u: unknown) => u is A, +>is : Symbol(Type.is, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 35, 26)) +>u : Symbol(u, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 37, 18)) +>u : Symbol(u, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 37, 18)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) + + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, +>validate : Symbol(Type.validate, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 37, 40)) +>input : Symbol(input, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 39, 24)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 20)) +>context : Symbol(context, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 39, 33)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) + + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O +>encode : Symbol(Type.encode, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 39, 68)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 41, 22)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 13)) + + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +>decode : Symbol(Type.decode, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 42, 6)) +>i : Symbol(i, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 44, 9)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 20)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 0, 0)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 29, 11)) +} + +interface Any extends Type {} +>Any : Symbol(Any, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 45, 1)) +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 27, 1)) + +type TypeOf = C["_A"]; +>TypeOf : Symbol(TypeOf, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 47, 44)) +>C : Symbol(C, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 49, 12)) +>Any : Symbol(Any, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 45, 1)) +>C : Symbol(C, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 49, 12)) + +type ToB = { [k in keyof S]: TypeOf }; +>ToB : Symbol(ToB, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 49, 37)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 29)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 9)) +>TypeOf : Symbol(TypeOf, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 47, 44)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 29)) + +type ToA = { [k in keyof S]: Type }; +>ToA : Symbol(ToA, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 59)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 17)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 9)) +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 27, 1)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 17)) + +type NeededInfo = { +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 45)) +>MyNamespaceSchema : Symbol(MyNamespaceSchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 54, 16)) + + ASchema: ToA; +>ASchema : Symbol(ASchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 54, 43)) +>ToA : Symbol(ToA, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 51, 59)) +>MyNamespaceSchema : Symbol(MyNamespaceSchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 54, 16)) + +}; + +export type MyInfo = NeededInfo>; +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 56, 2)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 45)) +>ToB : Symbol(ToB, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 49, 37)) +>initialize : Symbol(initialize, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 58, 37)) + +const tmp1: MyInfo = null!; +>tmp1 : Symbol(tmp1, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 60, 5)) +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 56, 2)) + +function tmp2(n: N) {} +>tmp2 : Symbol(tmp2, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 60, 27)) +>N : Symbol(N, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 61, 14)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 45)) +>n : Symbol(n, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 61, 36)) +>N : Symbol(N, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 61, 14)) + +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? +>tmp2 : Symbol(tmp2, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 60, 27)) +>tmp1 : Symbol(tmp1, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 60, 5)) + +class Server {} +>Server : Symbol(Server, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 62, 11)) +>X : Symbol(X, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 64, 13)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 52, 45)) + +export class MyServer extends Server {} // not assignable error at `MyInfo` +>MyServer : Symbol(MyServer, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 64, 37)) +>Server : Symbol(Server, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 62, 11)) +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts, 56, 2)) + diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.types b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.types new file mode 100644 index 0000000000..d360372d5a --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.types @@ -0,0 +1,168 @@ +=== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts === +type Either = Left | Right; +>Either : Either + +class Left { +>Left : Left + + readonly _tag: 'Left' = 'Left' +>_tag : "Left" +>'Left' : "Left" + + readonly _A!: A +>_A : A + + readonly _L!: L +>_L : L + + constructor(readonly value: L) {} +>value : L + + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { +>map : (f: (a: A) => B) => Either +>f : (a: A) => B +>a : A + + return this as any +>this as any : any +>this : this + } + ap(fab: Either B>): Either { +>ap : (fab: Either B>) => Either +>fab : Either B> +>a : A + + return null as any +>null as any : any +>null : null + } +} + +class Right { +>Right : Right + + readonly _tag: 'Right' = 'Right' +>_tag : "Right" +>'Right' : "Right" + + readonly _A!: A +>_A : A + + readonly _L!: L +>_L : L + + constructor(readonly value: A) {} +>value : A + + map(f: (a: A) => B): Either { +>map : (f: (a: A) => B) => Either +>f : (a: A) => B +>a : A + + return new Right(f(this.value)) +>new Right(f(this.value)) : Right +>Right : typeof Right +>f(this.value) : B +>f : (a: A) => B +>this.value : A +>this : this +>value : A + } + ap(fab: Either B>): Either { +>ap : (fab: Either B>) => Either +>fab : Either B> +>a : A + + return null as any; +>null as any : any +>null : null + } +} + +class Type { +>Type : Type + + readonly _A!: A; +>_A : A + + readonly _O!: O; +>_O : O + + readonly _I!: I; +>_I : I + + constructor( + /** a unique name for this codec */ + readonly name: string, +>name : string + + /** a custom type guard */ + readonly is: (u: unknown) => u is A, +>is : (u: unknown) => u is A +>u : unknown + + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, +>validate : (input: I, context: {}[]) => Either<{}[], A> +>input : I +>context : {}[] + + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O +>encode : (a: A) => O +>a : A + + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +>decode : (i: I) => Either<{}[], A> +>i : I +>null as any : any +>null : null +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; +>TypeOf : C["_A"] + +type ToB = { [k in keyof S]: TypeOf }; +>ToB : ToB + +type ToA = { [k in keyof S]: Type }; +>ToA : ToA + +type NeededInfo = { +>NeededInfo : NeededInfo + + ASchema: ToA; +>ASchema : ToA + +}; + +export type MyInfo = NeededInfo>; +>MyInfo : NeededInfo> +>initialize : any + +const tmp1: MyInfo = null!; +>tmp1 : NeededInfo> +>null! : never +>null : null + +function tmp2(n: N) {} +>tmp2 : >(n: N) => void +>n : N + +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? +>tmp2(tmp1) : any +>tmp2 : >(n: N) => void +>tmp1 : NeededInfo> + +class Server {} +>Server : Server + +export class MyServer extends Server {} // not assignable error at `MyInfo` +>MyServer : MyServer +>Server : Server>> + diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.errors.txt b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.errors.txt new file mode 100644 index 0000000000..aba1bc1db6 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.errors.txt @@ -0,0 +1,79 @@ +tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts(66,38): error TS2344: Type 'NeededInfo>' does not satisfy the constraint 'NeededInfo<{}>'. + Types of property 'ASchema' are incompatible. + Type 'ToA>' is not assignable to type 'ToA<{}>'. + Type '{}' is not assignable to type 'ToB<{ initialize: any; }>'. + + +==== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts (1 errors) ==== + type Either = Left | Right; + + class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } + } + + class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } + } + + class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } + } + + interface Any extends Type {} + + type TypeOf = C["_A"]; + + type ToB = { [k in keyof S]: TypeOf }; + type ToA = { [k in keyof S]: Type }; + + type NeededInfo = { + ASchema: ToA; + }; + + export type MyInfo = NeededInfo>; + + const tmp1: MyInfo = null!; + function tmp2(n: N) {} + // tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + + class Server {} + export class MyServer extends Server {} // not assignable error at `MyInfo` + ~~~~~~ +!!! error TS2344: Type 'NeededInfo>' does not satisfy the constraint 'NeededInfo<{}>'. +!!! error TS2344: Types of property 'ASchema' are incompatible. +!!! error TS2344: Type 'ToA>' is not assignable to type 'ToA<{}>'. +!!! error TS2344: Type '{}' is not assignable to type 'ToB<{ initialize: any; }>'. +!!! related TS2728 tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts:59:39: 'initialize' is declared here. \ No newline at end of file diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js new file mode 100644 index 0000000000..8a4340ada9 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.js @@ -0,0 +1,146 @@ +//// [varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts] +type Either = Left | Right; + +class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } +} + +class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } +} + +class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; + +type ToB = { [k in keyof S]: TypeOf }; +type ToA = { [k in keyof S]: Type }; + +type NeededInfo = { + ASchema: ToA; +}; + +export type MyInfo = NeededInfo>; + +const tmp1: MyInfo = null!; +function tmp2(n: N) {} +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + +class Server {} +export class MyServer extends Server {} // not assignable error at `MyInfo` + +//// [varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.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; +var Left = /** @class */ (function () { + function Left(value) { + this.value = value; + this._tag = 'Left'; + } + /** The given function is applied if this is a `Right` */ + Left.prototype.map = function (f) { + return this; + }; + Left.prototype.ap = function (fab) { + return null; + }; + return Left; +}()); +var Right = /** @class */ (function () { + function Right(value) { + this.value = value; + this._tag = 'Right'; + } + Right.prototype.map = function (f) { + return new Right(f(this.value)); + }; + Right.prototype.ap = function (fab) { + return null; + }; + return Right; +}()); +var Type = /** @class */ (function () { + function Type( + /** a unique name for this codec */ + name, + /** a custom type guard */ + is, + /** succeeds if a value of type I can be decoded to a value of type A */ + validate, + /** converts a value of type A to a value of type O */ + encode) { + this.name = name; + this.is = is; + this.validate = validate; + this.encode = encode; + } + /** a version of `validate` with a default context */ + Type.prototype.decode = function (i) { return null; }; + return Type; +}()); +var tmp1 = null; +function tmp2(n) { } +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) +var Server = /** @class */ (function () { + function Server() { + } + return Server; +}()); +var MyServer = /** @class */ (function (_super) { + __extends(MyServer, _super); + function MyServer() { + return _super !== null && _super.apply(this, arguments) || this; + } + return MyServer; +}(Server)); // not assignable error at `MyInfo` +exports.MyServer = MyServer; diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.symbols b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.symbols new file mode 100644 index 0000000000..6d8983bd95 --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.symbols @@ -0,0 +1,244 @@ +=== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts === +type Either = Left | Right; +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 14)) +>Left : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 45)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 14)) +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 14, 1)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 14)) + +class Left { +>Left : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 45)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 13)) + + readonly _tag: 'Left' = 'Left' +>_tag : Symbol(Left._tag, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 18)) + + readonly _A!: A +>_A : Symbol(Left._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 3, 34)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 13)) + + readonly _L!: L +>_L : Symbol(Left._L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 4, 19)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) + + constructor(readonly value: L) {} +>value : Symbol(Left.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 6, 16)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) + + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { +>map : Symbol(Left.map, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 6, 37)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 8)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 15)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 13)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 8)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 8, 8)) + + return this as any +>this : Symbol(Left, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 45)) + } + ap(fab: Either B>): Either { +>ap : Symbol(Left.ap, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 10, 5)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 7)) +>fab : Symbol(fab, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 10)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 26)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 13)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 7)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 2, 11)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 11, 7)) + + return null as any + } +} + +class Right { +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 14, 1)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) + + readonly _tag: 'Right' = 'Right' +>_tag : Symbol(Right._tag, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 19)) + + readonly _A!: A +>_A : Symbol(Right._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 17, 36)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) + + readonly _L!: L +>_L : Symbol(Right._L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 18, 19)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) + + constructor(readonly value: A) {} +>value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 20, 16)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) + + map(f: (a: A) => B): Either { +>map : Symbol(Right.map, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 20, 37)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 8)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 11)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 15)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 8)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 8)) + + return new Right(f(this.value)) +>Right : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 14, 1)) +>f : Symbol(f, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 21, 11)) +>this.value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 20, 16)) +>this : Symbol(Right, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 14, 1)) +>value : Symbol(Right.value, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 20, 16)) + } + ap(fab: Either B>): Either { +>ap : Symbol(Right.ap, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 23, 5)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 7)) +>fab : Symbol(fab, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 10)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 26)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 14)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 7)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>L : Symbol(L, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 16, 12)) +>B : Symbol(B, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 24, 7)) + + return null as any; + } +} + +class Type { +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 27, 1)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 13)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 20)) + + readonly _A!: A; +>_A : Symbol(Type._A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 35)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) + + readonly _O!: O; +>_O : Symbol(Type._O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 30, 18)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 13)) + + readonly _I!: I; +>_I : Symbol(Type._I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 31, 18)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 20)) + + constructor( + /** a unique name for this codec */ + readonly name: string, +>name : Symbol(Type.name, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 33, 14)) + + /** a custom type guard */ + readonly is: (u: unknown) => u is A, +>is : Symbol(Type.is, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 35, 26)) +>u : Symbol(u, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 37, 18)) +>u : Symbol(u, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 37, 18)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) + + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, +>validate : Symbol(Type.validate, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 37, 40)) +>input : Symbol(input, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 39, 24)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 20)) +>context : Symbol(context, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 39, 33)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) + + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O +>encode : Symbol(Type.encode, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 39, 68)) +>a : Symbol(a, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 41, 22)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) +>O : Symbol(O, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 13)) + + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +>decode : Symbol(Type.decode, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 42, 6)) +>i : Symbol(i, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 44, 9)) +>I : Symbol(I, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 20)) +>Either : Symbol(Either, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 0, 0)) +>A : Symbol(A, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 29, 11)) +} + +interface Any extends Type {} +>Any : Symbol(Any, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 45, 1)) +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 27, 1)) + +type TypeOf = C["_A"]; +>TypeOf : Symbol(TypeOf, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 47, 44)) +>C : Symbol(C, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 49, 12)) +>Any : Symbol(Any, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 45, 1)) +>C : Symbol(C, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 49, 12)) + +type ToB = { [k in keyof S]: TypeOf }; +>ToB : Symbol(ToB, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 49, 37)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 29)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 9)) +>TypeOf : Symbol(TypeOf, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 47, 44)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 29)) + +type ToA = { [k in keyof S]: Type }; +>ToA : Symbol(ToA, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 59)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 17)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 9)) +>Type : Symbol(Type, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 27, 1)) +>S : Symbol(S, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 9)) +>k : Symbol(k, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 17)) + +type NeededInfo = { +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 45)) +>MyNamespaceSchema : Symbol(MyNamespaceSchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 54, 16)) + + ASchema: ToA; +>ASchema : Symbol(ASchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 54, 43)) +>ToA : Symbol(ToA, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 51, 59)) +>MyNamespaceSchema : Symbol(MyNamespaceSchema, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 54, 16)) + +}; + +export type MyInfo = NeededInfo>; +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 56, 2)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 45)) +>ToB : Symbol(ToB, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 49, 37)) +>initialize : Symbol(initialize, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 58, 37)) + +const tmp1: MyInfo = null!; +>tmp1 : Symbol(tmp1, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 60, 5)) +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 56, 2)) + +function tmp2(n: N) {} +>tmp2 : Symbol(tmp2, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 60, 27)) +>N : Symbol(N, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 14)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 45)) +>n : Symbol(n, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 36)) +>N : Symbol(N, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 14)) + +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + +class Server {} +>Server : Symbol(Server, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 44)) +>X : Symbol(X, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 64, 13)) +>NeededInfo : Symbol(NeededInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 52, 45)) + +export class MyServer extends Server {} // not assignable error at `MyInfo` +>MyServer : Symbol(MyServer, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 64, 37)) +>Server : Symbol(Server, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 61, 44)) +>MyInfo : Symbol(MyInfo, Decl(varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts, 56, 2)) + diff --git a/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.types b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.types new file mode 100644 index 0000000000..02a69f2fab --- /dev/null +++ b/tests/baselines/reference/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.types @@ -0,0 +1,165 @@ +=== tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts === +type Either = Left | Right; +>Either : Either + +class Left { +>Left : Left + + readonly _tag: 'Left' = 'Left' +>_tag : "Left" +>'Left' : "Left" + + readonly _A!: A +>_A : A + + readonly _L!: L +>_L : L + + constructor(readonly value: L) {} +>value : L + + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { +>map : (f: (a: A) => B) => Either +>f : (a: A) => B +>a : A + + return this as any +>this as any : any +>this : this + } + ap(fab: Either B>): Either { +>ap : (fab: Either B>) => Either +>fab : Either B> +>a : A + + return null as any +>null as any : any +>null : null + } +} + +class Right { +>Right : Right + + readonly _tag: 'Right' = 'Right' +>_tag : "Right" +>'Right' : "Right" + + readonly _A!: A +>_A : A + + readonly _L!: L +>_L : L + + constructor(readonly value: A) {} +>value : A + + map(f: (a: A) => B): Either { +>map : (f: (a: A) => B) => Either +>f : (a: A) => B +>a : A + + return new Right(f(this.value)) +>new Right(f(this.value)) : Right +>Right : typeof Right +>f(this.value) : B +>f : (a: A) => B +>this.value : A +>this : this +>value : A + } + ap(fab: Either B>): Either { +>ap : (fab: Either B>) => Either +>fab : Either B> +>a : A + + return null as any; +>null as any : any +>null : null + } +} + +class Type { +>Type : Type + + readonly _A!: A; +>_A : A + + readonly _O!: O; +>_O : O + + readonly _I!: I; +>_I : I + + constructor( + /** a unique name for this codec */ + readonly name: string, +>name : string + + /** a custom type guard */ + readonly is: (u: unknown) => u is A, +>is : (u: unknown) => u is A +>u : unknown + + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, +>validate : (input: I, context: {}[]) => Either<{}[], A> +>input : I +>context : {}[] + + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O +>encode : (a: A) => O +>a : A + + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +>decode : (i: I) => Either<{}[], A> +>i : I +>null as any : any +>null : null +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; +>TypeOf : C["_A"] + +type ToB = { [k in keyof S]: TypeOf }; +>ToB : ToB + +type ToA = { [k in keyof S]: Type }; +>ToA : ToA + +type NeededInfo = { +>NeededInfo : NeededInfo + + ASchema: ToA; +>ASchema : ToA + +}; + +export type MyInfo = NeededInfo>; +>MyInfo : NeededInfo> +>initialize : any + +const tmp1: MyInfo = null!; +>tmp1 : NeededInfo> +>null! : never +>null : null + +function tmp2(n: N) {} +>tmp2 : >(n: N) => void +>n : N + +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + +class Server {} +>Server : Server + +export class MyServer extends Server {} // not assignable error at `MyInfo` +>MyServer : MyServer +>Server : Server>> + diff --git a/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts b/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts new file mode 100644 index 0000000000..c84abda5e5 --- /dev/null +++ b/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign.ts @@ -0,0 +1,67 @@ +// @strict: true +type Either = Left | Right; + +class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } +} + +class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } +} + +class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; + +type ToB = { [k in keyof S]: TypeOf }; +type ToA = { [k in keyof S]: Type }; + +type NeededInfo = { + ASchema: ToA; +}; + +export type MyInfo = NeededInfo>; + +const tmp1: MyInfo = null!; +function tmp2(n: N) {} +tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? + +class Server {} +export class MyServer extends Server {} // not assignable error at `MyInfo` \ No newline at end of file diff --git a/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts b/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts new file mode 100644 index 0000000000..14d835e618 --- /dev/null +++ b/tests/cases/compiler/varianceProblingAndZeroOrderIndexSignatureRelationsAlign2.ts @@ -0,0 +1,67 @@ +// @strict: true +type Either = Left | Right; + +class Left { + readonly _tag: 'Left' = 'Left' + readonly _A!: A + readonly _L!: L + constructor(readonly value: L) {} + /** The given function is applied if this is a `Right` */ + map(f: (a: A) => B): Either { + return this as any + } + ap(fab: Either B>): Either { + return null as any + } +} + +class Right { + readonly _tag: 'Right' = 'Right' + readonly _A!: A + readonly _L!: L + constructor(readonly value: A) {} + map(f: (a: A) => B): Either { + return new Right(f(this.value)) + } + ap(fab: Either B>): Either { + return null as any; + } +} + +class Type { + readonly _A!: A; + readonly _O!: O; + readonly _I!: I; + constructor( + /** a unique name for this codec */ + readonly name: string, + /** a custom type guard */ + readonly is: (u: unknown) => u is A, + /** succeeds if a value of type I can be decoded to a value of type A */ + readonly validate: (input: I, context: {}[]) => Either<{}[], A>, + /** converts a value of type A to a value of type O */ + readonly encode: (a: A) => O + ) {} + /** a version of `validate` with a default context */ + decode(i: I): Either<{}[], A> { return null as any; } +} + +interface Any extends Type {} + +type TypeOf = C["_A"]; + +type ToB = { [k in keyof S]: TypeOf }; +type ToA = { [k in keyof S]: Type }; + +type NeededInfo = { + ASchema: ToA; +}; + +export type MyInfo = NeededInfo>; + +const tmp1: MyInfo = null!; +function tmp2(n: N) {} +// tmp2(tmp1); // uncommenting this line removes a type error from a completely unrelated line ?? (see test 1, needs to behave the same) + +class Server {} +export class MyServer extends Server {} // not assignable error at `MyInfo` \ No newline at end of file From ee17915801d3e1cf796c7a92861c6b1dc5f4d884 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 19 Feb 2019 14:30:58 -0800 Subject: [PATCH 14/14] Fix build breaks (#29977) * Some callbacks in watchUtilities werent being strictly checked due to the structural fallback * Add direct dependeny on ms since mocha removed its impl * Manually init stats collection on base runner like mocha.run now does --- package.json | 2 ++ src/compiler/watchUtilities.ts | 10 +++++----- src/testRunner/parallel/host.ts | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f891f99be5..abf7aa17d3 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@types/minimist": "latest", "@types/mkdirp": "latest", "@types/mocha": "latest", + "@types/ms": "latest", "@types/node": "8.5.5", "@types/q": "latest", "@types/source-map-support": "latest", @@ -74,6 +75,7 @@ "mkdirp": "latest", "mocha": "latest", "mocha-fivemat-progress-reporter": "latest", + "ms": "latest", "plugin-error": "latest", "pretty-hrtime": "^1.0.3", "prex": "^0.4.3", diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index 9bf242e07e..565af054b8 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -361,9 +361,9 @@ namespace ts { function getWatchFactoryWith(watchLogLevel: WatchLogLevel, log: (s: string) => void, getDetailWatchInfo: GetDetailWatchInfo | undefined, watchFile: (host: WatchFileHost, file: string, callback: FileWatcherCallback, watchPriority: PollingInterval) => FileWatcher, watchDirectory: (host: WatchDirectoryHost, directory: string, callback: DirectoryWatcherCallback, flags: WatchDirectoryFlags) => FileWatcher): WatchFactory { - const createFileWatcher: CreateFileWatcher = getCreateFileWatcher(watchLogLevel, watchFile); + const createFileWatcher: CreateFileWatcher = getCreateFileWatcher(watchLogLevel, watchFile); const createFilePathWatcher: CreateFileWatcher = watchLogLevel === WatchLogLevel.None ? watchFilePath : createFileWatcher; - const createDirectoryWatcher: CreateFileWatcher = getCreateFileWatcher(watchLogLevel, watchDirectory); + const createDirectoryWatcher: CreateFileWatcher = getCreateFileWatcher(watchLogLevel, watchDirectory); return { watchFile: (host, file, callback, pollingInterval, detailInfo1, detailInfo2) => createFileWatcher(host, file, callback, pollingInterval, /*passThrough*/ undefined, detailInfo1, detailInfo2, watchFile, log, "FileWatcher", getDetailWatchInfo), @@ -402,7 +402,7 @@ namespace ts { } } - function createFileWatcherWithLogging(host: H, file: string, cb: WatchCallback, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo | undefined): FileWatcher { + function createFileWatcherWithLogging(host: H, file: string, cb: WatchCallback, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo | undefined): FileWatcher { log(`${watchCaption}:: Added:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`); const watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo); return { @@ -413,7 +413,7 @@ namespace ts { }; } - function createDirectoryWatcherWithLogging(host: H, file: string, cb: WatchCallback, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo | undefined): FileWatcher { + function createDirectoryWatcherWithLogging(host: H, file: string, cb: WatchCallback, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo | undefined): FileWatcher { const watchInfo = `${watchCaption}:: Added:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`; log(watchInfo); const start = timestamp(); @@ -432,7 +432,7 @@ namespace ts { }; } - function createFileWatcherWithTriggerLogging(host: H, file: string, cb: WatchCallback, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo | undefined): FileWatcher { + function createFileWatcherWithTriggerLogging(host: H, file: string, cb: WatchCallback, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo | undefined): FileWatcher { return addWatch(host, file, (fileName, cbOptional) => { const triggerredInfo = `${watchCaption}:: Triggered with ${fileName} ${cbOptional !== undefined ? cbOptional : ""}:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`; log(triggerredInfo); diff --git a/src/testRunner/parallel/host.ts b/src/testRunner/parallel/host.ts index 9adf9e7e85..597013ed0d 100644 --- a/src/testRunner/parallel/host.ts +++ b/src/testRunner/parallel/host.ts @@ -7,7 +7,7 @@ namespace Harness.Parallel.Host { const Base = Mocha.reporters.Base; const color = Base.color; const cursor = Base.cursor; - const ms = require("mocha/lib/ms") as typeof import("mocha/lib/ms"); + const ms = require("ms") as typeof import("ms"); const readline = require("readline") as typeof import("readline"); const os = require("os") as typeof import("os"); const tty = require("tty") as typeof import("tty"); @@ -530,6 +530,8 @@ namespace Harness.Parallel.Host { const replayRunner = new Mocha.Runner(new Mocha.Suite(""), /*delay*/ false); replayRunner.started = true; + const createStatsCollector = require("mocha/lib/stats-collector"); + createStatsCollector(replayRunner); // manually init stats collector like mocha.run would const consoleReporter = new Base(replayRunner); patchStats(consoleReporter.stats);