From 8e8a2397caffb09eb40905f95fe4ba92fd26d0e7 Mon Sep 17 00:00:00 2001 From: fullheightcoding Date: Thu, 25 Oct 2018 17:55:28 +1100 Subject: [PATCH 01/42] Fixed some typos. --- scripts/authors.ts | 14 +++++++------- scripts/bisect-test.ts | 2 +- scripts/createBenchmark.ts | 6 +++--- scripts/generateLocalizedDiagnosticMessages.ts | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/authors.ts b/scripts/authors.ts index b616ceb8601..b52898244b6 100644 --- a/scripts/authors.ts +++ b/scripts/authors.ts @@ -4,7 +4,7 @@ import child_process = require("child_process"); type Author = { displayNames: string[]; - preferedName?: string; + preferredName?: string; emails: string[]; }; @@ -20,7 +20,7 @@ const authorsPath = path.resolve("../AUTHORS.md"); function getKnownAuthors(): Author[] { const segmentRegExp = /\s?([^<]+)\s+<([^>]+)>/g; - const preferedNameRegeExp = /\s?#\s?([^#]+)$/; + const preferredNameRegeExp = /\s?#\s?([^#]+)$/; const knownAuthors: Author[] = []; if (!fs.existsSync(mailMapPath)) { @@ -37,13 +37,13 @@ function getKnownAuthors(): Author[] { author.displayNames.push(match[1]); author.emails.push(match[2]); } - if (match = preferedNameRegeExp.exec(line)) { - author.preferedName = match[1]; + if (match = preferredNameRegeExp.exec(line)) { + author.preferredName = match[1]; } if (!author.emails) continue; knownAuthors.push(author); - if (line.indexOf("#") > 0 && !author.preferedName) { - throw new Error("Could not match prefered name for: " + line); + if (line.indexOf("#") > 0 && !author.preferredName) { + throw new Error("Could not match preferred name for: " + line); } // console.log("===> line: " + line); // console.log(JSON.stringify(author, undefined, 2)); @@ -52,7 +52,7 @@ function getKnownAuthors(): Author[] { } function getAuthorName(author: Author) { - return author.preferedName || author.displayNames[0]; + return author.preferredName || author.displayNames[0]; } function getKnownAuthorMaps() { diff --git a/scripts/bisect-test.ts b/scripts/bisect-test.ts index 948b272470f..cc0248f6d64 100644 --- a/scripts/bisect-test.ts +++ b/scripts/bisect-test.ts @@ -5,7 +5,7 @@ import cp = require('child_process'); import fs = require('fs'); -// Slice off 'node bisect-test.js' from the commandline args +// Slice off 'node bisect-test.js' from the command line args var args = process.argv.slice(2); function tsc(tscArgs: string, onExit: (exitCode: number) => void) { diff --git a/scripts/createBenchmark.ts b/scripts/createBenchmark.ts index 6148d80bf2c..254c0d99af0 100644 --- a/scripts/createBenchmark.ts +++ b/scripts/createBenchmark.ts @@ -30,7 +30,7 @@ var rawCompilerSources = ""; sourceFiles.forEach(f=> { rawCompilerSources += "\r\n" + fs.readFileSync(path.join(tsSourceDir, f)).toString(); }); -var compilerSoruces = `var compilerSources = ${JSON.stringify(rawCompilerSources) };`; +var compilerSources = `var compilerSources = ${JSON.stringify(rawCompilerSources) };`; // .js code for the compiler, what we are actually testing var rawCompilerJavaScript = fs.readFileSync(path.join(tsBuildDir, "tsc.js")).toString(); @@ -38,7 +38,7 @@ rawCompilerJavaScript = rawCompilerJavaScript.replace("ts.executeCommandLine(ts. // lib.d.ts sources var rawLibSources = fs.readFileSync(path.join(tsBuildDir, "lib.d.ts")).toString(); -var libSoruces = `var libSources = ${JSON.stringify(rawLibSources) };`; +var libSources = `var libSources = ${JSON.stringify(rawLibSources) };`; // write test output if (!fs.existsSync(testOutputDir)) { @@ -48,7 +48,7 @@ if (!fs.existsSync(testOutputDir)) { // 1. compiler ts sources, used to test fs.writeFileSync( path.join(testOutputDir, "compilerSources.js"), - `${ compilerSoruces } \r\n ${ libSoruces }`); + `${ compilerSources } \r\n ${ libSources }`); // 2. the compiler js sources + a call the compiler fs.writeFileSync( diff --git a/scripts/generateLocalizedDiagnosticMessages.ts b/scripts/generateLocalizedDiagnosticMessages.ts index 09d117d533b..2374a9b4dab 100644 --- a/scripts/generateLocalizedDiagnosticMessages.ts +++ b/scripts/generateLocalizedDiagnosticMessages.ts @@ -36,7 +36,7 @@ function main(): void { console.error("Unexpected XML file structure. Expected to find result.LCX.$.TgtCul."); process.exit(1); } - const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul); + const outputDirectoryName = getPreferredLocaleName(result.LCX.$.TgtCul); if (!outputDirectoryName) { console.error(`Invalid output locale name for '${result.LCX.$.TgtCul}'.`); process.exit(1); @@ -64,7 +64,7 @@ function main(): void { * Most of the languages we support are neutral locales, so we want to use the language name. * There are three exceptions, zh-CN, zh-TW and pt-BR. */ - function getPreferedLocaleName(localeName: string) { + function getPreferredLocaleName(localeName: string) { switch (localeName) { case "zh-CN": case "zh-TW": From 01e71820fc62bcc31987f4a8912ed3fd023bd1dd Mon Sep 17 00:00:00 2001 From: AnyhowStep Date: Wed, 31 Oct 2018 17:00:24 -0400 Subject: [PATCH 02/42] Fixes Microsoft/TypeScript#6955 --- lib/lib.es5.d.ts | 4 ++-- src/lib/es5.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/lib.es5.d.ts b/lib/lib.es5.d.ts index d1a9d6f0d2a..82d13bf3f17 100644 --- a/lib/lib.es5.d.ts +++ b/lib/lib.es5.d.ts @@ -1046,14 +1046,14 @@ interface JSON { * @param reviver A function that transforms the results. This function is called for each member of the object. * If a member contains nested objects, the nested objects are transformed before the parent object is. */ - parse(text: string, reviver?: (key: any, value: any) => any): any; + parse(text: string, reviver?: (this : any, key: string, value: any) => any): any; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. * @param replacer A function that transforms the results. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; + stringify(value: any, replacer?: (this : any, key: string, value: any) => any, space?: string | number): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index c8e99f0d1db..2da00df5a60 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1026,14 +1026,14 @@ interface JSON { * @param reviver A function that transforms the results. This function is called for each member of the object. * If a member contains nested objects, the nested objects are transformed before the parent object is. */ - parse(text: string, reviver?: (key: any, value: any) => any): any; + parse(text: string, reviver?: (this : any, key: string, value: any) => any): any; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. * @param replacer A function that transforms the results. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; + stringify(value: any, replacer?: (this : any, key: string, value: any) => any, space?: string | number): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. From e3ee7ae997f4cf4b1aa9e724739078d467f0a3fb Mon Sep 17 00:00:00 2001 From: AnyhowStep Date: Wed, 31 Oct 2018 17:29:03 -0400 Subject: [PATCH 03/42] Update baselines --- .../reference/controlFlowIfStatement.types | 4 ++-- .../controlFlowPropertyDeclarations.types | 4 ++-- .../baselines/reference/json.stringify.types | 22 +++++++++---------- tests/baselines/reference/parserharness.types | 4 ++-- ...ymousTypeNotReferencingTypeParameter.types | 4 ++-- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/baselines/reference/controlFlowIfStatement.types b/tests/baselines/reference/controlFlowIfStatement.types index 03141e26185..35862e32654 100644 --- a/tests/baselines/reference/controlFlowIfStatement.types +++ b/tests/baselines/reference/controlFlowIfStatement.types @@ -101,9 +101,9 @@ function c(data: string | T): T { return JSON.parse(data); >JSON.parse(data) : any ->JSON.parse : (text: string, reviver?: (key: any, value: any) => any) => any +>JSON.parse : (text: string, reviver?: (this: any, key: string, value: any) => any) => any >JSON : JSON ->parse : (text: string, reviver?: (key: any, value: any) => any) => any +>parse : (text: string, reviver?: (this: any, key: string, value: any) => any) => any >data : string | (T & string) } else { diff --git a/tests/baselines/reference/controlFlowPropertyDeclarations.types b/tests/baselines/reference/controlFlowPropertyDeclarations.types index 0e698b72608..1cbe9969610 100644 --- a/tests/baselines/reference/controlFlowPropertyDeclarations.types +++ b/tests/baselines/reference/controlFlowPropertyDeclarations.types @@ -316,9 +316,9 @@ export class HTMLtoJSX { >'{' + JSON.stringify(whitespace) : string >'{' : "{" >JSON.stringify(whitespace) : string ->JSON.stringify : { (value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } +>JSON.stringify : { (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } >JSON : JSON ->stringify : { (value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } +>stringify : { (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } >whitespace : string >'}' : "}" diff --git a/tests/baselines/reference/json.stringify.types b/tests/baselines/reference/json.stringify.types index a25eac5aaf7..44f7636d46a 100644 --- a/tests/baselines/reference/json.stringify.types +++ b/tests/baselines/reference/json.stringify.types @@ -5,27 +5,27 @@ var value = null; JSON.stringify(value, undefined, 2); >JSON.stringify(value, undefined, 2) : string ->JSON.stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>JSON.stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >JSON : JSON ->stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >value : null >undefined : undefined >2 : 2 JSON.stringify(value, null, 2); >JSON.stringify(value, null, 2) : string ->JSON.stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>JSON.stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >JSON : JSON ->stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >value : null >null : null >2 : 2 JSON.stringify(value, ["a", 1], 2); >JSON.stringify(value, ["a", 1], 2) : string ->JSON.stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>JSON.stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >JSON : JSON ->stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >value : null >["a", 1] : (string | number)[] >"a" : "a" @@ -34,20 +34,20 @@ JSON.stringify(value, ["a", 1], 2); JSON.stringify(value, (k) => undefined, 2); >JSON.stringify(value, (k) => undefined, 2) : string ->JSON.stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>JSON.stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >JSON : JSON ->stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >value : null ->(k) => undefined : (k: string) => undefined +>(k) => undefined : (this: any, k: string) => undefined >k : string >undefined : undefined >2 : 2 JSON.stringify(value, undefined, 2); >JSON.stringify(value, undefined, 2) : string ->JSON.stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>JSON.stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >JSON : JSON ->stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >value : null >undefined : undefined >2 : 2 diff --git a/tests/baselines/reference/parserharness.types b/tests/baselines/reference/parserharness.types index 222ac9ab945..25bb34a6c52 100644 --- a/tests/baselines/reference/parserharness.types +++ b/tests/baselines/reference/parserharness.types @@ -7549,9 +7549,9 @@ module Harness { return JSON.stringify({ usePullLanguageService: usePull }); >JSON.stringify({ usePullLanguageService: usePull }) : string ->JSON.stringify : { (value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } +>JSON.stringify : { (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } >JSON : JSON ->stringify : { (value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } +>stringify : { (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } >{ usePullLanguageService: usePull } : { usePullLanguageService: boolean; } >usePullLanguageService : boolean >usePull : boolean diff --git a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types index 382c14fb22b..cd907c26ec8 100644 --- a/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types +++ b/tests/baselines/reference/staticAnonymousTypeNotReferencingTypeParameter.types @@ -594,9 +594,9 @@ class ListWrapper { >ListWrapper : typeof ListWrapper >l : T[] >JSON.stringify(l) : string ->JSON.stringify : { (value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } +>JSON.stringify : { (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } >JSON : JSON ->stringify : { (value: any, replacer?: (key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } +>stringify : { (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; (value: any, replacer?: (string | number)[], space?: string | number): string; } >l : T[] static maximum(dit: typeof ListWrapper, list: T[], predicate: (t: T) => number): T { From dd3ed0286885ff6e6dc0f8211f9281667387cf90 Mon Sep 17 00:00:00 2001 From: AnyhowStep Date: Tue, 13 Nov 2018 12:24:03 -0500 Subject: [PATCH 04/42] Removed stray whitespace --- lib/lib.es5.d.ts | 4 ++-- src/lib/es5.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/lib.es5.d.ts b/lib/lib.es5.d.ts index 82d13bf3f17..068ef13470a 100644 --- a/lib/lib.es5.d.ts +++ b/lib/lib.es5.d.ts @@ -1046,14 +1046,14 @@ interface JSON { * @param reviver A function that transforms the results. This function is called for each member of the object. * If a member contains nested objects, the nested objects are transformed before the parent object is. */ - parse(text: string, reviver?: (this : any, key: string, value: any) => any): any; + parse(text: string, reviver?: (this: any, key: string, value: any) => any): any; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. * @param replacer A function that transforms the results. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer?: (this : any, key: string, value: any) => any, space?: string | number): string; + stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 2da00df5a60..715b5f9fbac 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1026,14 +1026,14 @@ interface JSON { * @param reviver A function that transforms the results. This function is called for each member of the object. * If a member contains nested objects, the nested objects are transformed before the parent object is. */ - parse(text: string, reviver?: (this : any, key: string, value: any) => any): any; + parse(text: string, reviver?: (this: any, key: string, value: any) => any): any; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. * @param replacer A function that transforms the results. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. */ - stringify(value: any, replacer?: (this : any, key: string, value: any) => any, space?: string | number): string; + stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. * @param value A JavaScript value, usually an object or array, to be converted. From a769c354848236544de3829c62770eaed1190007 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Sun, 23 Dec 2018 23:13:46 +0100 Subject: [PATCH 05/42] property is used before its initialization: check more nodes Fixes: #29125 --- src/compiler/checker.ts | 14 +++- .../useBeforeDeclaration_jsx.errors.txt | 38 ++++++++++ .../reference/useBeforeDeclaration_jsx.js | 28 ++++++++ .../useBeforeDeclaration_jsx.symbols | 55 +++++++++++++++ .../reference/useBeforeDeclaration_jsx.types | 69 +++++++++++++++++++ ...eDeclaration_propertyAssignment.errors.txt | 38 +++++++++- ...useBeforeDeclaration_propertyAssignment.js | 39 ++++++++--- ...foreDeclaration_propertyAssignment.symbols | 62 +++++++++++++++-- ...BeforeDeclaration_propertyAssignment.types | 69 ++++++++++++++++++- .../compiler/useBeforeDeclaration_jsx.tsx | 16 +++++ ...useBeforeDeclaration_propertyAssignment.ts | 16 ++++- 11 files changed, 422 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/useBeforeDeclaration_jsx.errors.txt create mode 100644 tests/baselines/reference/useBeforeDeclaration_jsx.js create mode 100644 tests/baselines/reference/useBeforeDeclaration_jsx.symbols create mode 100644 tests/baselines/reference/useBeforeDeclaration_jsx.types create mode 100644 tests/cases/compiler/useBeforeDeclaration_jsx.tsx diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 23c5568f2e5..933ad041b91 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19094,7 +19094,19 @@ namespace ts { case SyntaxKind.PropertyDeclaration: return true; case SyntaxKind.PropertyAssignment: - // We might be in `a = { b: this.b }`, so keep looking. See `tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts`. + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.SpreadAssignment: + case SyntaxKind.ComputedPropertyName: + case SyntaxKind.TemplateSpan: + case SyntaxKind.JsxExpression: + case SyntaxKind.JsxAttribute: + case SyntaxKind.JsxAttributes: + case SyntaxKind.JsxSpreadAttribute: + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.ExpressionWithTypeArguments: + case SyntaxKind.HeritageClause: return false; default: return isExpressionNode(node) ? false : "quit"; diff --git a/tests/baselines/reference/useBeforeDeclaration_jsx.errors.txt b/tests/baselines/reference/useBeforeDeclaration_jsx.errors.txt new file mode 100644 index 00000000000..ea15b246163 --- /dev/null +++ b/tests/baselines/reference/useBeforeDeclaration_jsx.errors.txt @@ -0,0 +1,38 @@ +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(6,19): error TS2729: Property 'z' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(7,19): error TS2729: Property 'z' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(8,28): error TS2729: Property 'x' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(9,28): error TS2729: Property 'y' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_jsx.tsx(10,25): error TS2729: Property 'y' is used before its initialization. + + +==== tests/cases/compiler/useBeforeDeclaration_jsx.tsx (5 errors) ==== + namespace JSX { + export interface Element {} + } + + class C { + static a = ; + ~ +!!! error TS2729: Property 'z' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:13:12: 'z' is declared here. + static b = ; + ~ +!!! error TS2729: Property 'z' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:13:12: 'z' is declared here. + static c = ; + ~ +!!! error TS2729: Property 'x' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:11:12: 'x' is declared here. + static d = ; + ~ +!!! error TS2729: Property 'y' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:12:12: 'y' is declared here. + static e = {C.y}; + ~ +!!! error TS2729: Property 'y' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_jsx.tsx:12:12: 'y' is declared here. + static x = {}; + static y = ''; + static z = () => ; + } + \ No newline at end of file diff --git a/tests/baselines/reference/useBeforeDeclaration_jsx.js b/tests/baselines/reference/useBeforeDeclaration_jsx.js new file mode 100644 index 00000000000..e95bf254644 --- /dev/null +++ b/tests/baselines/reference/useBeforeDeclaration_jsx.js @@ -0,0 +1,28 @@ +//// [useBeforeDeclaration_jsx.tsx] +namespace JSX { + export interface Element {} +} + +class C { + static a = ; + static b = ; + static c = ; + static d = ; + static e = {C.y}; + static x = {}; + static y = ''; + static z = () => ; +} + + +//// [useBeforeDeclaration_jsx.jsx] +class C { +} +C.a = ; +C.b = ; +C.c = ; +C.d = ; +C.e = {C.y}; +C.x = {}; +C.y = ''; +C.z = () => ; diff --git a/tests/baselines/reference/useBeforeDeclaration_jsx.symbols b/tests/baselines/reference/useBeforeDeclaration_jsx.symbols new file mode 100644 index 00000000000..434fe841fe0 --- /dev/null +++ b/tests/baselines/reference/useBeforeDeclaration_jsx.symbols @@ -0,0 +1,55 @@ +=== tests/cases/compiler/useBeforeDeclaration_jsx.tsx === +namespace JSX { +>JSX : Symbol(JSX, Decl(useBeforeDeclaration_jsx.tsx, 0, 0)) + + export interface Element {} +>Element : Symbol(Element, Decl(useBeforeDeclaration_jsx.tsx, 0, 15)) +} + +class C { +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) + + static a = ; +>a : Symbol(C.a, Decl(useBeforeDeclaration_jsx.tsx, 4, 9)) +>C.z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +>C.z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) + + static b = ; +>b : Symbol(C.b, Decl(useBeforeDeclaration_jsx.tsx, 5, 27)) +>C.z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) + + static c = ; +>c : Symbol(C.c, Decl(useBeforeDeclaration_jsx.tsx, 6, 22)) +>C.x : Symbol(C.x, Decl(useBeforeDeclaration_jsx.tsx, 9, 34)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>x : Symbol(C.x, Decl(useBeforeDeclaration_jsx.tsx, 9, 34)) + + static d = ; +>d : Symbol(C.d, Decl(useBeforeDeclaration_jsx.tsx, 7, 38)) +>id : Symbol(id, Decl(useBeforeDeclaration_jsx.tsx, 8, 20)) +>C.y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) + + static e = {C.y}; +>e : Symbol(C.e, Decl(useBeforeDeclaration_jsx.tsx, 8, 38)) +>C.y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) +>C : Symbol(C, Decl(useBeforeDeclaration_jsx.tsx, 2, 1)) +>y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) + + static x = {}; +>x : Symbol(C.x, Decl(useBeforeDeclaration_jsx.tsx, 9, 34)) + + static y = ''; +>y : Symbol(C.y, Decl(useBeforeDeclaration_jsx.tsx, 10, 18)) + + static z = () => ; +>z : Symbol(C.z, Decl(useBeforeDeclaration_jsx.tsx, 11, 18)) +} + diff --git a/tests/baselines/reference/useBeforeDeclaration_jsx.types b/tests/baselines/reference/useBeforeDeclaration_jsx.types new file mode 100644 index 00000000000..18e0e341390 --- /dev/null +++ b/tests/baselines/reference/useBeforeDeclaration_jsx.types @@ -0,0 +1,69 @@ +=== tests/cases/compiler/useBeforeDeclaration_jsx.tsx === +namespace JSX { + export interface Element {} +} + +class C { +>C : C + + static a = ; +>a : JSX.Element +> : JSX.Element +>C.z : () => JSX.Element +>C : typeof C +>z : () => JSX.Element +>C.z : () => JSX.Element +>C : typeof C +>z : () => JSX.Element + + static b = ; +>b : JSX.Element +> : JSX.Element +>C.z : () => JSX.Element +>C : typeof C +>z : () => JSX.Element + + static c = ; +>c : JSX.Element +> : JSX.Element +>span : any +>C.x : {} +>C : typeof C +>x : {} +>span : any + + static d = ; +>d : JSX.Element +> : JSX.Element +>span : any +>id : string +>C.y : string +>C : typeof C +>y : string +>span : any + + static e = {C.y}; +>e : JSX.Element +>{C.y} : JSX.Element +>span : any +>C.y : string +>C : typeof C +>y : string +>span : any + + static x = {}; +>x : {} +>{} : {} + + static y = ''; +>y : string +>'' : "" + + static z = () => ; +>z : () => JSX.Element +>() => : () => JSX.Element +> : JSX.Element +>b : any +>b : any +} + diff --git a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.errors.txt b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.errors.txt index e58e7fa02e9..b1b2174d1dc 100644 --- a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.errors.txt +++ b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.errors.txt @@ -1,12 +1,44 @@ tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(2,27): error TS2729: Property 'b' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(2,38): error TS2729: Property 'c' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(2,47): error TS2729: Property 'b' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(2,59): error TS2729: Property 'c' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(8,32): error TS2729: Property 'B' is used before its initialization. +tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts(13,12): error TS2729: Property 'D' is used before its initialization. -==== tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts (1 errors) ==== +==== tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts (6 errors) ==== export class C { - public a = { b: this.b }; + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; ~ !!! error TS2729: Property 'b' is used before its initialization. !!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:3:13: 'b' is declared here. + ~ +!!! error TS2729: Property 'c' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:4:12: 'c' is declared here. + ~ +!!! error TS2729: Property 'b' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:3:13: 'b' is declared here. + ~ +!!! error TS2729: Property 'c' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:4:12: 'c' is declared here. private b = 0; + public c = { c: this.b }; } - \ No newline at end of file + + class D { + static A = class extends D.B { + ~ +!!! error TS2729: Property 'B' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:11:12: 'B' is declared here. + [D.D]() {} // should be an error + } + static B = class {} + static C = { + [D.D]: 1, + ~ +!!! error TS2729: Property 'D' is used before its initialization. +!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts:16:12: 'D' is declared here. + ...{get [D.D]() {return 0;}} // should be an error + }; + static D = ''; + } \ No newline at end of file diff --git a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.js b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.js index e34604e0a4e..47968d429ad 100644 --- a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.js +++ b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.js @@ -1,18 +1,37 @@ //// [useBeforeDeclaration_propertyAssignment.ts] export class C { - public a = { b: this.b }; + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; private b = 0; + public c = { c: this.b }; } - + +class D { + static A = class extends D.B { + [D.D]() {} // should be an error + } + static B = class {} + static C = { + [D.D]: 1, + ...{get [D.D]() {return 0;}} // should be an error + }; + static D = ''; +} //// [useBeforeDeclaration_propertyAssignment.js] -"use strict"; -exports.__esModule = true; -var C = /** @class */ (function () { - function C() { - this.a = { b: this.b }; +export class C { + constructor() { + this.a = Object.assign({ b: this.b }, this.c, { [this.b]: `${this.c}` }); this.b = 0; + this.c = { c: this.b }; } - return C; -}()); -exports.C = C; +} +class D { +} +D.A = class extends D.B { + [D.D]() { } // should be an error +}; +D.B = class { +}; +D.C = Object.assign({ [D.D]: 1 }, { get [D.D]() { return 0; } } // should be an error +); +D.D = ''; diff --git a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.symbols b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.symbols index 5b067232ef6..7c8acfc5375 100644 --- a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.symbols +++ b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.symbols @@ -2,14 +2,68 @@ export class C { >C : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) - public a = { b: this.b }; + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; >a : Symbol(C.a, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 16)) >b : Symbol(b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 17)) ->this.b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 30)) +>this.b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) >this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) ->b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 30)) +>b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) +>this.c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) +>this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) +>c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) +>[this.b] : Symbol([this.b], Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 39)) +>this.b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) +>this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) +>b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) +>this.c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) +>this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) +>c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) private b = 0; ->b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 30)) +>b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) + + public c = { c: this.b }; +>c : Symbol(C.c, Decl(useBeforeDeclaration_propertyAssignment.ts, 2, 18)) +>c : Symbol(c, Decl(useBeforeDeclaration_propertyAssignment.ts, 3, 16)) +>this.b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) +>this : Symbol(C, Decl(useBeforeDeclaration_propertyAssignment.ts, 0, 0)) +>b : Symbol(C.b, Decl(useBeforeDeclaration_propertyAssignment.ts, 1, 63)) } +class D { +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) + + static A = class extends D.B { +>A : Symbol(D.A, Decl(useBeforeDeclaration_propertyAssignment.ts, 6, 9)) +>D.B : Symbol(D.B, Decl(useBeforeDeclaration_propertyAssignment.ts, 9, 5)) +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) +>B : Symbol(D.B, Decl(useBeforeDeclaration_propertyAssignment.ts, 9, 5)) + + [D.D]() {} // should be an error +>[D.D] : Symbol((Anonymous class)[D.D], Decl(useBeforeDeclaration_propertyAssignment.ts, 7, 34)) +>D.D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) +>D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) + } + static B = class {} +>B : Symbol(D.B, Decl(useBeforeDeclaration_propertyAssignment.ts, 9, 5)) + + static C = { +>C : Symbol(D.C, Decl(useBeforeDeclaration_propertyAssignment.ts, 10, 23)) + + [D.D]: 1, +>[D.D] : Symbol([D.D], Decl(useBeforeDeclaration_propertyAssignment.ts, 11, 16)) +>D.D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) +>D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) + + ...{get [D.D]() {return 0;}} // should be an error +>[D.D] : Symbol([D.D], Decl(useBeforeDeclaration_propertyAssignment.ts, 13, 12)) +>D.D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) +>D : Symbol(D, Decl(useBeforeDeclaration_propertyAssignment.ts, 4, 1)) +>D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) + + }; + static D = ''; +>D : Symbol(D.D, Decl(useBeforeDeclaration_propertyAssignment.ts, 14, 6)) +} diff --git a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.types b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.types index cb30e36f28d..e4136fde22a 100644 --- a/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.types +++ b/tests/baselines/reference/useBeforeDeclaration_propertyAssignment.types @@ -2,16 +2,79 @@ export class C { >C : C - public a = { b: this.b }; ->a : { b: number; } ->{ b: this.b } : { b: number; } + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; +>a : { c: number; b: number; } +>{ b: this.b, ...this.c, [this.b]: `${this.c}`} : { c: number; b: number; } >b : number >this.b : number >this : this >b : number +>this.c : { c: number; } +>this : this +>c : { c: number; } +>[this.b] : string +>this.b : number +>this : this +>b : number +>`${this.c}` : string +>this.c : { c: number; } +>this : this +>c : { c: number; } private b = 0; >b : number >0 : 0 + + public c = { c: this.b }; +>c : { c: number; } +>{ c: this.b } : { c: number; } +>c : number +>this.b : number +>this : this +>b : number } +class D { +>D : D + + static A = class extends D.B { +>A : typeof (Anonymous class) +>class extends D.B { [D.D]() {} // should be an error } : typeof (Anonymous class) +>D.B : (Anonymous class) +>D : typeof D +>B : typeof (Anonymous class) + + [D.D]() {} // should be an error +>[D.D] : () => void +>D.D : string +>D : typeof D +>D : string + } + static B = class {} +>B : typeof (Anonymous class) +>class {} : typeof (Anonymous class) + + static C = { +>C : { [x: string]: number; } +>{ [D.D]: 1, ...{get [D.D]() {return 0;}} // should be an error } : { [x: string]: number; } + + [D.D]: 1, +>[D.D] : number +>D.D : string +>D : typeof D +>D : string +>1 : 1 + + ...{get [D.D]() {return 0;}} // should be an error +>{get [D.D]() {return 0;}} : { [x: string]: number; } +>[D.D] : number +>D.D : string +>D : typeof D +>D : string +>0 : 0 + + }; + static D = ''; +>D : string +>'' : "" +} diff --git a/tests/cases/compiler/useBeforeDeclaration_jsx.tsx b/tests/cases/compiler/useBeforeDeclaration_jsx.tsx new file mode 100644 index 00000000000..3995bf8a738 --- /dev/null +++ b/tests/cases/compiler/useBeforeDeclaration_jsx.tsx @@ -0,0 +1,16 @@ +// @jsx: preserve +// @target: ES6 +namespace JSX { + export interface Element {} +} + +class C { + static a = ; + static b = ; + static c = ; + static d = ; + static e = {C.y}; + static x = {}; + static y = ''; + static z = () => ; +} diff --git a/tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts b/tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts index bdd84473c57..6ce314bcc03 100644 --- a/tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts +++ b/tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts @@ -1,4 +1,18 @@ +// @target: ES6 export class C { - public a = { b: this.b }; + public a = { b: this.b, ...this.c, [this.b]: `${this.c}`}; private b = 0; + public c = { c: this.b }; } + +class D { + static A = class extends D.B { + [D.D]() {} // should be an error + } + static B = class {} + static C = { + [D.D]: 1, + ...{get [D.D]() {return 0;}} // should be an error + }; + static D = ''; +} \ No newline at end of file From c9c9f859f3f9118e707ff3cef6a2a02e2d599890 Mon Sep 17 00:00:00 2001 From: xiaofa Date: Thu, 17 Jan 2019 05:51:57 +0800 Subject: [PATCH 06/42] fix quick fix infer parameter types from usage in js file --- src/services/textChanges.ts | 4 +++- .../fourslash/codeFixInferFromUsageArrowJS.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 4689e18508c..7dab7205841 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -340,7 +340,9 @@ namespace ts.textChanges { } public insertJsdocCommentBefore(sourceFile: SourceFile, node: HasJSDoc, tag: JSDoc): void { - const fnStart = node.getStart(sourceFile); + const fnStart = node.kind === SyntaxKind.ArrowFunction + ? node.parent.parent.getStart(sourceFile) + : node.getStart(sourceFile); if (node.jsDoc) { for (const jsdoc of node.jsDoc) { this.deleteRange(sourceFile, { diff --git a/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts b/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts new file mode 100644 index 00000000000..e867ae99c75 --- /dev/null +++ b/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts @@ -0,0 +1,18 @@ +/// +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @noImplicitAny: true +// @Filename: test.js + +////const foo = x => x.y + 1; + +verify.codeFix({ + description: "Infer parameter types from usage", + index: 0, + newFileContent: +`/** + * @param {{ y: number; }} x + */ +const foo = x => x.y + 1;`, +}); \ No newline at end of file From 1b4bce236eeb2dc6ed0f3a5467b15f5bedeb2dfa Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 17 Jan 2019 14:37:31 -0800 Subject: [PATCH 07/42] Infer contextual types from return types through generic functions --- src/compiler/checker.ts | 46 +++++++++++++++++++++++++++-------------- src/compiler/types.ts | 1 + 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cb132ebf927..352a5c31592 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14591,18 +14591,18 @@ namespace ts { } function inferFromProperties(source: Type, target: Type) { - if (isTupleType(source)) { + if (isArrayType(source) || isTupleType(source)) { if (isTupleType(target)) { - const sourceLength = getLengthOfTupleType(source); + const sourceLength = isTupleType(source) ? getLengthOfTupleType(source) : 0; const targetLength = getLengthOfTupleType(target); - const sourceRestType = getRestTypeOfTupleType(source); + const sourceRestType = isTupleType(source) ? getRestTypeOfTupleType(source) : getElementTypeOfArrayType(source); const targetRestType = getRestTypeOfTupleType(target); const fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength; for (let i = 0; i < fixedLength; i++) { - inferFromTypes(i < sourceLength ? source.typeArguments![i] : sourceRestType!, target.typeArguments![i]); + inferFromTypes(i < sourceLength ? (source).typeArguments![i] : sourceRestType!, target.typeArguments![i]); } if (targetRestType) { - const types = fixedLength < sourceLength ? source.typeArguments!.slice(fixedLength, sourceLength) : []; + const types = fixedLength < sourceLength ? (source).typeArguments!.slice(fixedLength, sourceLength) : []; if (sourceRestType) { types.push(sourceRestType); } @@ -17694,14 +17694,28 @@ namespace ts { // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. function getApparentTypeOfContextualType(node: Expression): Type | undefined { - let contextualType = getContextualType(node); - contextualType = contextualType && mapType(contextualType, getApparentType); - if (contextualType && contextualType.flags & TypeFlags.Union) { - if (isObjectLiteralExpression(node)) { - return discriminateContextualTypeByObjectMembers(node, contextualType as UnionType); + const contextualType = instantiateContextualType(getContextualType(node), node); + if (contextualType) { + const apparentType = mapType(contextualType, getApparentType); + if (apparentType.flags & TypeFlags.Union) { + if (isObjectLiteralExpression(node)) { + return discriminateContextualTypeByObjectMembers(node, apparentType as UnionType); + } + else if (isJsxAttributes(node)) { + return discriminateContextualTypeByJSXAttributes(node, apparentType as UnionType); + } } - else if (isJsxAttributes(node)) { - return discriminateContextualTypeByJSXAttributes(node, contextualType as UnionType); + return apparentType; + } + } + + // If the given contextual type constains instantiable types and if a mapper representing + // return type inferences is available, instantiate those types using that mapper. + function instantiateContextualType(contextualType: Type | undefined, node: Expression): Type | undefined { + if (contextualType && maybeTypeOfKind(contextualType, TypeFlags.Instantiable)) { + const returnMapper = (getContextualMapper(node)).returnMapper; + if (returnMapper) { + return mapType(contextualType, t => t.flags & TypeFlags.Instantiable ? instantiateType(t, returnMapper) : t); } } return contextualType; @@ -19847,6 +19861,9 @@ namespace ts { const inferenceTargetType = getReturnTypeOfSignature(signature); // Inferences made from return types have lower priority than all other inferences. inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType); + // Create a type mapper for instantiating generic contextual types using the inferences made + // from the return type. + context.returnMapper = cloneTypeMapper(context); } } @@ -23022,12 +23039,9 @@ namespace ts { } function checkExpressionForMutableLocation(node: Expression, checkMode: CheckMode | undefined, contextualType?: Type, forceTuple?: boolean): Type { - if (arguments.length === 2) { - contextualType = getContextualType(node); - } const type = checkExpression(node, checkMode, forceTuple); return isTypeAssertion(node) ? type : - getWidenedLiteralLikeTypeForContextualType(type, contextualType); + getWidenedLiteralLikeTypeForContextualType(type, instantiateContextualType(arguments.length === 2 ? getContextualType(node) : contextualType, node)); } function checkPropertyAssignment(node: PropertyAssignment, checkMode?: CheckMode): Type { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c6c34c7434e..a2e1fe73798 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4364,6 +4364,7 @@ namespace ts { inferences: InferenceInfo[]; // Inferences made for each type parameter flags: InferenceFlags; // Inference flags compareTypes: TypeComparer; // Type comparer function + returnMapper?: TypeMapper; // Type mapper for inferences from return types (if any) } /* @internal */ From da9feca0b00ad2fb59ca23a0cbe882066521f4bb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 17 Jan 2019 14:38:04 -0800 Subject: [PATCH 08/42] Accept new baselines --- .../reference/errorMessagesIntersectionTypes02.errors.txt | 8 ++++---- .../reference/errorMessagesIntersectionTypes02.types | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/baselines/reference/errorMessagesIntersectionTypes02.errors.txt b/tests/baselines/reference/errorMessagesIntersectionTypes02.errors.txt index 6a9dd26706c..1225d3662cb 100644 --- a/tests/baselines/reference/errorMessagesIntersectionTypes02.errors.txt +++ b/tests/baselines/reference/errorMessagesIntersectionTypes02.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/errorMessagesIntersectionTypes02.ts(14,5): error TS2322: Type '{ fooProp: string; } & Bar' is not assignable to type 'FooBar'. +tests/cases/compiler/errorMessagesIntersectionTypes02.ts(14,5): error TS2322: Type '{ fooProp: "frizzlebizzle"; } & Bar' is not assignable to type 'FooBar'. Types of property 'fooProp' are incompatible. - Type 'string' is not assignable to type '"hello" | "world"'. + Type '"frizzlebizzle"' is not assignable to type '"hello" | "world"'. ==== tests/cases/compiler/errorMessagesIntersectionTypes02.ts (1 errors) ==== @@ -19,8 +19,8 @@ tests/cases/compiler/errorMessagesIntersectionTypes02.ts(14,5): error TS2322: Ty let fooBar: FooBar = mixBar({ ~~~~~~ -!!! error TS2322: Type '{ fooProp: string; } & Bar' is not assignable to type 'FooBar'. +!!! error TS2322: Type '{ fooProp: "frizzlebizzle"; } & Bar' is not assignable to type 'FooBar'. !!! error TS2322: Types of property 'fooProp' are incompatible. -!!! error TS2322: Type 'string' is not assignable to type '"hello" | "world"'. +!!! error TS2322: Type '"frizzlebizzle"' is not assignable to type '"hello" | "world"'. fooProp: "frizzlebizzle" }); \ No newline at end of file diff --git a/tests/baselines/reference/errorMessagesIntersectionTypes02.types b/tests/baselines/reference/errorMessagesIntersectionTypes02.types index ee21ee3ed91..f1aa28ca32e 100644 --- a/tests/baselines/reference/errorMessagesIntersectionTypes02.types +++ b/tests/baselines/reference/errorMessagesIntersectionTypes02.types @@ -18,12 +18,12 @@ declare function mixBar(obj: T): T & Bar; let fooBar: FooBar = mixBar({ >fooBar : FooBar ->mixBar({ fooProp: "frizzlebizzle"}) : { fooProp: string; } & Bar +>mixBar({ fooProp: "frizzlebizzle"}) : { fooProp: "frizzlebizzle"; } & Bar >mixBar : (obj: T) => T & Bar ->{ fooProp: "frizzlebizzle"} : { fooProp: string; } +>{ fooProp: "frizzlebizzle"} : { fooProp: "frizzlebizzle"; } fooProp: "frizzlebizzle" ->fooProp : string +>fooProp : "frizzlebizzle" >"frizzlebizzle" : "frizzlebizzle" }); From bb1c91fac6945481e0a56cebce98b855482377e4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 17 Jan 2019 17:04:29 -0800 Subject: [PATCH 09/42] Remove literal freshness when contextual type is a literal type --- src/compiler/checker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 352a5c31592..f66667d2ddc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22962,7 +22962,9 @@ namespace ts { context.contextualMapper = contextualMapper; const checkMode = contextualMapper === identityMapper ? CheckMode.SkipContextSensitive : contextualMapper ? CheckMode.Inferential : CheckMode.Contextual; - const result = checkExpression(node, checkMode); + const type = checkExpression(node, checkMode); + const result = maybeTypeOfKind(type, TypeFlags.Literal) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ? + getRegularTypeOfLiteralType(type) : type; context.contextualType = saveContextualType; context.contextualMapper = saveContextualMapper; return result; From 4163d2dee4d78e26e831f9c369515fd1028d7cde Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 17 Jan 2019 17:16:52 -0800 Subject: [PATCH 10/42] Add tests --- .../inferFromGenericFunctionReturnTypes3.ts | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts diff --git a/tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts b/tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts new file mode 100644 index 00000000000..e44e7c4a5e0 --- /dev/null +++ b/tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts @@ -0,0 +1,174 @@ +// @strict: true +// @target: es6 +// @declaration: true + +// Repros from #5487 + +function truePromise(): Promise { + return Promise.resolve(true); +} + +interface Wrap { + value: T; +} + +function wrap(value: T): Wrap { + return { value }; +} + +function wrappedFoo(): Wrap<'foo'> { + return wrap('foo'); +} + +function wrapBar(value: 'bar'): Wrap<'bar'> { + return { value }; +} + +function wrappedBar(): Wrap<'bar'> { + const value = 'bar'; + const inferred = wrapBar(value); + const literal = wrapBar('bar'); + const value2: string = 'bar'; + const literal2 = wrapBar(value2); // Error + return wrap(value); +} + +function wrappedBaz(): Wrap<'baz'> { + const value: 'baz' = 'baz'; + return wrap(value); +} + +// Repro from #11152 + +interface FolderContentItem { + type: 'folder' | 'file'; +} + +let a: FolderContentItem[] = []; +a = [1, 2, 3, 4, 5].map(v => ({ type: 'folder' })); + +// Repro from #11312 + +let arr: Array<[number, number]> = [[1, 2]] + +let mappedArr: Array<[number, number]> = arr.map(([x, y]) => { + return [x, y]; +}) + +// Repro from #13594 + +export namespace DiagnosticSeverity { + export const Error = 1; + export const Warning = 2; + export const Information = 3; + export const Hint = 4; +} + +export type DiagnosticSeverity = 1 | 2 | 3 | 4; + +export interface Diagnostic { + severity?: DiagnosticSeverity; + code?: number | string; + source?: string; + message: string; +} + +function bug(): Diagnostic[] { + let values: any[] = []; + return values.map((value) => { + return { + severity: DiagnosticSeverity.Error, + message: 'message' + } + }); +} + +// Repro from #22870 + +function objectToMap(obj: any) { + return new Map(Object.keys(obj).map(key => [key, obj[key]])); +}; + +// Repro from #24352 + +interface Person { + phoneNumbers: { + __typename: 'PhoneNumber'; + }[]; +} + +function createPerson(): Person { + return { + phoneNumbers: [1].map(() => ({ + __typename: 'PhoneNumber' + })) + }; +} + +// Repro from #26621 + +type Box = { value: T }; +declare function box(value: T): Box; + +type WinCondition = + | { type: 'win', player: string } + | { type: 'draw' }; + +let zz: Box = box({ type: 'draw' }); + +type WinType = 'win' | 'draw'; + +let yy: Box = box('draw'); + +// Repro from #27074 + +interface OK { + kind: "OK"; + value: T; +} +export function ok(value: T): OK { + return { + kind: "OK", + value: value + }; +} + +let result: OK<[string, number]> = ok(["hello", 12]); + +// Repro from #25889 + +interface I { + code: 'mapped', + name: string, +} + +const a3: I[] = ['a', 'b'].map(name => { + return { + code: 'mapped', + name, + } +}); + +// Repro from https://www.memsql.com/blog/porting-30k-lines-of-code-from-flow-to-typescript/ + +type Player = { + name: string; + age: number; + position: "STRIKER" | "GOALKEEPER", +}; + +type F = () => Promise>; + +const f1: F = () => { + return Promise.all([ + { + name: "David Gomes", + age: 23, + position: "GOALKEEPER", + }, { + name: "Cristiano Ronaldo", + age: 33, + position: "STRIKER", + } + ]); +}; From c809002bd3d07df7b6b60893a940c3079c4338fc Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 17 Jan 2019 17:17:03 -0800 Subject: [PATCH 11/42] Accept new baselines --- ...FromGenericFunctionReturnTypes3.errors.txt | 177 +++++++ .../inferFromGenericFunctionReturnTypes3.js | 285 +++++++++++ ...ferFromGenericFunctionReturnTypes3.symbols | 409 ++++++++++++++++ ...inferFromGenericFunctionReturnTypes3.types | 452 ++++++++++++++++++ 4 files changed, 1323 insertions(+) create mode 100644 tests/baselines/reference/inferFromGenericFunctionReturnTypes3.errors.txt create mode 100644 tests/baselines/reference/inferFromGenericFunctionReturnTypes3.js create mode 100644 tests/baselines/reference/inferFromGenericFunctionReturnTypes3.symbols create mode 100644 tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.errors.txt b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.errors.txt new file mode 100644 index 00000000000..9a0d64c1a56 --- /dev/null +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.errors.txt @@ -0,0 +1,177 @@ +tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts(28,30): error TS2345: Argument of type 'string' is not assignable to parameter of type '"bar"'. + + +==== tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts (1 errors) ==== + // Repros from #5487 + + function truePromise(): Promise { + return Promise.resolve(true); + } + + interface Wrap { + value: T; + } + + function wrap(value: T): Wrap { + return { value }; + } + + function wrappedFoo(): Wrap<'foo'> { + return wrap('foo'); + } + + function wrapBar(value: 'bar'): Wrap<'bar'> { + return { value }; + } + + function wrappedBar(): Wrap<'bar'> { + const value = 'bar'; + const inferred = wrapBar(value); + const literal = wrapBar('bar'); + const value2: string = 'bar'; + const literal2 = wrapBar(value2); // Error + ~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type '"bar"'. + return wrap(value); + } + + function wrappedBaz(): Wrap<'baz'> { + const value: 'baz' = 'baz'; + return wrap(value); + } + + // Repro from #11152 + + interface FolderContentItem { + type: 'folder' | 'file'; + } + + let a: FolderContentItem[] = []; + a = [1, 2, 3, 4, 5].map(v => ({ type: 'folder' })); + + // Repro from #11312 + + let arr: Array<[number, number]> = [[1, 2]] + + let mappedArr: Array<[number, number]> = arr.map(([x, y]) => { + return [x, y]; + }) + + // Repro from #13594 + + export namespace DiagnosticSeverity { + export const Error = 1; + export const Warning = 2; + export const Information = 3; + export const Hint = 4; + } + + export type DiagnosticSeverity = 1 | 2 | 3 | 4; + + export interface Diagnostic { + severity?: DiagnosticSeverity; + code?: number | string; + source?: string; + message: string; + } + + function bug(): Diagnostic[] { + let values: any[] = []; + return values.map((value) => { + return { + severity: DiagnosticSeverity.Error, + message: 'message' + } + }); + } + + // Repro from #22870 + + function objectToMap(obj: any) { + return new Map(Object.keys(obj).map(key => [key, obj[key]])); + }; + + // Repro from #24352 + + interface Person { + phoneNumbers: { + __typename: 'PhoneNumber'; + }[]; + } + + function createPerson(): Person { + return { + phoneNumbers: [1].map(() => ({ + __typename: 'PhoneNumber' + })) + }; + } + + // Repro from #26621 + + type Box = { value: T }; + declare function box(value: T): Box; + + type WinCondition = + | { type: 'win', player: string } + | { type: 'draw' }; + + let zz: Box = box({ type: 'draw' }); + + type WinType = 'win' | 'draw'; + + let yy: Box = box('draw'); + + // Repro from #27074 + + interface OK { + kind: "OK"; + value: T; + } + export function ok(value: T): OK { + return { + kind: "OK", + value: value + }; + } + + let result: OK<[string, number]> = ok(["hello", 12]); + + // Repro from #25889 + + interface I { + code: 'mapped', + name: string, + } + + const a3: I[] = ['a', 'b'].map(name => { + return { + code: 'mapped', + name, + } + }); + + // Repro from https://www.memsql.com/blog/porting-30k-lines-of-code-from-flow-to-typescript/ + + type Player = { + name: string; + age: number; + position: "STRIKER" | "GOALKEEPER", + }; + + type F = () => Promise>; + + const f1: F = () => { + return Promise.all([ + { + name: "David Gomes", + age: 23, + position: "GOALKEEPER", + }, { + name: "Cristiano Ronaldo", + age: 33, + position: "STRIKER", + } + ]); + }; + \ No newline at end of file diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.js b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.js new file mode 100644 index 00000000000..ca1533bbab1 --- /dev/null +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.js @@ -0,0 +1,285 @@ +//// [inferFromGenericFunctionReturnTypes3.ts] +// Repros from #5487 + +function truePromise(): Promise { + return Promise.resolve(true); +} + +interface Wrap { + value: T; +} + +function wrap(value: T): Wrap { + return { value }; +} + +function wrappedFoo(): Wrap<'foo'> { + return wrap('foo'); +} + +function wrapBar(value: 'bar'): Wrap<'bar'> { + return { value }; +} + +function wrappedBar(): Wrap<'bar'> { + const value = 'bar'; + const inferred = wrapBar(value); + const literal = wrapBar('bar'); + const value2: string = 'bar'; + const literal2 = wrapBar(value2); // Error + return wrap(value); +} + +function wrappedBaz(): Wrap<'baz'> { + const value: 'baz' = 'baz'; + return wrap(value); +} + +// Repro from #11152 + +interface FolderContentItem { + type: 'folder' | 'file'; +} + +let a: FolderContentItem[] = []; +a = [1, 2, 3, 4, 5].map(v => ({ type: 'folder' })); + +// Repro from #11312 + +let arr: Array<[number, number]> = [[1, 2]] + +let mappedArr: Array<[number, number]> = arr.map(([x, y]) => { + return [x, y]; +}) + +// Repro from #13594 + +export namespace DiagnosticSeverity { + export const Error = 1; + export const Warning = 2; + export const Information = 3; + export const Hint = 4; +} + +export type DiagnosticSeverity = 1 | 2 | 3 | 4; + +export interface Diagnostic { + severity?: DiagnosticSeverity; + code?: number | string; + source?: string; + message: string; +} + +function bug(): Diagnostic[] { + let values: any[] = []; + return values.map((value) => { + return { + severity: DiagnosticSeverity.Error, + message: 'message' + } + }); +} + +// Repro from #22870 + +function objectToMap(obj: any) { + return new Map(Object.keys(obj).map(key => [key, obj[key]])); +}; + +// Repro from #24352 + +interface Person { + phoneNumbers: { + __typename: 'PhoneNumber'; + }[]; +} + +function createPerson(): Person { + return { + phoneNumbers: [1].map(() => ({ + __typename: 'PhoneNumber' + })) + }; +} + +// Repro from #26621 + +type Box = { value: T }; +declare function box(value: T): Box; + +type WinCondition = + | { type: 'win', player: string } + | { type: 'draw' }; + +let zz: Box = box({ type: 'draw' }); + +type WinType = 'win' | 'draw'; + +let yy: Box = box('draw'); + +// Repro from #27074 + +interface OK { + kind: "OK"; + value: T; +} +export function ok(value: T): OK { + return { + kind: "OK", + value: value + }; +} + +let result: OK<[string, number]> = ok(["hello", 12]); + +// Repro from #25889 + +interface I { + code: 'mapped', + name: string, +} + +const a3: I[] = ['a', 'b'].map(name => { + return { + code: 'mapped', + name, + } +}); + +// Repro from https://www.memsql.com/blog/porting-30k-lines-of-code-from-flow-to-typescript/ + +type Player = { + name: string; + age: number; + position: "STRIKER" | "GOALKEEPER", +}; + +type F = () => Promise>; + +const f1: F = () => { + return Promise.all([ + { + name: "David Gomes", + age: 23, + position: "GOALKEEPER", + }, { + name: "Cristiano Ronaldo", + age: 33, + position: "STRIKER", + } + ]); +}; + + +//// [inferFromGenericFunctionReturnTypes3.js] +// Repros from #5487 +function truePromise() { + return Promise.resolve(true); +} +function wrap(value) { + return { value }; +} +function wrappedFoo() { + return wrap('foo'); +} +function wrapBar(value) { + return { value }; +} +function wrappedBar() { + const value = 'bar'; + const inferred = wrapBar(value); + const literal = wrapBar('bar'); + const value2 = 'bar'; + const literal2 = wrapBar(value2); // Error + return wrap(value); +} +function wrappedBaz() { + const value = 'baz'; + return wrap(value); +} +let a = []; +a = [1, 2, 3, 4, 5].map(v => ({ type: 'folder' })); +// Repro from #11312 +let arr = [[1, 2]]; +let mappedArr = arr.map(([x, y]) => { + return [x, y]; +}); +// Repro from #13594 +export var DiagnosticSeverity; +(function (DiagnosticSeverity) { + DiagnosticSeverity.Error = 1; + DiagnosticSeverity.Warning = 2; + DiagnosticSeverity.Information = 3; + DiagnosticSeverity.Hint = 4; +})(DiagnosticSeverity || (DiagnosticSeverity = {})); +function bug() { + let values = []; + return values.map((value) => { + return { + severity: DiagnosticSeverity.Error, + message: 'message' + }; + }); +} +// Repro from #22870 +function objectToMap(obj) { + return new Map(Object.keys(obj).map(key => [key, obj[key]])); +} +; +function createPerson() { + return { + phoneNumbers: [1].map(() => ({ + __typename: 'PhoneNumber' + })) + }; +} +let zz = box({ type: 'draw' }); +let yy = box('draw'); +export function ok(value) { + return { + kind: "OK", + value: value + }; +} +let result = ok(["hello", 12]); +const a3 = ['a', 'b'].map(name => { + return { + code: 'mapped', + name, + }; +}); +const f1 = () => { + return Promise.all([ + { + name: "David Gomes", + age: 23, + position: "GOALKEEPER", + }, { + name: "Cristiano Ronaldo", + age: 33, + position: "STRIKER", + } + ]); +}; + + +//// [inferFromGenericFunctionReturnTypes3.d.ts] +export declare namespace DiagnosticSeverity { + const Error = 1; + const Warning = 2; + const Information = 3; + const Hint = 4; +} +export declare type DiagnosticSeverity = 1 | 2 | 3 | 4; +export interface Diagnostic { + severity?: DiagnosticSeverity; + code?: number | string; + source?: string; + message: string; +} +interface OK { + kind: "OK"; + value: T; +} +export declare function ok(value: T): OK; +export {}; diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.symbols b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.symbols new file mode 100644 index 00000000000..16beb0546de --- /dev/null +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.symbols @@ -0,0 +1,409 @@ +=== tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts === +// Repros from #5487 + +function truePromise(): Promise { +>truePromise : Symbol(truePromise, Decl(inferFromGenericFunctionReturnTypes3.ts, 0, 0)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + return Promise.resolve(true); +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +} + +interface Wrap { +>Wrap : Symbol(Wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 4, 1)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 6, 15)) + + value: T; +>value : Symbol(Wrap.value, Decl(inferFromGenericFunctionReturnTypes3.ts, 6, 19)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 6, 15)) +} + +function wrap(value: T): Wrap { +>wrap : Symbol(wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 8, 1)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 10, 14)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 10, 17)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 10, 14)) +>Wrap : Symbol(Wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 4, 1)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 10, 14)) + + return { value }; +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 11, 12)) +} + +function wrappedFoo(): Wrap<'foo'> { +>wrappedFoo : Symbol(wrappedFoo, Decl(inferFromGenericFunctionReturnTypes3.ts, 12, 1)) +>Wrap : Symbol(Wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 4, 1)) + + return wrap('foo'); +>wrap : Symbol(wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 8, 1)) +} + +function wrapBar(value: 'bar'): Wrap<'bar'> { +>wrapBar : Symbol(wrapBar, Decl(inferFromGenericFunctionReturnTypes3.ts, 16, 1)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 18, 17)) +>Wrap : Symbol(Wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 4, 1)) + + return { value }; +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 19, 12)) +} + +function wrappedBar(): Wrap<'bar'> { +>wrappedBar : Symbol(wrappedBar, Decl(inferFromGenericFunctionReturnTypes3.ts, 20, 1)) +>Wrap : Symbol(Wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 4, 1)) + + const value = 'bar'; +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 23, 9)) + + const inferred = wrapBar(value); +>inferred : Symbol(inferred, Decl(inferFromGenericFunctionReturnTypes3.ts, 24, 9)) +>wrapBar : Symbol(wrapBar, Decl(inferFromGenericFunctionReturnTypes3.ts, 16, 1)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 23, 9)) + + const literal = wrapBar('bar'); +>literal : Symbol(literal, Decl(inferFromGenericFunctionReturnTypes3.ts, 25, 9)) +>wrapBar : Symbol(wrapBar, Decl(inferFromGenericFunctionReturnTypes3.ts, 16, 1)) + + const value2: string = 'bar'; +>value2 : Symbol(value2, Decl(inferFromGenericFunctionReturnTypes3.ts, 26, 9)) + + const literal2 = wrapBar(value2); // Error +>literal2 : Symbol(literal2, Decl(inferFromGenericFunctionReturnTypes3.ts, 27, 9)) +>wrapBar : Symbol(wrapBar, Decl(inferFromGenericFunctionReturnTypes3.ts, 16, 1)) +>value2 : Symbol(value2, Decl(inferFromGenericFunctionReturnTypes3.ts, 26, 9)) + + return wrap(value); +>wrap : Symbol(wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 8, 1)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 23, 9)) +} + +function wrappedBaz(): Wrap<'baz'> { +>wrappedBaz : Symbol(wrappedBaz, Decl(inferFromGenericFunctionReturnTypes3.ts, 29, 1)) +>Wrap : Symbol(Wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 4, 1)) + + const value: 'baz' = 'baz'; +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 32, 9)) + + return wrap(value); +>wrap : Symbol(wrap, Decl(inferFromGenericFunctionReturnTypes3.ts, 8, 1)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 32, 9)) +} + +// Repro from #11152 + +interface FolderContentItem { +>FolderContentItem : Symbol(FolderContentItem, Decl(inferFromGenericFunctionReturnTypes3.ts, 34, 1)) + + type: 'folder' | 'file'; +>type : Symbol(FolderContentItem.type, Decl(inferFromGenericFunctionReturnTypes3.ts, 38, 29)) +} + +let a: FolderContentItem[] = []; +>a : Symbol(a, Decl(inferFromGenericFunctionReturnTypes3.ts, 42, 3)) +>FolderContentItem : Symbol(FolderContentItem, Decl(inferFromGenericFunctionReturnTypes3.ts, 34, 1)) + +a = [1, 2, 3, 4, 5].map(v => ({ type: 'folder' })); +>a : Symbol(a, Decl(inferFromGenericFunctionReturnTypes3.ts, 42, 3)) +>[1, 2, 3, 4, 5].map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>v : Symbol(v, Decl(inferFromGenericFunctionReturnTypes3.ts, 43, 24)) +>type : Symbol(type, Decl(inferFromGenericFunctionReturnTypes3.ts, 43, 31)) + +// Repro from #11312 + +let arr: Array<[number, number]> = [[1, 2]] +>arr : Symbol(arr, Decl(inferFromGenericFunctionReturnTypes3.ts, 47, 3)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +let mappedArr: Array<[number, number]> = arr.map(([x, y]) => { +>mappedArr : Symbol(mappedArr, Decl(inferFromGenericFunctionReturnTypes3.ts, 49, 3)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>arr.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>arr : Symbol(arr, Decl(inferFromGenericFunctionReturnTypes3.ts, 47, 3)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(inferFromGenericFunctionReturnTypes3.ts, 49, 51)) +>y : Symbol(y, Decl(inferFromGenericFunctionReturnTypes3.ts, 49, 53)) + + return [x, y]; +>x : Symbol(x, Decl(inferFromGenericFunctionReturnTypes3.ts, 49, 51)) +>y : Symbol(y, Decl(inferFromGenericFunctionReturnTypes3.ts, 49, 53)) + +}) + +// Repro from #13594 + +export namespace DiagnosticSeverity { +>DiagnosticSeverity : Symbol(DiagnosticSeverity, Decl(inferFromGenericFunctionReturnTypes3.ts, 51, 2), Decl(inferFromGenericFunctionReturnTypes3.ts, 60, 1)) + + export const Error = 1; +>Error : Symbol(Error, Decl(inferFromGenericFunctionReturnTypes3.ts, 56, 13)) + + export const Warning = 2; +>Warning : Symbol(Warning, Decl(inferFromGenericFunctionReturnTypes3.ts, 57, 13)) + + export const Information = 3; +>Information : Symbol(Information, Decl(inferFromGenericFunctionReturnTypes3.ts, 58, 13)) + + export const Hint = 4; +>Hint : Symbol(Hint, Decl(inferFromGenericFunctionReturnTypes3.ts, 59, 13)) +} + +export type DiagnosticSeverity = 1 | 2 | 3 | 4; +>DiagnosticSeverity : Symbol(DiagnosticSeverity, Decl(inferFromGenericFunctionReturnTypes3.ts, 51, 2), Decl(inferFromGenericFunctionReturnTypes3.ts, 60, 1)) + +export interface Diagnostic { +>Diagnostic : Symbol(Diagnostic, Decl(inferFromGenericFunctionReturnTypes3.ts, 62, 47)) + + severity?: DiagnosticSeverity; +>severity : Symbol(Diagnostic.severity, Decl(inferFromGenericFunctionReturnTypes3.ts, 64, 29)) +>DiagnosticSeverity : Symbol(DiagnosticSeverity, Decl(inferFromGenericFunctionReturnTypes3.ts, 51, 2), Decl(inferFromGenericFunctionReturnTypes3.ts, 60, 1)) + + code?: number | string; +>code : Symbol(Diagnostic.code, Decl(inferFromGenericFunctionReturnTypes3.ts, 65, 31)) + + source?: string; +>source : Symbol(Diagnostic.source, Decl(inferFromGenericFunctionReturnTypes3.ts, 66, 24)) + + message: string; +>message : Symbol(Diagnostic.message, Decl(inferFromGenericFunctionReturnTypes3.ts, 67, 17)) +} + +function bug(): Diagnostic[] { +>bug : Symbol(bug, Decl(inferFromGenericFunctionReturnTypes3.ts, 69, 1)) +>Diagnostic : Symbol(Diagnostic, Decl(inferFromGenericFunctionReturnTypes3.ts, 62, 47)) + + let values: any[] = []; +>values : Symbol(values, Decl(inferFromGenericFunctionReturnTypes3.ts, 72, 4)) + + return values.map((value) => { +>values.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>values : Symbol(values, Decl(inferFromGenericFunctionReturnTypes3.ts, 72, 4)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 73, 20)) + + return { + severity: DiagnosticSeverity.Error, +>severity : Symbol(severity, Decl(inferFromGenericFunctionReturnTypes3.ts, 74, 10)) +>DiagnosticSeverity.Error : Symbol(DiagnosticSeverity.Error, Decl(inferFromGenericFunctionReturnTypes3.ts, 56, 13)) +>DiagnosticSeverity : Symbol(DiagnosticSeverity, Decl(inferFromGenericFunctionReturnTypes3.ts, 51, 2), Decl(inferFromGenericFunctionReturnTypes3.ts, 60, 1)) +>Error : Symbol(DiagnosticSeverity.Error, Decl(inferFromGenericFunctionReturnTypes3.ts, 56, 13)) + + message: 'message' +>message : Symbol(message, Decl(inferFromGenericFunctionReturnTypes3.ts, 75, 38)) + } + }); +} + +// Repro from #22870 + +function objectToMap(obj: any) { +>objectToMap : Symbol(objectToMap, Decl(inferFromGenericFunctionReturnTypes3.ts, 79, 1)) +>obj : Symbol(obj, Decl(inferFromGenericFunctionReturnTypes3.ts, 83, 21)) + + return new Map(Object.keys(obj).map(key => [key, obj[key]])); +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Object.keys(obj).map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>Object.keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>keys : Symbol(ObjectConstructor.keys, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(inferFromGenericFunctionReturnTypes3.ts, 83, 21)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>key : Symbol(key, Decl(inferFromGenericFunctionReturnTypes3.ts, 84, 37)) +>key : Symbol(key, Decl(inferFromGenericFunctionReturnTypes3.ts, 84, 37)) +>obj : Symbol(obj, Decl(inferFromGenericFunctionReturnTypes3.ts, 83, 21)) +>key : Symbol(key, Decl(inferFromGenericFunctionReturnTypes3.ts, 84, 37)) + +}; + +// Repro from #24352 + +interface Person { +>Person : Symbol(Person, Decl(inferFromGenericFunctionReturnTypes3.ts, 85, 2)) + + phoneNumbers: { +>phoneNumbers : Symbol(Person.phoneNumbers, Decl(inferFromGenericFunctionReturnTypes3.ts, 89, 18)) + + __typename: 'PhoneNumber'; +>__typename : Symbol(__typename, Decl(inferFromGenericFunctionReturnTypes3.ts, 90, 17)) + + }[]; +} + +function createPerson(): Person { +>createPerson : Symbol(createPerson, Decl(inferFromGenericFunctionReturnTypes3.ts, 93, 1)) +>Person : Symbol(Person, Decl(inferFromGenericFunctionReturnTypes3.ts, 85, 2)) + + return { + phoneNumbers: [1].map(() => ({ +>phoneNumbers : Symbol(phoneNumbers, Decl(inferFromGenericFunctionReturnTypes3.ts, 96, 10)) +>[1].map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) + + __typename: 'PhoneNumber' +>__typename : Symbol(__typename, Decl(inferFromGenericFunctionReturnTypes3.ts, 97, 34)) + + })) + }; +} + +// Repro from #26621 + +type Box = { value: T }; +>Box : Symbol(Box, Decl(inferFromGenericFunctionReturnTypes3.ts, 101, 1)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 105, 9)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 105, 15)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 105, 9)) + +declare function box(value: T): Box; +>box : Symbol(box, Decl(inferFromGenericFunctionReturnTypes3.ts, 105, 27)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 106, 21)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 106, 24)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 106, 21)) +>Box : Symbol(Box, Decl(inferFromGenericFunctionReturnTypes3.ts, 101, 1)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 106, 21)) + +type WinCondition = +>WinCondition : Symbol(WinCondition, Decl(inferFromGenericFunctionReturnTypes3.ts, 106, 42)) + + | { type: 'win', player: string } +>type : Symbol(type, Decl(inferFromGenericFunctionReturnTypes3.ts, 109, 7)) +>player : Symbol(player, Decl(inferFromGenericFunctionReturnTypes3.ts, 109, 20)) + + | { type: 'draw' }; +>type : Symbol(type, Decl(inferFromGenericFunctionReturnTypes3.ts, 110, 7)) + +let zz: Box = box({ type: 'draw' }); +>zz : Symbol(zz, Decl(inferFromGenericFunctionReturnTypes3.ts, 112, 3)) +>Box : Symbol(Box, Decl(inferFromGenericFunctionReturnTypes3.ts, 101, 1)) +>WinCondition : Symbol(WinCondition, Decl(inferFromGenericFunctionReturnTypes3.ts, 106, 42)) +>box : Symbol(box, Decl(inferFromGenericFunctionReturnTypes3.ts, 105, 27)) +>type : Symbol(type, Decl(inferFromGenericFunctionReturnTypes3.ts, 112, 33)) + +type WinType = 'win' | 'draw'; +>WinType : Symbol(WinType, Decl(inferFromGenericFunctionReturnTypes3.ts, 112, 50)) + +let yy: Box = box('draw'); +>yy : Symbol(yy, Decl(inferFromGenericFunctionReturnTypes3.ts, 116, 3)) +>Box : Symbol(Box, Decl(inferFromGenericFunctionReturnTypes3.ts, 101, 1)) +>WinType : Symbol(WinType, Decl(inferFromGenericFunctionReturnTypes3.ts, 112, 50)) +>box : Symbol(box, Decl(inferFromGenericFunctionReturnTypes3.ts, 105, 27)) + +// Repro from #27074 + +interface OK { +>OK : Symbol(OK, Decl(inferFromGenericFunctionReturnTypes3.ts, 116, 35)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 120, 13)) + + kind: "OK"; +>kind : Symbol(OK.kind, Decl(inferFromGenericFunctionReturnTypes3.ts, 120, 17)) + + value: T; +>value : Symbol(OK.value, Decl(inferFromGenericFunctionReturnTypes3.ts, 121, 15)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 120, 13)) +} +export function ok(value: T): OK { +>ok : Symbol(ok, Decl(inferFromGenericFunctionReturnTypes3.ts, 123, 1)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 124, 19)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 124, 22)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 124, 19)) +>OK : Symbol(OK, Decl(inferFromGenericFunctionReturnTypes3.ts, 116, 35)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 124, 19)) + + return { + kind: "OK", +>kind : Symbol(kind, Decl(inferFromGenericFunctionReturnTypes3.ts, 125, 12)) + + value: value +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 126, 19)) +>value : Symbol(value, Decl(inferFromGenericFunctionReturnTypes3.ts, 124, 22)) + + }; +} + +let result: OK<[string, number]> = ok(["hello", 12]); +>result : Symbol(result, Decl(inferFromGenericFunctionReturnTypes3.ts, 131, 3)) +>OK : Symbol(OK, Decl(inferFromGenericFunctionReturnTypes3.ts, 116, 35)) +>ok : Symbol(ok, Decl(inferFromGenericFunctionReturnTypes3.ts, 123, 1)) + +// Repro from #25889 + +interface I { +>I : Symbol(I, Decl(inferFromGenericFunctionReturnTypes3.ts, 131, 53)) + + code: 'mapped', +>code : Symbol(I.code, Decl(inferFromGenericFunctionReturnTypes3.ts, 135, 13)) + + name: string, +>name : Symbol(I.name, Decl(inferFromGenericFunctionReturnTypes3.ts, 136, 19)) +} + +const a3: I[] = ['a', 'b'].map(name => { +>a3 : Symbol(a3, Decl(inferFromGenericFunctionReturnTypes3.ts, 140, 5)) +>I : Symbol(I, Decl(inferFromGenericFunctionReturnTypes3.ts, 131, 53)) +>['a', 'b'].map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>name : Symbol(name, Decl(inferFromGenericFunctionReturnTypes3.ts, 140, 31)) + + return { + code: 'mapped', +>code : Symbol(code, Decl(inferFromGenericFunctionReturnTypes3.ts, 141, 12)) + + name, +>name : Symbol(name, Decl(inferFromGenericFunctionReturnTypes3.ts, 142, 23)) + } +}); + +// Repro from https://www.memsql.com/blog/porting-30k-lines-of-code-from-flow-to-typescript/ + +type Player = { +>Player : Symbol(Player, Decl(inferFromGenericFunctionReturnTypes3.ts, 145, 3)) + + name: string; +>name : Symbol(name, Decl(inferFromGenericFunctionReturnTypes3.ts, 149, 15)) + + age: number; +>age : Symbol(age, Decl(inferFromGenericFunctionReturnTypes3.ts, 150, 17)) + + position: "STRIKER" | "GOALKEEPER", +>position : Symbol(position, Decl(inferFromGenericFunctionReturnTypes3.ts, 151, 16)) + +}; + +type F = () => Promise>; +>F : Symbol(F, Decl(inferFromGenericFunctionReturnTypes3.ts, 153, 2)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Player : Symbol(Player, Decl(inferFromGenericFunctionReturnTypes3.ts, 145, 3)) + +const f1: F = () => { +>f1 : Symbol(f1, Decl(inferFromGenericFunctionReturnTypes3.ts, 157, 5)) +>F : Symbol(F, Decl(inferFromGenericFunctionReturnTypes3.ts, 153, 2)) + + return Promise.all([ +>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --) ... and 6 more) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --) ... and 6 more) + { + name: "David Gomes", +>name : Symbol(name, Decl(inferFromGenericFunctionReturnTypes3.ts, 159, 9)) + + age: 23, +>age : Symbol(age, Decl(inferFromGenericFunctionReturnTypes3.ts, 160, 32)) + + position: "GOALKEEPER", +>position : Symbol(position, Decl(inferFromGenericFunctionReturnTypes3.ts, 161, 20)) + + }, { + name: "Cristiano Ronaldo", +>name : Symbol(name, Decl(inferFromGenericFunctionReturnTypes3.ts, 163, 12)) + + age: 33, +>age : Symbol(age, Decl(inferFromGenericFunctionReturnTypes3.ts, 164, 38)) + + position: "STRIKER", +>position : Symbol(position, Decl(inferFromGenericFunctionReturnTypes3.ts, 165, 20)) + } + ]); +}; + diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types new file mode 100644 index 00000000000..e983cc64819 --- /dev/null +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types @@ -0,0 +1,452 @@ +=== tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts === +// Repros from #5487 + +function truePromise(): Promise { +>truePromise : () => Promise +>true : true + + return Promise.resolve(true); +>Promise.resolve(true) : Promise +>Promise.resolve : { (value: T | PromiseLike): Promise; (): Promise; } +>Promise : PromiseConstructor +>resolve : { (value: T | PromiseLike): Promise; (): Promise; } +>true : true +} + +interface Wrap { + value: T; +>value : T +} + +function wrap(value: T): Wrap { +>wrap : (value: T) => Wrap +>value : T + + return { value }; +>{ value } : { value: T; } +>value : T +} + +function wrappedFoo(): Wrap<'foo'> { +>wrappedFoo : () => Wrap<"foo"> + + return wrap('foo'); +>wrap('foo') : Wrap<"foo"> +>wrap : (value: T) => Wrap +>'foo' : "foo" +} + +function wrapBar(value: 'bar'): Wrap<'bar'> { +>wrapBar : (value: "bar") => Wrap<"bar"> +>value : "bar" + + return { value }; +>{ value } : { value: "bar"; } +>value : "bar" +} + +function wrappedBar(): Wrap<'bar'> { +>wrappedBar : () => Wrap<"bar"> + + const value = 'bar'; +>value : "bar" +>'bar' : "bar" + + const inferred = wrapBar(value); +>inferred : Wrap<"bar"> +>wrapBar(value) : Wrap<"bar"> +>wrapBar : (value: "bar") => Wrap<"bar"> +>value : "bar" + + const literal = wrapBar('bar'); +>literal : Wrap<"bar"> +>wrapBar('bar') : Wrap<"bar"> +>wrapBar : (value: "bar") => Wrap<"bar"> +>'bar' : "bar" + + const value2: string = 'bar'; +>value2 : string +>'bar' : "bar" + + const literal2 = wrapBar(value2); // Error +>literal2 : Wrap<"bar"> +>wrapBar(value2) : Wrap<"bar"> +>wrapBar : (value: "bar") => Wrap<"bar"> +>value2 : string + + return wrap(value); +>wrap(value) : Wrap<"bar"> +>wrap : (value: T) => Wrap +>value : "bar" +} + +function wrappedBaz(): Wrap<'baz'> { +>wrappedBaz : () => Wrap<"baz"> + + const value: 'baz' = 'baz'; +>value : "baz" +>'baz' : "baz" + + return wrap(value); +>wrap(value) : Wrap<"baz"> +>wrap : (value: T) => Wrap +>value : "baz" +} + +// Repro from #11152 + +interface FolderContentItem { + type: 'folder' | 'file'; +>type : "folder" | "file" +} + +let a: FolderContentItem[] = []; +>a : FolderContentItem[] +>[] : never[] + +a = [1, 2, 3, 4, 5].map(v => ({ type: 'folder' })); +>a = [1, 2, 3, 4, 5].map(v => ({ type: 'folder' })) : { type: "folder"; }[] +>a : FolderContentItem[] +>[1, 2, 3, 4, 5].map(v => ({ type: 'folder' })) : { type: "folder"; }[] +>[1, 2, 3, 4, 5].map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] +>[1, 2, 3, 4, 5] : number[] +>1 : 1 +>2 : 2 +>3 : 3 +>4 : 4 +>5 : 5 +>map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] +>v => ({ type: 'folder' }) : (v: number) => { type: "folder"; } +>v : number +>({ type: 'folder' }) : { type: "folder"; } +>{ type: 'folder' } : { type: "folder"; } +>type : "folder" +>'folder' : "folder" + +// Repro from #11312 + +let arr: Array<[number, number]> = [[1, 2]] +>arr : [number, number][] +>[[1, 2]] : [number, number][] +>[1, 2] : [number, number] +>1 : 1 +>2 : 2 + +let mappedArr: Array<[number, number]> = arr.map(([x, y]) => { +>mappedArr : [number, number][] +>arr.map(([x, y]) => { return [x, y];}) : [number, number][] +>arr.map : (callbackfn: (value: [number, number], index: number, array: [number, number][]) => U, thisArg?: any) => U[] +>arr : [number, number][] +>map : (callbackfn: (value: [number, number], index: number, array: [number, number][]) => U, thisArg?: any) => U[] +>([x, y]) => { return [x, y];} : ([x, y]: [number, number]) => [number, number] +>x : number +>y : number + + return [x, y]; +>[x, y] : [number, number] +>x : number +>y : number + +}) + +// Repro from #13594 + +export namespace DiagnosticSeverity { +>DiagnosticSeverity : typeof DiagnosticSeverity + + export const Error = 1; +>Error : 1 +>1 : 1 + + export const Warning = 2; +>Warning : 2 +>2 : 2 + + export const Information = 3; +>Information : 3 +>3 : 3 + + export const Hint = 4; +>Hint : 4 +>4 : 4 +} + +export type DiagnosticSeverity = 1 | 2 | 3 | 4; +>DiagnosticSeverity : DiagnosticSeverity + +export interface Diagnostic { + severity?: DiagnosticSeverity; +>severity : 1 | 2 | 3 | 4 | undefined + + code?: number | string; +>code : string | number | undefined + + source?: string; +>source : string | undefined + + message: string; +>message : string +} + +function bug(): Diagnostic[] { +>bug : () => Diagnostic[] + + let values: any[] = []; +>values : any[] +>[] : never[] + + return values.map((value) => { +>values.map((value) => { return { severity: DiagnosticSeverity.Error, message: 'message' } }) : { severity: 1; message: string; }[] +>values.map : (callbackfn: (value: any, index: number, array: any[]) => U, thisArg?: any) => U[] +>values : any[] +>map : (callbackfn: (value: any, index: number, array: any[]) => U, thisArg?: any) => U[] +>(value) => { return { severity: DiagnosticSeverity.Error, message: 'message' } } : (value: any) => { severity: 1; message: string; } +>value : any + + return { +>{ severity: DiagnosticSeverity.Error, message: 'message' } : { severity: 1; message: string; } + + severity: DiagnosticSeverity.Error, +>severity : 1 +>DiagnosticSeverity.Error : 1 +>DiagnosticSeverity : typeof DiagnosticSeverity +>Error : 1 + + message: 'message' +>message : string +>'message' : "message" + } + }); +} + +// Repro from #22870 + +function objectToMap(obj: any) { +>objectToMap : (obj: any) => Map +>obj : any + + return new Map(Object.keys(obj).map(key => [key, obj[key]])); +>new Map(Object.keys(obj).map(key => [key, obj[key]])) : Map +>Map : MapConstructor +>Object.keys(obj).map(key => [key, obj[key]]) : [string, any][] +>Object.keys(obj).map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>Object.keys(obj) : string[] +>Object.keys : (o: {}) => string[] +>Object : ObjectConstructor +>keys : (o: {}) => string[] +>obj : any +>map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>key => [key, obj[key]] : (key: string) => [string, any] +>key : string +>[key, obj[key]] : [string, any] +>key : string +>obj[key] : any +>obj : any +>key : string + +}; + +// Repro from #24352 + +interface Person { + phoneNumbers: { +>phoneNumbers : { __typename: "PhoneNumber"; }[] + + __typename: 'PhoneNumber'; +>__typename : "PhoneNumber" + + }[]; +} + +function createPerson(): Person { +>createPerson : () => Person + + return { +>{ phoneNumbers: [1].map(() => ({ __typename: 'PhoneNumber' })) } : { phoneNumbers: { __typename: "PhoneNumber"; }[]; } + + phoneNumbers: [1].map(() => ({ +>phoneNumbers : { __typename: "PhoneNumber"; }[] +>[1].map(() => ({ __typename: 'PhoneNumber' })) : { __typename: "PhoneNumber"; }[] +>[1].map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] +>[1] : number[] +>1 : 1 +>map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] +>() => ({ __typename: 'PhoneNumber' }) : () => { __typename: "PhoneNumber"; } +>({ __typename: 'PhoneNumber' }) : { __typename: "PhoneNumber"; } +>{ __typename: 'PhoneNumber' } : { __typename: "PhoneNumber"; } + + __typename: 'PhoneNumber' +>__typename : "PhoneNumber" +>'PhoneNumber' : "PhoneNumber" + + })) + }; +} + +// Repro from #26621 + +type Box = { value: T }; +>Box : Box +>value : T + +declare function box(value: T): Box; +>box : (value: T) => Box +>value : T + +type WinCondition = +>WinCondition : WinCondition + + | { type: 'win', player: string } +>type : "win" +>player : string + + | { type: 'draw' }; +>type : "draw" + +let zz: Box = box({ type: 'draw' }); +>zz : Box +>box({ type: 'draw' }) : Box<{ type: "draw"; }> +>box : (value: T) => Box +>{ type: 'draw' } : { type: "draw"; } +>type : "draw" +>'draw' : "draw" + +type WinType = 'win' | 'draw'; +>WinType : "win" | "draw" + +let yy: Box = box('draw'); +>yy : Box<"win" | "draw"> +>box('draw') : Box<"draw"> +>box : (value: T) => Box +>'draw' : "draw" + +// Repro from #27074 + +interface OK { + kind: "OK"; +>kind : "OK" + + value: T; +>value : T +} +export function ok(value: T): OK { +>ok : (value: T) => OK +>value : T + + return { +>{ kind: "OK", value: value } : { kind: "OK"; value: T; } + + kind: "OK", +>kind : "OK" +>"OK" : "OK" + + value: value +>value : T +>value : T + + }; +} + +let result: OK<[string, number]> = ok(["hello", 12]); +>result : OK<[string, number]> +>ok(["hello", 12]) : OK<[string, number]> +>ok : (value: T) => OK +>["hello", 12] : [string, number] +>"hello" : "hello" +>12 : 12 + +// Repro from #25889 + +interface I { + code: 'mapped', +>code : "mapped" + + name: string, +>name : string +} + +const a3: I[] = ['a', 'b'].map(name => { +>a3 : I[] +>['a', 'b'].map(name => { return { code: 'mapped', name, }}) : { code: "mapped"; name: string; }[] +>['a', 'b'].map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>['a', 'b'] : string[] +>'a' : "a" +>'b' : "b" +>map : (callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[] +>name => { return { code: 'mapped', name, }} : (name: string) => { code: "mapped"; name: string; } +>name : string + + return { +>{ code: 'mapped', name, } : { code: "mapped"; name: string; } + + code: 'mapped', +>code : "mapped" +>'mapped' : "mapped" + + name, +>name : string + } +}); + +// Repro from https://www.memsql.com/blog/porting-30k-lines-of-code-from-flow-to-typescript/ + +type Player = { +>Player : Player + + name: string; +>name : string + + age: number; +>age : number + + position: "STRIKER" | "GOALKEEPER", +>position : "STRIKER" | "GOALKEEPER" + +}; + +type F = () => Promise>; +>F : F + +const f1: F = () => { +>f1 : F +>() => { return Promise.all([ { name: "David Gomes", age: 23, position: "GOALKEEPER", }, { name: "Cristiano Ronaldo", age: 33, position: "STRIKER", } ]);} : () => Promise<[{ name: string; age: number; position: "GOALKEEPER"; }, { name: string; age: number; position: "STRIKER"; }]> + + return Promise.all([ +>Promise.all([ { name: "David Gomes", age: 23, position: "GOALKEEPER", }, { name: "Cristiano Ronaldo", age: 33, position: "STRIKER", } ]) : Promise<[{ name: string; age: number; position: "GOALKEEPER"; }, { name: string; age: number; position: "STRIKER"; }]> +>Promise.all : { (values: Iterable>): Promise; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: (T | PromiseLike)[]): Promise; } +>Promise : PromiseConstructor +>all : { (values: Iterable>): Promise; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike, T10 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike, T9 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike, T8 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike, T7 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike, T6 | PromiseLike]): Promise<[T1, T2, T3, T4, T5, T6]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike, T5 | PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike, T4 | PromiseLike]): Promise<[T1, T2, T3, T4]>; (values: [T1 | PromiseLike, T2 | PromiseLike, T3 | PromiseLike]): Promise<[T1, T2, T3]>; (values: [T1 | PromiseLike, T2 | PromiseLike]): Promise<[T1, T2]>; (values: (T | PromiseLike)[]): Promise; } +>[ { name: "David Gomes", age: 23, position: "GOALKEEPER", }, { name: "Cristiano Ronaldo", age: 33, position: "STRIKER", } ] : [{ name: string; age: number; position: "GOALKEEPER"; }, { name: string; age: number; position: "STRIKER"; }] + { +>{ name: "David Gomes", age: 23, position: "GOALKEEPER", } : { name: string; age: number; position: "GOALKEEPER"; } + + name: "David Gomes", +>name : string +>"David Gomes" : "David Gomes" + + age: 23, +>age : number +>23 : 23 + + position: "GOALKEEPER", +>position : "GOALKEEPER" +>"GOALKEEPER" : "GOALKEEPER" + + }, { +>{ name: "Cristiano Ronaldo", age: 33, position: "STRIKER", } : { name: string; age: number; position: "STRIKER"; } + + name: "Cristiano Ronaldo", +>name : string +>"Cristiano Ronaldo" : "Cristiano Ronaldo" + + age: 33, +>age : number +>33 : 33 + + position: "STRIKER", +>position : "STRIKER" +>"STRIKER" : "STRIKER" + } + ]); +}; + From 0b366ce751784e6aaced01daa107b9c9770d2996 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 18 Jan 2019 14:47:58 -0800 Subject: [PATCH 12/42] Address CR feedback --- src/compiler/checker.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f66667d2ddc..c85b7457f73 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17715,12 +17715,28 @@ namespace ts { if (contextualType && maybeTypeOfKind(contextualType, TypeFlags.Instantiable)) { const returnMapper = (getContextualMapper(node)).returnMapper; if (returnMapper) { - return mapType(contextualType, t => t.flags & TypeFlags.Instantiable ? instantiateType(t, returnMapper) : t); + return instantiateInstantiableTypes(contextualType, returnMapper); } } return contextualType; } + // This function is similar to instantiateType, except (a) that it only instantiates types that + // are classified as instantiable (i.e. it doesn't instantiate object types), and (b) it performs + // no reductions on instantiated union types. + function instantiateInstantiableTypes(type: Type, mapper: TypeMapper): Type { + if (type.flags & TypeFlags.Instantiable) { + return instantiateType(type, mapper); + } + if (type.flags & TypeFlags.Union) { + getUnionType(map((type).types, t => instantiateInstantiableTypes(t, mapper)), UnionReduction.None); + } + if (type.flags & TypeFlags.Intersection) { + getIntersectionType(map((type).types, t => instantiateInstantiableTypes(t, mapper))); + } + return type; + } + /** * Woah! Do you really want to use this function? * @@ -22963,6 +22979,9 @@ namespace ts { const checkMode = contextualMapper === identityMapper ? CheckMode.SkipContextSensitive : contextualMapper ? CheckMode.Inferential : CheckMode.Contextual; const type = checkExpression(node, checkMode); + // We strip literal freshness when an appropriate contextual type is present such that contextually typed + // literals always preserve their literal types (otherwise they might widen during type inference). An alternative + // here would be to not mark contextually typed literals as fresh in the first place. const result = maybeTypeOfKind(type, TypeFlags.Literal) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ? getRegularTypeOfLiteralType(type) : type; context.contextualType = saveContextualType; From 0b1da02a62e3bb88611514840e6cc397ef33eab8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 18 Jan 2019 16:02:13 -0800 Subject: [PATCH 13/42] Add missing return statements (ugh) --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c85b7457f73..7ba3b2771c3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17729,10 +17729,10 @@ namespace ts { return instantiateType(type, mapper); } if (type.flags & TypeFlags.Union) { - getUnionType(map((type).types, t => instantiateInstantiableTypes(t, mapper)), UnionReduction.None); + return getUnionType(map((type).types, t => instantiateInstantiableTypes(t, mapper)), UnionReduction.None); } if (type.flags & TypeFlags.Intersection) { - getIntersectionType(map((type).types, t => instantiateInstantiableTypes(t, mapper))); + return getIntersectionType(map((type).types, t => instantiateInstantiableTypes(t, mapper))); } return type; } From 60e7528ee642a03708f9bda31d242d69a6271132 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 20 Jan 2019 08:20:40 -0800 Subject: [PATCH 14/42] No union type reductions in contextual types --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7ba3b2771c3..490453a6b40 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17696,7 +17696,7 @@ namespace ts { function getApparentTypeOfContextualType(node: Expression): Type | undefined { const contextualType = instantiateContextualType(getContextualType(node), node); if (contextualType) { - const apparentType = mapType(contextualType, getApparentType); + const apparentType = mapType(contextualType, getApparentType, /*noReductions*/ true); if (apparentType.flags & TypeFlags.Union) { if (isObjectLiteralExpression(node)) { return discriminateContextualTypeByObjectMembers(node, apparentType as UnionType); @@ -17709,7 +17709,7 @@ namespace ts { } } - // If the given contextual type constains instantiable types and if a mapper representing + // If the given contextual type contains instantiable types and if a mapper representing // return type inferences is available, instantiate those types using that mapper. function instantiateContextualType(contextualType: Type | undefined, node: Expression): Type | undefined { if (contextualType && maybeTypeOfKind(contextualType, TypeFlags.Instantiable)) { @@ -17721,7 +17721,7 @@ namespace ts { return contextualType; } - // This function is similar to instantiateType, except (a) that it only instantiates types that + // This function is similar to instantiateType, except that (a) it only instantiates types that // are classified as instantiable (i.e. it doesn't instantiate object types), and (b) it performs // no reductions on instantiated union types. function instantiateInstantiableTypes(type: Type, mapper: TypeMapper): Type { From dbea08f9c8be9c2aab63b01cb7c7ca114805aa37 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 20 Jan 2019 08:21:26 -0800 Subject: [PATCH 15/42] Accept new baselines --- .../reference/objectLiteralExcessProperties.errors.txt | 4 ++-- tests/baselines/reference/objectLiteralExcessProperties.types | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/objectLiteralExcessProperties.errors.txt b/tests/baselines/reference/objectLiteralExcessProperties.errors.txt index 4b034b06206..e4fc4d69fca 100644 --- a/tests/baselines/reference/objectLiteralExcessProperties.errors.txt +++ b/tests/baselines/reference/objectLiteralExcessProperties.errors.txt @@ -25,7 +25,7 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(37,25): error TS2304: Cann tests/cases/compiler/objectLiteralExcessProperties.ts(39,11): error TS2322: Type '{ name: string; }' is not assignable to type 'T'. tests/cases/compiler/objectLiteralExcessProperties.ts(41,11): error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type 'T & { prop: boolean; }'. Type '{ name: string; prop: boolean; }' is not assignable to type 'T'. -tests/cases/compiler/objectLiteralExcessProperties.ts(43,43): error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type 'T | { prop: boolean; }'. +tests/cases/compiler/objectLiteralExcessProperties.ts(43,43): error TS2322: Type '{ name: string; prop: true; }' is not assignable to type 'T | { prop: boolean; }'. Object literal may only specify known properties, and 'name' does not exist in type '{ prop: boolean; }'. tests/cases/compiler/objectLiteralExcessProperties.ts(45,76): error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type '{ name: string; } | (T & { prop: boolean; })'. Object literal may only specify known properties, and 'prop' does not exist in type '{ name: string; }'. @@ -119,7 +119,7 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(49,44): error TS2322: Type // Excess property checks only on non-generic parts of unions const obj3: T | { prop: boolean } = { name: "test", prop: true }; ~~~~~~~~~~~~ -!!! error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type 'T | { prop: boolean; }'. +!!! error TS2322: Type '{ name: string; prop: true; }' is not assignable to type 'T | { prop: boolean; }'. !!! error TS2322: Object literal may only specify known properties, and 'name' does not exist in type '{ prop: boolean; }'. // Excess property checks only on non-generic parts of unions const obj4: T & { prop: boolean } | { name: string } = { name: "test", prop: true }; diff --git a/tests/baselines/reference/objectLiteralExcessProperties.types b/tests/baselines/reference/objectLiteralExcessProperties.types index 8765432ab70..812f48c8904 100644 --- a/tests/baselines/reference/objectLiteralExcessProperties.types +++ b/tests/baselines/reference/objectLiteralExcessProperties.types @@ -124,10 +124,10 @@ function test() { const obj3: T | { prop: boolean } = { name: "test", prop: true }; >obj3 : T | { prop: boolean; } >prop : boolean ->{ name: "test", prop: true } : { name: string; prop: boolean; } +>{ name: "test", prop: true } : { name: string; prop: true; } >name : string >"test" : "test" ->prop : boolean +>prop : true >true : true // Excess property checks only on non-generic parts of unions From cf479fc384bad6f171927a4334954331d076003c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 20 Jan 2019 08:21:41 -0800 Subject: [PATCH 16/42] Add regression test for #29168 --- .../compiler/contextualTypeShouldBeLiteral.ts | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/cases/compiler/contextualTypeShouldBeLiteral.ts b/tests/cases/compiler/contextualTypeShouldBeLiteral.ts index 1012c567a71..5da49215f5f 100644 --- a/tests/cases/compiler/contextualTypeShouldBeLiteral.ts +++ b/tests/cases/compiler/contextualTypeShouldBeLiteral.ts @@ -93,4 +93,30 @@ let xyz: LikeA | LikeB = { } }; -xyz; \ No newline at end of file +xyz; + +// Repro from #29168 + +interface TestObject { + type?: 'object'; + items: { + [k: string]: TestGeneric; + }; +} + +interface TestString { + type: 'string'; +} + +type TestGeneric = (TestString | TestObject) & { [k: string]: any; }; + +const test: TestGeneric = { + items: { + hello: { type: 'string' }, + world: { + items: { + nested: { type: 'string' } + } + } + } +}; From 2ea02517091efd421e9085af8154a8cb1e3db741 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 20 Jan 2019 08:21:49 -0800 Subject: [PATCH 17/42] Accept new baselines --- .../contextualTypeShouldBeLiteral.js | 39 ++++++++++++- .../contextualTypeShouldBeLiteral.symbols | 56 +++++++++++++++++++ .../contextualTypeShouldBeLiteral.types | 56 +++++++++++++++++++ 3 files changed, 150 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/contextualTypeShouldBeLiteral.js b/tests/baselines/reference/contextualTypeShouldBeLiteral.js index dcb9da993c1..727609a5abd 100644 --- a/tests/baselines/reference/contextualTypeShouldBeLiteral.js +++ b/tests/baselines/reference/contextualTypeShouldBeLiteral.js @@ -93,7 +93,34 @@ let xyz: LikeA | LikeB = { } }; -xyz; +xyz; + +// Repro from #29168 + +interface TestObject { + type?: 'object'; + items: { + [k: string]: TestGeneric; + }; +} + +interface TestString { + type: 'string'; +} + +type TestGeneric = (TestString | TestObject) & { [k: string]: any; }; + +const test: TestGeneric = { + items: { + hello: { type: 'string' }, + world: { + items: { + nested: { type: 'string' } + } + } + } +}; + //// [contextualTypeShouldBeLiteral.js] "use strict"; @@ -134,3 +161,13 @@ var xyz = { } }; xyz; +var test = { + items: { + hello: { type: 'string' }, + world: { + items: { + nested: { type: 'string' } + } + } + } +}; diff --git a/tests/baselines/reference/contextualTypeShouldBeLiteral.symbols b/tests/baselines/reference/contextualTypeShouldBeLiteral.symbols index 314117b509d..a38443d4b02 100644 --- a/tests/baselines/reference/contextualTypeShouldBeLiteral.symbols +++ b/tests/baselines/reference/contextualTypeShouldBeLiteral.symbols @@ -227,3 +227,59 @@ let xyz: LikeA | LikeB = { xyz; >xyz : Symbol(xyz, Decl(contextualTypeShouldBeLiteral.ts, 82, 3)) +// Repro from #29168 + +interface TestObject { +>TestObject : Symbol(TestObject, Decl(contextualTypeShouldBeLiteral.ts, 94, 4)) + + type?: 'object'; +>type : Symbol(TestObject.type, Decl(contextualTypeShouldBeLiteral.ts, 98, 22)) + + items: { +>items : Symbol(TestObject.items, Decl(contextualTypeShouldBeLiteral.ts, 99, 18)) + + [k: string]: TestGeneric; +>k : Symbol(k, Decl(contextualTypeShouldBeLiteral.ts, 101, 5)) +>TestGeneric : Symbol(TestGeneric, Decl(contextualTypeShouldBeLiteral.ts, 107, 1)) + + }; +} + +interface TestString { +>TestString : Symbol(TestString, Decl(contextualTypeShouldBeLiteral.ts, 103, 1)) + + type: 'string'; +>type : Symbol(TestString.type, Decl(contextualTypeShouldBeLiteral.ts, 105, 22)) +} + +type TestGeneric = (TestString | TestObject) & { [k: string]: any; }; +>TestGeneric : Symbol(TestGeneric, Decl(contextualTypeShouldBeLiteral.ts, 107, 1)) +>TestString : Symbol(TestString, Decl(contextualTypeShouldBeLiteral.ts, 103, 1)) +>TestObject : Symbol(TestObject, Decl(contextualTypeShouldBeLiteral.ts, 94, 4)) +>k : Symbol(k, Decl(contextualTypeShouldBeLiteral.ts, 109, 50)) + +const test: TestGeneric = { +>test : Symbol(test, Decl(contextualTypeShouldBeLiteral.ts, 111, 5)) +>TestGeneric : Symbol(TestGeneric, Decl(contextualTypeShouldBeLiteral.ts, 107, 1)) + + items: { +>items : Symbol(items, Decl(contextualTypeShouldBeLiteral.ts, 111, 27)) + + hello: { type: 'string' }, +>hello : Symbol(hello, Decl(contextualTypeShouldBeLiteral.ts, 112, 10)) +>type : Symbol(type, Decl(contextualTypeShouldBeLiteral.ts, 113, 12)) + + world: { +>world : Symbol(world, Decl(contextualTypeShouldBeLiteral.ts, 113, 30)) + + items: { +>items : Symbol(items, Decl(contextualTypeShouldBeLiteral.ts, 114, 12)) + + nested: { type: 'string' } +>nested : Symbol(nested, Decl(contextualTypeShouldBeLiteral.ts, 115, 14)) +>type : Symbol(type, Decl(contextualTypeShouldBeLiteral.ts, 116, 17)) + } + } + } +}; + diff --git a/tests/baselines/reference/contextualTypeShouldBeLiteral.types b/tests/baselines/reference/contextualTypeShouldBeLiteral.types index a5867f0de42..d9795c7e33f 100644 --- a/tests/baselines/reference/contextualTypeShouldBeLiteral.types +++ b/tests/baselines/reference/contextualTypeShouldBeLiteral.types @@ -222,3 +222,59 @@ let xyz: LikeA | LikeB = { xyz; >xyz : LikeA +// Repro from #29168 + +interface TestObject { + type?: 'object'; +>type : "object" | undefined + + items: { +>items : { [k: string]: TestGeneric; } + + [k: string]: TestGeneric; +>k : string + + }; +} + +interface TestString { + type: 'string'; +>type : "string" +} + +type TestGeneric = (TestString | TestObject) & { [k: string]: any; }; +>TestGeneric : TestGeneric +>k : string + +const test: TestGeneric = { +>test : TestGeneric +>{ items: { hello: { type: 'string' }, world: { items: { nested: { type: 'string' } } } }} : { items: { hello: { type: "string"; }; world: { items: { nested: { type: "string"; }; }; }; }; } + + items: { +>items : { hello: { type: "string"; }; world: { items: { nested: { type: "string"; }; }; }; } +>{ hello: { type: 'string' }, world: { items: { nested: { type: 'string' } } } } : { hello: { type: "string"; }; world: { items: { nested: { type: "string"; }; }; }; } + + hello: { type: 'string' }, +>hello : { type: "string"; } +>{ type: 'string' } : { type: "string"; } +>type : "string" +>'string' : "string" + + world: { +>world : { items: { nested: { type: "string"; }; }; } +>{ items: { nested: { type: 'string' } } } : { items: { nested: { type: "string"; }; }; } + + items: { +>items : { nested: { type: "string"; }; } +>{ nested: { type: 'string' } } : { nested: { type: "string"; }; } + + nested: { type: 'string' } +>nested : { type: "string"; } +>{ type: 'string' } : { type: "string"; } +>type : "string" +>'string' : "string" + } + } + } +}; + From ddbac8f3fe87bb6044ceab2f68eacd81d7dd6977 Mon Sep 17 00:00:00 2001 From: xiaofa Date: Sat, 26 Jan 2019 23:59:32 +0800 Subject: [PATCH 18/42] get appropriate parent jsdoc node for arrow functions --- src/services/codefixes/inferFromUsage.ts | 12 +++++++++++- src/services/textChanges.ts | 4 +--- .../fourslash/codeFixInferFromUsageArrowJS.ts | 17 +++++++++++++---- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 8e5b962116d..f47f618f79d 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -274,7 +274,17 @@ namespace ts.codefix { return !!merged; })); const tag = createJSDocComment(comments.join("\n"), createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags])); - changes.insertJsdocCommentBefore(sourceFile, parent, tag); + const jsDocNode = parent.kind === SyntaxKind.ArrowFunction ? getJsDocNodeForArrowFunction(parent) : parent; + jsDocNode.jsDoc = parent.jsDoc; + jsDocNode.jsDocCache = parent.jsDocCache; + changes.insertJsdocCommentBefore(sourceFile, jsDocNode, tag); + } + + function getJsDocNodeForArrowFunction(signature: ArrowFunction): HasJSDoc { + if (signature.parent.kind === SyntaxKind.PropertyDeclaration) { + return signature.parent; + } + return signature.parent.parent; } function tryMergeJsdocTags(oldTag: JSDocTag, newTag: JSDocTag): JSDocTag | undefined { diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 7dab7205841..4689e18508c 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -340,9 +340,7 @@ namespace ts.textChanges { } public insertJsdocCommentBefore(sourceFile: SourceFile, node: HasJSDoc, tag: JSDoc): void { - const fnStart = node.kind === SyntaxKind.ArrowFunction - ? node.parent.parent.getStart(sourceFile) - : node.getStart(sourceFile); + const fnStart = node.getStart(sourceFile); if (node.jsDoc) { for (const jsdoc of node.jsDoc) { this.deleteRange(sourceFile, { diff --git a/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts b/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts index e867ae99c75..0a800fd7d63 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageArrowJS.ts @@ -6,13 +6,22 @@ // @Filename: test.js ////const foo = x => x.y + 1; +////class C { +//// m = x => x.y + 1; +////} -verify.codeFix({ - description: "Infer parameter types from usage", - index: 0, +verify.codeFixAll({ + fixId: "inferFromUsage", + fixAllDescription: "Infer all types from usage", newFileContent: `/** * @param {{ y: number; }} x */ -const foo = x => x.y + 1;`, +const foo = x => x.y + 1; +class C { + /** + * @param {{ y: number; }} x + */ + m = x => x.y + 1; +}`, }); \ No newline at end of file From 7a31706a9ff01cacd58ca7b5a7601940845b0439 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 30 Jan 2019 06:38:13 -0800 Subject: [PATCH 19/42] Only check constraints after type argument inference is complete --- src/compiler/checker.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ed65908d926..44f118b3a54 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14788,7 +14788,7 @@ namespace ts { return getWidenedType(unwidenedType); } - function getInferredType(context: InferenceContext, index: number): Type { + function getInferredType(context: InferenceContext, index: number, ignoreConstraints = false): Type { const inference = context.inferences[index]; let inferredType = inference.inferredType; if (!inferredType) { @@ -14836,11 +14836,13 @@ namespace ts { inference.inferredType = inferredType; - const constraint = getConstraintOfTypeParameter(inference.typeParameter); - if (constraint) { - const instantiatedConstraint = instantiateType(constraint, context); - if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { - inference.inferredType = inferredType = instantiatedConstraint; + if (!ignoreConstraints) { + const constraint = getConstraintOfTypeParameter(inference.typeParameter); + if (constraint) { + const instantiatedConstraint = instantiateType(constraint, context); + if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + inference.inferredType = inferredType = instantiatedConstraint; + } } } } @@ -14852,10 +14854,10 @@ namespace ts { return isInJavaScriptFile ? anyType : emptyObjectType; } - function getInferredTypes(context: InferenceContext): Type[] { + function getInferredTypes(context: InferenceContext, ignoreConstraints = false): Type[] { const result: Type[] = []; for (let i = 0; i < context.inferences.length; i++) { - result.push(getInferredType(context, i)); + result.push(getInferredType(context, i, ignoreConstraints)); } return result; } @@ -19925,7 +19927,10 @@ namespace ts { inferTypes(context.inferences, spreadType, restType); } - return getInferredTypes(context); + // If we are excluding context sensitive arguments we know there is another round of type inference + // coming, so we omit constraint checking. Otherwise, when a type parameter's constraint is self- + // referential, checking the constraint would cause inferences to be fixed prematurely. + return getInferredTypes(context, !!excludeArgument); } function getArrayifiedType(type: Type) { From e0082f6bfc44c3a8c340274d8c9fc9658ab7946a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 30 Jan 2019 06:43:28 -0800 Subject: [PATCH 20/42] Accept new baselines --- ...spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt b/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt index 393e21edb6c..bca28dbcf5e 100644 --- a/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt +++ b/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt @@ -1,5 +1,5 @@ error TS2318: Cannot find global type 'IterableIterator'. -tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts(6,1): error TS2554: Expected 2 arguments, but got 1. +tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts(6,1): error TS2345: Argument of type '[]' is not assignable to parameter of type 'never'. !!! error TS2318: Cannot find global type 'IterableIterator'. @@ -11,5 +11,4 @@ tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts(6,1): err call(function* (a: 'a') { }); // error, 2nd argument required ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2554: Expected 2 arguments, but got 1. -!!! related TS6210 tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts:3:5: An argument for 'args' was not provided. \ No newline at end of file +!!! error TS2345: Argument of type '[]' is not assignable to parameter of type 'never'. \ No newline at end of file From caa89cafde7a5d53f14b123630e2b3530caa4f2d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 30 Jan 2019 08:45:43 -0800 Subject: [PATCH 21/42] Add regression test --- .../inferenceAndSelfReferentialConstraint.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/cases/compiler/inferenceAndSelfReferentialConstraint.ts diff --git a/tests/cases/compiler/inferenceAndSelfReferentialConstraint.ts b/tests/cases/compiler/inferenceAndSelfReferentialConstraint.ts new file mode 100644 index 00000000000..2d991a652c1 --- /dev/null +++ b/tests/cases/compiler/inferenceAndSelfReferentialConstraint.ts @@ -0,0 +1,29 @@ +// @strict + +// Repro from #29520 + +type Test = { + [P in K | "foo"]: P extends "foo" ? true : () => any +} + +function test>(arg: T) { + return arg; +} + +const res1 = test({ + foo: true, + bar() { + } +}); + +const res2 = test({ + foo: true, + bar: function () { + } +}); + +const res3 = test({ + foo: true, + bar: () => { + } +}); From 390f20f4fc722bd1f96a625f4f33f59f1b2670be Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 30 Jan 2019 08:45:51 -0800 Subject: [PATCH 22/42] Accept new baselines --- .../inferenceAndSelfReferentialConstraint.js | 52 ++++++++++++++ ...erenceAndSelfReferentialConstraint.symbols | 63 +++++++++++++++++ ...nferenceAndSelfReferentialConstraint.types | 67 +++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 tests/baselines/reference/inferenceAndSelfReferentialConstraint.js create mode 100644 tests/baselines/reference/inferenceAndSelfReferentialConstraint.symbols create mode 100644 tests/baselines/reference/inferenceAndSelfReferentialConstraint.types diff --git a/tests/baselines/reference/inferenceAndSelfReferentialConstraint.js b/tests/baselines/reference/inferenceAndSelfReferentialConstraint.js new file mode 100644 index 00000000000..a13f100c2da --- /dev/null +++ b/tests/baselines/reference/inferenceAndSelfReferentialConstraint.js @@ -0,0 +1,52 @@ +//// [inferenceAndSelfReferentialConstraint.ts] +// @strict + +// Repro from #29520 + +type Test = { + [P in K | "foo"]: P extends "foo" ? true : () => any +} + +function test>(arg: T) { + return arg; +} + +const res1 = test({ + foo: true, + bar() { + } +}); + +const res2 = test({ + foo: true, + bar: function () { + } +}); + +const res3 = test({ + foo: true, + bar: () => { + } +}); + + +//// [inferenceAndSelfReferentialConstraint.js] +// @strict +function test(arg) { + return arg; +} +var res1 = test({ + foo: true, + bar: function () { + } +}); +var res2 = test({ + foo: true, + bar: function () { + } +}); +var res3 = test({ + foo: true, + bar: function () { + } +}); diff --git a/tests/baselines/reference/inferenceAndSelfReferentialConstraint.symbols b/tests/baselines/reference/inferenceAndSelfReferentialConstraint.symbols new file mode 100644 index 00000000000..121736623ea --- /dev/null +++ b/tests/baselines/reference/inferenceAndSelfReferentialConstraint.symbols @@ -0,0 +1,63 @@ +=== tests/cases/compiler/inferenceAndSelfReferentialConstraint.ts === +// @strict + +// Repro from #29520 + +type Test = { +>Test : Symbol(Test, Decl(inferenceAndSelfReferentialConstraint.ts, 0, 0)) +>K : Symbol(K, Decl(inferenceAndSelfReferentialConstraint.ts, 4, 10)) + + [P in K | "foo"]: P extends "foo" ? true : () => any +>P : Symbol(P, Decl(inferenceAndSelfReferentialConstraint.ts, 5, 3)) +>K : Symbol(K, Decl(inferenceAndSelfReferentialConstraint.ts, 4, 10)) +>P : Symbol(P, Decl(inferenceAndSelfReferentialConstraint.ts, 5, 3)) +} + +function test>(arg: T) { +>test : Symbol(test, Decl(inferenceAndSelfReferentialConstraint.ts, 6, 1)) +>T : Symbol(T, Decl(inferenceAndSelfReferentialConstraint.ts, 8, 14)) +>Test : Symbol(Test, Decl(inferenceAndSelfReferentialConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(inferenceAndSelfReferentialConstraint.ts, 8, 14)) +>arg : Symbol(arg, Decl(inferenceAndSelfReferentialConstraint.ts, 8, 39)) +>T : Symbol(T, Decl(inferenceAndSelfReferentialConstraint.ts, 8, 14)) + + return arg; +>arg : Symbol(arg, Decl(inferenceAndSelfReferentialConstraint.ts, 8, 39)) +} + +const res1 = test({ +>res1 : Symbol(res1, Decl(inferenceAndSelfReferentialConstraint.ts, 12, 5)) +>test : Symbol(test, Decl(inferenceAndSelfReferentialConstraint.ts, 6, 1)) + + foo: true, +>foo : Symbol(foo, Decl(inferenceAndSelfReferentialConstraint.ts, 12, 19)) + + bar() { +>bar : Symbol(bar, Decl(inferenceAndSelfReferentialConstraint.ts, 13, 12)) + } +}); + +const res2 = test({ +>res2 : Symbol(res2, Decl(inferenceAndSelfReferentialConstraint.ts, 18, 5)) +>test : Symbol(test, Decl(inferenceAndSelfReferentialConstraint.ts, 6, 1)) + + foo: true, +>foo : Symbol(foo, Decl(inferenceAndSelfReferentialConstraint.ts, 18, 19)) + + bar: function () { +>bar : Symbol(bar, Decl(inferenceAndSelfReferentialConstraint.ts, 19, 12)) + } +}); + +const res3 = test({ +>res3 : Symbol(res3, Decl(inferenceAndSelfReferentialConstraint.ts, 24, 5)) +>test : Symbol(test, Decl(inferenceAndSelfReferentialConstraint.ts, 6, 1)) + + foo: true, +>foo : Symbol(foo, Decl(inferenceAndSelfReferentialConstraint.ts, 24, 19)) + + bar: () => { +>bar : Symbol(bar, Decl(inferenceAndSelfReferentialConstraint.ts, 25, 12)) + } +}); + diff --git a/tests/baselines/reference/inferenceAndSelfReferentialConstraint.types b/tests/baselines/reference/inferenceAndSelfReferentialConstraint.types new file mode 100644 index 00000000000..c4c723baaa0 --- /dev/null +++ b/tests/baselines/reference/inferenceAndSelfReferentialConstraint.types @@ -0,0 +1,67 @@ +=== tests/cases/compiler/inferenceAndSelfReferentialConstraint.ts === +// @strict + +// Repro from #29520 + +type Test = { +>Test : Test + + [P in K | "foo"]: P extends "foo" ? true : () => any +>true : true +} + +function test>(arg: T) { +>test : >(arg: T) => T +>arg : T + + return arg; +>arg : T +} + +const res1 = test({ +>res1 : { foo: true; bar(): void; } +>test({ foo: true, bar() { }}) : { foo: true; bar(): void; } +>test : >(arg: T) => T +>{ foo: true, bar() { }} : { foo: true; bar(): void; } + + foo: true, +>foo : true +>true : true + + bar() { +>bar : () => void + } +}); + +const res2 = test({ +>res2 : { foo: true; bar: () => void; } +>test({ foo: true, bar: function () { }}) : { foo: true; bar: () => void; } +>test : >(arg: T) => T +>{ foo: true, bar: function () { }} : { foo: true; bar: () => void; } + + foo: true, +>foo : true +>true : true + + bar: function () { +>bar : () => void +>function () { } : () => void + } +}); + +const res3 = test({ +>res3 : { foo: true; bar: () => void; } +>test({ foo: true, bar: () => { }}) : { foo: true; bar: () => void; } +>test : >(arg: T) => T +>{ foo: true, bar: () => { }} : { foo: true; bar: () => void; } + + foo: true, +>foo : true +>true : true + + bar: () => { +>bar : () => void +>() => { } : () => void + } +}); + From 782622f9cd271e76a802c70db3b7c2859c5b6aa0 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Thu, 31 Jan 2019 19:44:49 +0100 Subject: [PATCH 23/42] clarify error message for 'readonly' type operator --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- .../readonlyArraysAndTuples.errors.txt | 32 +++++----- .../reference/readonlyArraysAndTuples.js | 2 + .../reference/readonlyArraysAndTuples.symbols | 62 ++++++++++--------- .../reference/readonlyArraysAndTuples.types | 3 + .../types/tuple/readonlyArraysAndTuples.ts | 1 + 7 files changed, 59 insertions(+), 45 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ac4f9561131..f2fb30424c3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -30750,7 +30750,7 @@ namespace ts { } else if (node.operator === SyntaxKind.ReadonlyKeyword) { if (node.type.kind !== SyntaxKind.ArrayType && node.type.kind !== SyntaxKind.TupleType) { - return grammarErrorOnFirstToken(node, Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_types, tokenToString(SyntaxKind.SymbolKeyword)); + return grammarErrorOnFirstToken(node, Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types, tokenToString(SyntaxKind.SymbolKeyword)); } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 68fbb52cc37..0fed10d24ad 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1023,7 +1023,7 @@ "category": "Error", "code": 1353 }, - "'readonly' type modifier is only permitted on array and tuple types.": { + "'readonly' type modifier is only permitted on array and tuple literal types.": { "category": "Error", "code": 1354 }, diff --git a/tests/baselines/reference/readonlyArraysAndTuples.errors.txt b/tests/baselines/reference/readonlyArraysAndTuples.errors.txt index aa196e25993..d2f051b6d81 100644 --- a/tests/baselines/reference/readonlyArraysAndTuples.errors.txt +++ b/tests/baselines/reference/readonlyArraysAndTuples.errors.txt @@ -1,16 +1,17 @@ -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(9,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple types. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(10,15): error TS1354: 'readonly' type modifier is only permitted on array and tuple types. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(11,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple types. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(14,5): error TS2740: Type 'readonly string[]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(16,5): error TS2740: Type 'readonly [string, string]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(20,5): error TS2739: Type 'string[]' is missing the following properties from type '[string, string]': 0, 1 -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(21,5): error TS2740: Type 'readonly string[]' is missing the following properties from type '[string, string]': 0, 1, pop, push, and 5 more. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(22,5): error TS2740: Type 'readonly [string, string]' is missing the following properties from type '[string, string]': pop, push, reverse, shift, and 3 more. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(23,5): error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(24,5): error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(9,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(10,15): error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(11,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(12,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(15,5): error TS2740: Type 'readonly string[]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(17,5): error TS2740: Type 'readonly [string, string]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(21,5): error TS2739: Type 'string[]' is missing the following properties from type '[string, string]': 0, 1 +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(22,5): error TS2740: Type 'readonly string[]' is missing the following properties from type '[string, string]': 0, 1, pop, push, and 5 more. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(23,5): error TS2740: Type 'readonly [string, string]' is missing the following properties from type '[string, string]': pop, push, reverse, shift, and 3 more. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(24,5): error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 -==== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts (10 errors) ==== +==== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts (11 errors) ==== type T10 = string[]; type T11 = Array; type T12 = readonly string[]; @@ -21,13 +22,16 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(24,5): error TS27 type T30 = readonly string; // Error ~~~~~~~~ -!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple types. +!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. type T31 = readonly T; // Error ~~~~~~~~ -!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple types. +!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. type T32 = readonly readonly string[]; // Error ~~~~~~~~ -!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple types. +!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. + type T33 = readonly Array; // Error + ~~~~~~~~ +!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) { ma = ra; // Error diff --git a/tests/baselines/reference/readonlyArraysAndTuples.js b/tests/baselines/reference/readonlyArraysAndTuples.js index ac36a24cf43..0ba392dadb4 100644 --- a/tests/baselines/reference/readonlyArraysAndTuples.js +++ b/tests/baselines/reference/readonlyArraysAndTuples.js @@ -10,6 +10,7 @@ type T21 = readonly [number, number]; type T30 = readonly string; // Error type T31 = readonly T; // Error type T32 = readonly readonly string[]; // Error +type T33 = readonly Array; // Error function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) { ma = ra; // Error @@ -55,4 +56,5 @@ declare type T21 = readonly [number, number]; declare type T30 = readonly string; declare type T31 = readonly T; declare type T32 = readonly readonly string[]; +declare type T33 = readonly Array; declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): void; diff --git a/tests/baselines/reference/readonlyArraysAndTuples.symbols b/tests/baselines/reference/readonlyArraysAndTuples.symbols index d8b383be479..c7c371af0d8 100644 --- a/tests/baselines/reference/readonlyArraysAndTuples.symbols +++ b/tests/baselines/reference/readonlyArraysAndTuples.symbols @@ -30,59 +30,63 @@ type T31 = readonly T; // Error type T32 = readonly readonly string[]; // Error >T32 : Symbol(T32, Decl(readonlyArraysAndTuples.ts, 9, 25)) +type T33 = readonly Array; // Error +>T33 : Symbol(T33, Decl(readonlyArraysAndTuples.ts, 10, 38)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) { ->f1 : Symbol(f1, Decl(readonlyArraysAndTuples.ts, 10, 38)) ->ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12)) ->ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25)) ->mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48)) ->rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70)) +>f1 : Symbol(f1, Decl(readonlyArraysAndTuples.ts, 11, 34)) +>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 13, 12)) +>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 13, 25)) +>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48)) +>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 13, 70)) ma = ra; // Error ->ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12)) ->ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25)) +>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 13, 12)) +>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 13, 25)) ma = mt; ->ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12)) ->mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48)) +>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 13, 12)) +>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48)) ma = rt; // Error ->ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12)) ->rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70)) +>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 13, 12)) +>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 13, 70)) ra = ma; ->ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25)) ->ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12)) +>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 13, 25)) +>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 13, 12)) ra = mt; ->ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25)) ->mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48)) +>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 13, 25)) +>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48)) ra = rt; ->ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25)) ->rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70)) +>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 13, 25)) +>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 13, 70)) mt = ma; // Error ->mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48)) ->ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12)) +>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48)) +>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 13, 12)) mt = ra; // Error ->mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48)) ->ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25)) +>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48)) +>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 13, 25)) mt = rt; // Error ->mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48)) ->rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70)) +>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48)) +>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 13, 70)) rt = ma; // Error ->rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70)) ->ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12)) +>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 13, 70)) +>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 13, 12)) rt = ra; // Error ->rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70)) ->ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25)) +>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 13, 70)) +>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 13, 25)) rt = mt; ->rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70)) ->mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48)) +>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 13, 70)) +>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48)) } diff --git a/tests/baselines/reference/readonlyArraysAndTuples.types b/tests/baselines/reference/readonlyArraysAndTuples.types index c2509785a9b..9ffb409d526 100644 --- a/tests/baselines/reference/readonlyArraysAndTuples.types +++ b/tests/baselines/reference/readonlyArraysAndTuples.types @@ -26,6 +26,9 @@ type T31 = readonly T; // Error type T32 = readonly readonly string[]; // Error >T32 : readonly string[] +type T33 = readonly Array; // Error +>T33 : string[] + function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) { >f1 : (ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) => void >ma : string[] diff --git a/tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts b/tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts index 6e7e5e3d6e8..d9fecee7dea 100644 --- a/tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts +++ b/tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts @@ -12,6 +12,7 @@ type T21 = readonly [number, number]; type T30 = readonly string; // Error type T31 = readonly T; // Error type T32 = readonly readonly string[]; // Error +type T33 = readonly Array; // Error function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) { ma = ra; // Error From 2a91e7aab2bcf5cf322eb1172c9909a0c8162ab7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 31 Jan 2019 15:32:52 -0800 Subject: [PATCH 24/42] Revert previous changes, use flag to disable fixing during constraint check --- src/compiler/checker.ts | 29 ++++++++++++++--------------- src/compiler/types.ts | 1 + 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 44f118b3a54..e60d5e4a2ad 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14112,7 +14112,9 @@ namespace ts { function mapper(t: Type): Type { for (let i = 0; i < inferences.length; i++) { if (t === inferences[i].typeParameter) { - inferences[i].isFixed = true; + if (!(context.flags & InferenceFlags.NoFixing)) { + inferences[i].isFixed = true; + } return getInferredType(context, i); } } @@ -14788,7 +14790,7 @@ namespace ts { return getWidenedType(unwidenedType); } - function getInferredType(context: InferenceContext, index: number, ignoreConstraints = false): Type { + function getInferredType(context: InferenceContext, index: number): Type { const inference = context.inferences[index]; let inferredType = inference.inferredType; if (!inferredType) { @@ -14836,14 +14838,14 @@ namespace ts { inference.inferredType = inferredType; - if (!ignoreConstraints) { - const constraint = getConstraintOfTypeParameter(inference.typeParameter); - if (constraint) { - const instantiatedConstraint = instantiateType(constraint, context); - if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { - inference.inferredType = inferredType = instantiatedConstraint; - } + const constraint = getConstraintOfTypeParameter(inference.typeParameter); + if (constraint) { + context.flags |= InferenceFlags.NoFixing; + const instantiatedConstraint = instantiateType(constraint, context); + if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + inference.inferredType = inferredType = instantiatedConstraint; } + context.flags &= ~InferenceFlags.NoFixing; } } @@ -14854,10 +14856,10 @@ namespace ts { return isInJavaScriptFile ? anyType : emptyObjectType; } - function getInferredTypes(context: InferenceContext, ignoreConstraints = false): Type[] { + function getInferredTypes(context: InferenceContext): Type[] { const result: Type[] = []; for (let i = 0; i < context.inferences.length; i++) { - result.push(getInferredType(context, i, ignoreConstraints)); + result.push(getInferredType(context, i)); } return result; } @@ -19927,10 +19929,7 @@ namespace ts { inferTypes(context.inferences, spreadType, restType); } - // If we are excluding context sensitive arguments we know there is another round of type inference - // coming, so we omit constraint checking. Otherwise, when a type parameter's constraint is self- - // referential, checking the constraint would cause inferences to be fixed prematurely. - return getInferredTypes(context, !!excludeArgument); + return getInferredTypes(context); } function getArrayifiedType(type: Type) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a6690dc252c..38d241ce722 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4341,6 +4341,7 @@ namespace ts { None = 0, // No special inference behaviors NoDefault = 1 << 0, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType) AnyDefault = 1 << 1, // Infer anyType for no inferences (otherwise emptyObjectType) + NoFixing = 1 << 2, // Disable type parameter fixing } /** From 51ccfb1201c970691437b039709a540ffd29fda2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 31 Jan 2019 15:33:00 -0800 Subject: [PATCH 25/42] Accept new baselines --- tests/baselines/reference/jsdocTemplateTag3.types | 2 +- ...spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/jsdocTemplateTag3.types b/tests/baselines/reference/jsdocTemplateTag3.types index e26b847519e..7dd45f47f00 100644 --- a/tests/baselines/reference/jsdocTemplateTag3.types +++ b/tests/baselines/reference/jsdocTemplateTag3.types @@ -52,7 +52,7 @@ function f(t, u, v, w, x) { } f({ a: 12, b: 'hi', c: null }, undefined, { c: false, d: 12, b: undefined }, 101, 'nope'); ->f({ a: 12, b: 'hi', c: null }, undefined, { c: false, d: 12, b: undefined }, 101, 'nope') : string | number +>f({ a: 12, b: 'hi', c: null }, undefined, { c: false, d: 12, b: undefined }, 101, 'nope') : 101 | "nope" >f : (t: T, u: U, v: V, w: W, x: X) => W | X >{ a: 12, b: 'hi', c: null } : { a: number; b: string; c: null; } >a : number diff --git a/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt b/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt index bca28dbcf5e..393e21edb6c 100644 --- a/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt +++ b/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt @@ -1,5 +1,5 @@ error TS2318: Cannot find global type 'IterableIterator'. -tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts(6,1): error TS2345: Argument of type '[]' is not assignable to parameter of type 'never'. +tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts(6,1): error TS2554: Expected 2 arguments, but got 1. !!! error TS2318: Cannot find global type 'IterableIterator'. @@ -11,4 +11,5 @@ tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts(6,1): err call(function* (a: 'a') { }); // error, 2nd argument required ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '[]' is not assignable to parameter of type 'never'. \ No newline at end of file +!!! error TS2554: Expected 2 arguments, but got 1. +!!! related TS6210 tests/cases/compiler/spreadOfParamsFromGeneratorMakesRequiredParams.ts:3:5: An argument for 'args' was not provided. \ No newline at end of file From 84250e388870f52a2d81998cf724dbeac3a8daf0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 1 Feb 2019 06:57:07 -0800 Subject: [PATCH 26/42] Increase accuracy of remaining subtype reduction work estimate --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ac4f9561131..cb011bdae5e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9273,9 +9273,9 @@ namespace ts { const source = types[i]; for (const target of types) { if (source !== target) { - if (count === 10000) { - // After 10000 subtype checks we estimate the remaining amount of work by assuming the - // same ratio of checks to removals. If the estimated number of remaining type checks is + if (count === 100000) { + // After 100000 subtype checks we estimate the remaining amount of work by assuming the + // same ratio of checks per element. If the estimated number of remaining type checks is // greater than an upper limit we deem the union type too complex to represent. The // upper limit is 25M for unions of primitives only, and 1M otherwise. This for example // caps union types at 5000 unique literal types and 1000 unique object types. From c58157573e863e4a9838cbd7a62874e06e8f7b2b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 1 Feb 2019 10:48:52 -0800 Subject: [PATCH 27/42] Add breaking change repros --- .../compiler/inferFromGenericFunctionReturnTypes3.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts b/tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts index e44e7c4a5e0..429d98b6a39 100644 --- a/tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts +++ b/tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts @@ -172,3 +172,13 @@ const f1: F = () => { } ]); }; + +// Breaking change repros from #29478 + +declare function foldLeft(z: U, f: (acc: U, t: boolean) => U): U; +let res: boolean = foldLeft(true, (acc, t) => acc && t); // Error + +enum State { A, B } +type Foo = { state: State } +declare function bar(f: () => T[]): T[]; +let x: Foo[] = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]); // Error From 42be36d1826eccd6686906e0c74c2de118083ffd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 1 Feb 2019 10:48:58 -0800 Subject: [PATCH 28/42] Accept new baselines --- ...FromGenericFunctionReturnTypes3.errors.txt | 28 +++++++++- .../inferFromGenericFunctionReturnTypes3.js | 17 ++++++ ...ferFromGenericFunctionReturnTypes3.symbols | 52 +++++++++++++++++ ...inferFromGenericFunctionReturnTypes3.types | 56 +++++++++++++++++++ 4 files changed, 152 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.errors.txt b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.errors.txt index 9a0d64c1a56..7c79c63f78a 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.errors.txt +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.errors.txt @@ -1,7 +1,13 @@ tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts(28,30): error TS2345: Argument of type 'string' is not assignable to parameter of type '"bar"'. +tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts(175,47): error TS2322: Type 'boolean' is not assignable to type 'true'. +tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts(180,26): error TS2322: Type '{ state: State.A; }[] | { state: State.B; }[]' is not assignable to type '{ state: State.A; }[]'. + Type '{ state: State.B; }[]' is not assignable to type '{ state: State.A; }[]'. + Type '{ state: State.B; }' is not assignable to type '{ state: State.A; }'. + Types of property 'state' are incompatible. + Type 'State.B' is not assignable to type 'State.A'. -==== tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts (1 errors) ==== +==== tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts (3 errors) ==== // Repros from #5487 function truePromise(): Promise { @@ -174,4 +180,24 @@ tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts(28,30): error TS234 } ]); }; + + // Breaking change repros from #29478 + + declare function foldLeft(z: U, f: (acc: U, t: boolean) => U): U; + let res: boolean = foldLeft(true, (acc, t) => acc && t); // Error + ~~~~~~~~ +!!! error TS2322: Type 'boolean' is not assignable to type 'true'. +!!! related TS6502 tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts:174:39: The expected type comes from the return type of this signature. + + enum State { A, B } + type Foo = { state: State } + declare function bar(f: () => T[]): T[]; + let x: Foo[] = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]); // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ state: State.A; }[] | { state: State.B; }[]' is not assignable to type '{ state: State.A; }[]'. +!!! error TS2322: Type '{ state: State.B; }[]' is not assignable to type '{ state: State.A; }[]'. +!!! error TS2322: Type '{ state: State.B; }' is not assignable to type '{ state: State.A; }'. +!!! error TS2322: Types of property 'state' are incompatible. +!!! error TS2322: Type 'State.B' is not assignable to type 'State.A'. +!!! related TS6502 tests/cases/compiler/inferFromGenericFunctionReturnTypes3.ts:179:28: The expected type comes from the return type of this signature. \ No newline at end of file diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.js b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.js index ca1533bbab1..99070e6ddcb 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.js +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.js @@ -169,6 +169,16 @@ const f1: F = () => { } ]); }; + +// Breaking change repros from #29478 + +declare function foldLeft(z: U, f: (acc: U, t: boolean) => U): U; +let res: boolean = foldLeft(true, (acc, t) => acc && t); // Error + +enum State { A, B } +type Foo = { state: State } +declare function bar(f: () => T[]): T[]; +let x: Foo[] = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]); // Error //// [inferFromGenericFunctionReturnTypes3.js] @@ -261,6 +271,13 @@ const f1 = () => { } ]); }; +let res = foldLeft(true, (acc, t) => acc && t); // Error +var State; +(function (State) { + State[State["A"] = 0] = "A"; + State[State["B"] = 1] = "B"; +})(State || (State = {})); +let x = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]); // Error //// [inferFromGenericFunctionReturnTypes3.d.ts] diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.symbols b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.symbols index 16beb0546de..7281886e627 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.symbols +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.symbols @@ -407,3 +407,55 @@ const f1: F = () => { ]); }; +// Breaking change repros from #29478 + +declare function foldLeft(z: U, f: (acc: U, t: boolean) => U): U; +>foldLeft : Symbol(foldLeft, Decl(inferFromGenericFunctionReturnTypes3.ts, 169, 2)) +>U : Symbol(U, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 26)) +>z : Symbol(z, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 29)) +>U : Symbol(U, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 26)) +>f : Symbol(f, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 34)) +>acc : Symbol(acc, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 39)) +>U : Symbol(U, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 26)) +>t : Symbol(t, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 46)) +>U : Symbol(U, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 26)) +>U : Symbol(U, Decl(inferFromGenericFunctionReturnTypes3.ts, 173, 26)) + +let res: boolean = foldLeft(true, (acc, t) => acc && t); // Error +>res : Symbol(res, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 3)) +>foldLeft : Symbol(foldLeft, Decl(inferFromGenericFunctionReturnTypes3.ts, 169, 2)) +>acc : Symbol(acc, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 35)) +>t : Symbol(t, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 39)) +>acc : Symbol(acc, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 35)) +>t : Symbol(t, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 39)) + +enum State { A, B } +>State : Symbol(State, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 56)) +>A : Symbol(State.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 12)) +>B : Symbol(State.B, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 15)) + +type Foo = { state: State } +>Foo : Symbol(Foo, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 19)) +>state : Symbol(state, Decl(inferFromGenericFunctionReturnTypes3.ts, 177, 12)) +>State : Symbol(State, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 56)) + +declare function bar(f: () => T[]): T[]; +>bar : Symbol(bar, Decl(inferFromGenericFunctionReturnTypes3.ts, 177, 27)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 178, 21)) +>f : Symbol(f, Decl(inferFromGenericFunctionReturnTypes3.ts, 178, 24)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 178, 21)) +>T : Symbol(T, Decl(inferFromGenericFunctionReturnTypes3.ts, 178, 21)) + +let x: Foo[] = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]); // Error +>x : Symbol(x, Decl(inferFromGenericFunctionReturnTypes3.ts, 179, 3)) +>Foo : Symbol(Foo, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 19)) +>bar : Symbol(bar, Decl(inferFromGenericFunctionReturnTypes3.ts, 177, 27)) +>state : Symbol(state, Decl(inferFromGenericFunctionReturnTypes3.ts, 179, 36)) +>State.A : Symbol(State.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 12)) +>State : Symbol(State, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 56)) +>A : Symbol(State.A, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 12)) +>state : Symbol(state, Decl(inferFromGenericFunctionReturnTypes3.ts, 179, 59)) +>State.B : Symbol(State.B, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 15)) +>State : Symbol(State, Decl(inferFromGenericFunctionReturnTypes3.ts, 174, 56)) +>B : Symbol(State.B, Decl(inferFromGenericFunctionReturnTypes3.ts, 176, 15)) + diff --git a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types index e983cc64819..ccbeb99a113 100644 --- a/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types +++ b/tests/baselines/reference/inferFromGenericFunctionReturnTypes3.types @@ -450,3 +450,59 @@ const f1: F = () => { ]); }; +// Breaking change repros from #29478 + +declare function foldLeft(z: U, f: (acc: U, t: boolean) => U): U; +>foldLeft : (z: U, f: (acc: U, t: boolean) => U) => U +>z : U +>f : (acc: U, t: boolean) => U +>acc : U +>t : boolean + +let res: boolean = foldLeft(true, (acc, t) => acc && t); // Error +>res : boolean +>foldLeft(true, (acc, t) => acc && t) : any +>foldLeft : (z: U, f: (acc: U, t: boolean) => U) => U +>true : true +>(acc, t) => acc && t : (acc: true, t: boolean) => boolean +>acc : true +>t : boolean +>acc && t : boolean +>acc : true +>t : boolean + +enum State { A, B } +>State : State +>A : State.A +>B : State.B + +type Foo = { state: State } +>Foo : Foo +>state : State + +declare function bar(f: () => T[]): T[]; +>bar : (f: () => T[]) => T[] +>f : () => T[] + +let x: Foo[] = bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]); // Error +>x : Foo[] +>bar(() => !!true ? [{ state: State.A }] : [{ state: State.B }]) : any +>bar : (f: () => T[]) => T[] +>() => !!true ? [{ state: State.A }] : [{ state: State.B }] : () => { state: State.A; }[] | { state: State.B; }[] +>!!true ? [{ state: State.A }] : [{ state: State.B }] : { state: State; }[] +>!!true : true +>!true : false +>true : true +>[{ state: State.A }] : { state: State; }[] +>{ state: State.A } : { state: State; } +>state : State +>State.A : State.A +>State : typeof State +>A : State.A +>[{ state: State.B }] : { state: State; }[] +>{ state: State.B } : { state: State; } +>state : State +>State.B : State.B +>State : typeof State +>B : State.B + From ed277b8ee978209b59443cccc6755145b23dd976 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 1 Feb 2019 10:50:04 -0800 Subject: [PATCH 29/42] Handle GetAccessor and SetAccessor in isThisless (#27869) --- src/compiler/checker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cb011bdae5e..078216f6203 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6364,7 +6364,9 @@ namespace ts { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: case SyntaxKind.Constructor: - return isThislessFunctionLikeDeclaration(declaration); + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return isThislessFunctionLikeDeclaration(declaration); } } } From 4b84f56b21b3845cde5b4a0d351e58e684644821 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 1 Feb 2019 16:09:17 -0800 Subject: [PATCH 30/42] Fix type reference dts emit failure --- src/compiler/checker.ts | 17 +++++++++- .../reference/typeReferenceRelatedFiles.js | 34 +++++++++++++++++++ .../typeReferenceRelatedFiles.symbols | 21 ++++++++++++ .../reference/typeReferenceRelatedFiles.types | 21 ++++++++++++ .../typeReferenceRelatedFiles.ts | 18 ++++++++++ 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/typeReferenceRelatedFiles.js create mode 100644 tests/baselines/reference/typeReferenceRelatedFiles.symbols create mode 100644 tests/baselines/reference/typeReferenceRelatedFiles.types create mode 100644 tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0cfdeadc00a..875c9b5d185 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -29540,9 +29540,12 @@ namespace ts { return; } const file = host.getSourceFile(resolvedDirective.resolvedFileName)!; - fileToDirective.set(file.path, key); + // Add the transitive closure of path references loaded by this file (as long as they are not) + // part of an existing type reference. + addReferencedFilesToTypeDirective(file, key); }); } + return { getReferencedExportContainer, getReferencedImportDeclaration, @@ -29701,6 +29704,18 @@ namespace ts { } return false; } + + function addReferencedFilesToTypeDirective(file: SourceFile, key: string) { + if (fileToDirective.has(file.path)) return; + fileToDirective.set(file.path, key); + for (const { fileName } of file.referencedFiles) { + const resolvedFile = resolveTripleslashReference(fileName, file.originalFileName); + const referencedFile = host.getSourceFile(resolvedFile); + if (referencedFile) { + addReferencedFilesToTypeDirective(referencedFile, key); + } + } + } } function getExternalModuleFileFromDeclaration(declaration: AnyImportOrReExport | ModuleDeclaration | ImportTypeNode): SourceFile | undefined { diff --git a/tests/baselines/reference/typeReferenceRelatedFiles.js b/tests/baselines/reference/typeReferenceRelatedFiles.js new file mode 100644 index 00000000000..77cf0a8e16d --- /dev/null +++ b/tests/baselines/reference/typeReferenceRelatedFiles.js @@ -0,0 +1,34 @@ +//// [tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts] //// + +//// [index.d.ts] +/// +//// [fs.d.ts] +declare module "fs" { + interface FSWatcher {} +} +//// [package.json] +{ + "name": "@types/node", + "version": "1.0.0" +} +//// [main.ts] +/// +import { FSWatcher } from "fs"; +export function f() { + return {} as FSWatcher; +} + + +//// [main.js] +"use strict"; +exports.__esModule = true; +function f() { + return {}; +} +exports.f = f; + + +//// [main.d.ts] +/// +import { FSWatcher } from "fs"; +export declare function f(): FSWatcher; diff --git a/tests/baselines/reference/typeReferenceRelatedFiles.symbols b/tests/baselines/reference/typeReferenceRelatedFiles.symbols new file mode 100644 index 00000000000..689125fe0fa --- /dev/null +++ b/tests/baselines/reference/typeReferenceRelatedFiles.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/declarationEmit/node_modules/@types/node/index.d.ts === +/// +No type information for this code.=== tests/cases/conformance/declarationEmit/node_modules/@types/node/fs.d.ts === +declare module "fs" { +>"fs" : Symbol("fs", Decl(fs.d.ts, 0, 0)) + + interface FSWatcher {} +>FSWatcher : Symbol(FSWatcher, Decl(fs.d.ts, 0, 21)) +} +=== tests/cases/conformance/declarationEmit/main.ts === +/// +import { FSWatcher } from "fs"; +>FSWatcher : Symbol(FSWatcher, Decl(main.ts, 1, 8)) + +export function f() { +>f : Symbol(f, Decl(main.ts, 1, 31)) + + return {} as FSWatcher; +>FSWatcher : Symbol(FSWatcher, Decl(main.ts, 1, 8)) +} + diff --git a/tests/baselines/reference/typeReferenceRelatedFiles.types b/tests/baselines/reference/typeReferenceRelatedFiles.types new file mode 100644 index 00000000000..824bde2ab98 --- /dev/null +++ b/tests/baselines/reference/typeReferenceRelatedFiles.types @@ -0,0 +1,21 @@ +=== tests/cases/conformance/declarationEmit/node_modules/@types/node/index.d.ts === +/// +No type information for this code.=== tests/cases/conformance/declarationEmit/node_modules/@types/node/fs.d.ts === +declare module "fs" { +>"fs" : typeof import("fs") + + interface FSWatcher {} +} +=== tests/cases/conformance/declarationEmit/main.ts === +/// +import { FSWatcher } from "fs"; +>FSWatcher : any + +export function f() { +>f : () => FSWatcher + + return {} as FSWatcher; +>{} as FSWatcher : FSWatcher +>{} : {} +} + diff --git a/tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts b/tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts new file mode 100644 index 00000000000..f144f15cddb --- /dev/null +++ b/tests/cases/conformance/declarationEmit/typeReferenceRelatedFiles.ts @@ -0,0 +1,18 @@ +// @declaration: true +// @filename: node_modules/@types/node/index.d.ts +/// +// @filename: node_modules/@types/node/fs.d.ts +declare module "fs" { + interface FSWatcher {} +} +// @filename: node_modules/@types/node/package.json +{ + "name": "@types/node", + "version": "1.0.0" +} +// @filename: main.ts +/// +import { FSWatcher } from "fs"; +export function f() { + return {} as FSWatcher; +} From efbe630a1332f5357b08838e7040d9f5a742a5f2 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Fri, 1 Feb 2019 17:05:04 -0800 Subject: [PATCH 31/42] Use unknown for array predicates' return types --- src/lib/es5.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 8dc6ee90a2e..7d2c7b80a7b 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1114,13 +1114,13 @@ interface ReadonlyArray { * @param callbackfn A function that accepts up to three arguments. The every method calls the callbackfn function for each element in array1 until the callbackfn returns false, or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ - every(callbackfn: (value: T, index: number, array: ReadonlyArray) => boolean, thisArg?: any): boolean; + every(callbackfn: (value: T, index: number, array: ReadonlyArray) => unknown, thisArg?: any): boolean; /** * Determines whether the specified callback function returns true for any element of an array. * @param callbackfn A function that accepts up to three arguments. The some method calls the callbackfn function for each element in array1 until the callbackfn returns true, or until the end of the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ - some(callbackfn: (value: T, index: number, array: ReadonlyArray) => boolean, thisArg?: any): boolean; + some(callbackfn: (value: T, index: number, array: ReadonlyArray) => unknown, thisArg?: any): boolean; /** * Performs the specified action for each element in an array. * @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array. @@ -1144,7 +1144,7 @@ interface ReadonlyArray { * @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array. * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. */ - filter(callbackfn: (value: T, index: number, array: ReadonlyArray) => any, thisArg?: any): T[]; + filter(callbackfn: (value: T, index: number, array: ReadonlyArray) => unknown, thisArg?: any): T[]; /** * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. From e7ad76ddc851e0df40f86f7ebb184cd020566bb4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 2 Feb 2019 09:28:21 -0800 Subject: [PATCH 32/42] Less restrictive constraints in Parameters and ReturnType types --- src/lib/es5.d.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 8dc6ee90a2e..3f19abfa16b 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1451,22 +1451,22 @@ type NonNullable = T extends null | undefined ? never : T; /** * Obtain the parameters of a function type in a tuple */ -type Parameters any> = T extends (...args: infer P) => any ? P : never; +type Parameters any> = T extends (...args: infer P) => any ? P : never; /** * Obtain the parameters of a constructor function type in a tuple */ -type ConstructorParameters any> = T extends new (...args: infer P) => any ? P : never; +type ConstructorParameters any> = T extends new (...args: infer P) => any ? P : never; /** * Obtain the return type of a function type */ -type ReturnType any> = T extends (...args: any[]) => infer R ? R : any; +type ReturnType any> = T extends (...args: any) => infer R ? R : any; /** * Obtain the return type of a constructor function type */ -type InstanceType any> = T extends new (...args: any[]) => infer R ? R : any; +type InstanceType any> = T extends new (...args: any) => infer R ? R : any; /** * Marker for contextual 'this' type From be4fb30e611629c535ae513f7e9376335d5fb448 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 2 Feb 2019 09:28:28 -0800 Subject: [PATCH 33/42] Accept new baselines --- .../genericRestParameters1.errors.txt | 24 ++--- .../genericRestParameters2.errors.txt | 89 ------------------- .../reference/inferTypes1.errors.txt | 24 ++--- .../parameterListAsTupleType.errors.txt | 8 +- 4 files changed, 21 insertions(+), 124 deletions(-) delete mode 100644 tests/baselines/reference/genericRestParameters2.errors.txt diff --git a/tests/baselines/reference/genericRestParameters1.errors.txt b/tests/baselines/reference/genericRestParameters1.errors.txt index d0a09ee4638..3eed7183374 100644 --- a/tests/baselines/reference/genericRestParameters1.errors.txt +++ b/tests/baselines/reference/genericRestParameters1.errors.txt @@ -1,19 +1,13 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(22,1): error TS2556: Expected 3 arguments, but got 1 or more. tests/cases/conformance/types/rest/genericRestParameters1.ts(31,1): error TS2556: Expected 3 arguments, but got 1 or more. -tests/cases/conformance/types/rest/genericRestParameters1.ts(133,40): error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. - Types of parameters 'args' and 'args' are incompatible. - Type 'any[]' is not assignable to type 'T'. -tests/cases/conformance/types/rest/genericRestParameters1.ts(134,51): error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. - Types of parameters 'args' and 'args' are incompatible. - Type 'any[]' is not assignable to type 'T'. -tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. - Type 'Function' provides no match for the signature '(...args: any[]): any'. +tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. + Type 'Function' provides no match for the signature '(...args: any): any'. tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS2322: Type '(a: never) => void' is not assignable to type '(...args: any[]) => void'. Types of parameters 'a' and 'args' are incompatible. Type 'any' is not assignable to type 'never'. -==== tests/cases/conformance/types/rest/genericRestParameters1.ts (6 errors) ==== +==== tests/cases/conformance/types/rest/genericRestParameters1.ts (4 errors) ==== declare let f1: (...x: [number, string, boolean]) => void; declare let f2: (x0: number, x1: string, x2: boolean) => void; @@ -152,19 +146,11 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS232 type T05 = Parameters<(...args: T[]) => void>; type T06 = ConstructorParameters void>; type T07 = Parameters<(...args: T) => void>; - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. -!!! error TS2344: Types of parameters 'args' and 'args' are incompatible. -!!! error TS2344: Type 'any[]' is not assignable to type 'T'. type T08 = ConstructorParameters void>; - ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. -!!! error TS2344: Types of parameters 'args' and 'args' are incompatible. -!!! error TS2344: Type 'any[]' is not assignable to type 'T'. type T09 = Parameters; ~~~~~~~~ -!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. -!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any[]): any'. +!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. +!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any): any'. type Record1 = { move: [number, 'left' | 'right']; diff --git a/tests/baselines/reference/genericRestParameters2.errors.txt b/tests/baselines/reference/genericRestParameters2.errors.txt deleted file mode 100644 index a22af304ab8..00000000000 --- a/tests/baselines/reference/genericRestParameters2.errors.txt +++ /dev/null @@ -1,89 +0,0 @@ -tests/cases/conformance/types/rest/genericRestParameters2.ts(71,40): error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. - Types of parameters 'x' and 'args' are incompatible. - Property '0' is missing in type 'any[]' but required in type '[string, ...any[]]'. - - -==== tests/cases/conformance/types/rest/genericRestParameters2.ts (1 errors) ==== - declare const t1: [number, string, ...boolean[]]; - declare const t2: [string, ...boolean[]]; - declare const t3: [...boolean[]]; - declare const t4: []; - - declare let f00: (...x: [number, string, boolean]) => void; - declare let f01: (a: number, ...x: [string, boolean]) => void; - declare let f02: (a: number, b: string, ...x: [boolean]) => void; - declare let f03: (a: number, b: string, c: boolean) => void; - declare let f04: (a: number, b: string, c: boolean, ...x: []) => void; - - declare let f10: (...x: [number, string, ...boolean[]]) => void; - declare let f11: (a: number, ...x: [string, ...boolean[]]) => void; - declare let f12: (a: number, b: string, ...x: [...boolean[]]) => void; - declare let f13: (a: number, b: string, ...c: boolean[]) => void; - - declare const ns: [number, string]; - declare const sn: [string, number]; - - f10(42, "hello"); - f10(42, "hello", true); - f10(42, "hello", true, false); - f10(t1[0], t1[1], t1[2], t1[3]); - f10(...t1); - f10(42, ...t2); - f10(42, "hello", ...t3); - f10(42, "hello", true, ...t4); - f10(42, "hello", true, ...t4, false, ...t3); - - f11(42, "hello"); - f11(42, "hello", true); - f11(42, "hello", true, false); - f11(t1[0], t1[1], t1[2], t1[3]); - f11(...t1); - f11(42, ...t2); - f11(42, "hello", ...t3); - f11(42, "hello", true, ...t4); - f11(42, "hello", true, ...t4, false, ...t3); - - f12(42, "hello"); - f12(42, "hello", true); - f12(42, "hello", true, false); - f12(t1[0], t1[1], t1[2], t1[3]); - f12(...t1); - f12(42, ...t2); - f12(42, "hello", ...t3); - f12(42, "hello", true, ...t4); - f12(42, "hello", true, ...t4, false, ...t3); - - f13(42, "hello"); - f13(42, "hello", true); - f13(42, "hello", true, false); - f13(t1[0], t1[1], t1[2], t1[3]); - f13(...t1); - f13(42, ...t2); - f13(42, "hello", ...t3); - f13(42, "hello", true, ...t4); - f13(42, "hello", true, ...t4, false, ...t3); - - declare const f20: (...args: T) => T; - - f20(...t1); - f20(42, ...t2); - f20(42, "hello", ...t3); - f20(42, "hello", ...t2, true); - - type T01 = Parameters<(x: number, y: string, ...z: boolean[]) => void>; - type T02 = Parameters<(...args: [number, string, ...boolean[]]) => void>; - type T03 = ConstructorParameters void>; - type T04 = ConstructorParameters void>; - type T05 = Parameters<(x: string, ...args: T) => void>; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. -!!! error TS2344: Types of parameters 'x' and 'args' are incompatible. -!!! error TS2344: Property '0' is missing in type 'any[]' but required in type '[string, ...any[]]'. - type T06 = T05<[number, ...boolean[]]>; - - type P1 = T extends (head: infer A, ...tail: infer B) => any ? { head: A, tail: B } : any[]; - - type T10 = P1<(x: number, y: string, ...z: boolean[]) => void>; - type T11 = P1<(...z: number[]) => void>; - type T12 = P1<(x: number, y: number) => void>; - \ No newline at end of file diff --git a/tests/baselines/reference/inferTypes1.errors.txt b/tests/baselines/reference/inferTypes1.errors.txt index 4684b8f5e34..be16eb4c3f7 100644 --- a/tests/baselines/reference/inferTypes1.errors.txt +++ b/tests/baselines/reference/inferTypes1.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/types/conditional/inferTypes1.ts(31,23): error TS2344: Type 'string' does not satisfy the constraint '(...args: any[]) => any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(32,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. - Type 'Function' provides no match for the signature '(...args: any[]): any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(37,25): error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any[]) => any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(38,25): error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any[]) => any'. - Type 'Function' provides no match for the signature 'new (...args: any[]): any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(31,23): error TS2344: Type 'string' does not satisfy the constraint '(...args: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(32,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. + Type 'Function' provides no match for the signature '(...args: any): any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(37,25): error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(38,25): error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'. + Type 'Function' provides no match for the signature 'new (...args: any): any'. tests/cases/conformance/types/conditional/inferTypes1.ts(46,25): error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'. tests/cases/conformance/types/conditional/inferTypes1.ts(47,25): error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'. Type 'Function' provides no match for the signature '(x: any): any'. @@ -54,22 +54,22 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: type T16 = ReturnType; // never type T17 = ReturnType; // Error ~~~~~~ -!!! error TS2344: Type 'string' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Type 'string' does not satisfy the constraint '(...args: any) => any'. type T18 = ReturnType; // Error ~~~~~~~~ -!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. -!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any[]): any'. +!!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. +!!! error TS2344: Type 'Function' provides no match for the signature '(...args: any): any'. type U10 = InstanceType; // C type U11 = InstanceType; // any type U12 = InstanceType; // never type U13 = InstanceType; // Error ~~~~~~ -!!! error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any[]) => any'. +!!! error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any) => any'. type U14 = InstanceType; // Error ~~~~~~~~ -!!! error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any[]) => any'. -!!! error TS2344: Type 'Function' provides no match for the signature 'new (...args: any[]): any'. +!!! error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'. +!!! error TS2344: Type 'Function' provides no match for the signature 'new (...args: any): any'. type ArgumentType any> = T extends (a: infer A) => any ? A : any; diff --git a/tests/baselines/reference/parameterListAsTupleType.errors.txt b/tests/baselines/reference/parameterListAsTupleType.errors.txt index 021138ec2ba..6bf3d74466e 100644 --- a/tests/baselines/reference/parameterListAsTupleType.errors.txt +++ b/tests/baselines/reference/parameterListAsTupleType.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/parameterListAsTupleType.ts(8,17): error TS2322: Type 'string' is not assignable to type 'number'. -tests/cases/compiler/parameterListAsTupleType.ts(16,23): error TS2344: Type 'typeof C' does not satisfy the constraint '(...args: any[]) => any'. - Type 'typeof C' provides no match for the signature '(...args: any[]): any'. +tests/cases/compiler/parameterListAsTupleType.ts(16,23): error TS2344: Type 'typeof C' does not satisfy the constraint '(...args: any) => any'. + Type 'typeof C' provides no match for the signature '(...args: any): any'. ==== tests/cases/compiler/parameterListAsTupleType.ts (2 errors) ==== @@ -23,8 +23,8 @@ tests/cases/compiler/parameterListAsTupleType.ts(16,23): error TS2344: Type 'typ type Cps = Parameters; // should not work ~~~~~~~~ -!!! error TS2344: Type 'typeof C' does not satisfy the constraint '(...args: any[]) => any'. -!!! error TS2344: Type 'typeof C' provides no match for the signature '(...args: any[]): any'. +!!! error TS2344: Type 'typeof C' does not satisfy the constraint '(...args: any) => any'. +!!! error TS2344: Type 'typeof C' provides no match for the signature '(...args: any): any'. type Ccps = ConstructorParameters; // should be [number, string] class D { From 332861b4fc5215f4553135a118cfdd76077ea242 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 2 Feb 2019 09:37:52 -0800 Subject: [PATCH 34/42] Add tests --- .../conformance/types/conditional/inferTypes1.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/cases/conformance/types/conditional/inferTypes1.ts b/tests/cases/conformance/types/conditional/inferTypes1.ts index 6f31b8e49eb..83d6bd0c0b3 100644 --- a/tests/cases/conformance/types/conditional/inferTypes1.ts +++ b/tests/cases/conformance/types/conditional/inferTypes1.ts @@ -33,6 +33,7 @@ type T15 = ReturnType; // any type T16 = ReturnType; // never type T17 = ReturnType; // Error type T18 = ReturnType; // Error +type T19 = ReturnType<(x: string, ...args: T) => T[]>; // T[] type U10 = InstanceType; // C type U11 = InstanceType; // any @@ -168,3 +169,13 @@ type EnsureIsString = T extends MustBeString ? U : never; type Test1 = EnsureIsString<"hello">; // "hello" type Test2 = EnsureIsString<42>; // never + +// Repros from #26856 + +function invoker (key: K, ...args: A) { + return any>> (obj: T): ReturnType => obj[key](...args) +} + +const result = invoker('test', true)({ test: (a: boolean) => 123 }) + +type Foo2 = ReturnType<(...args: A) => string>; From 118a2ccad450c5d62a9a2f54261a0415e432b487 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 2 Feb 2019 09:37:59 -0800 Subject: [PATCH 35/42] Accept new baselines --- .../reference/inferTypes1.errors.txt | 39 +- tests/baselines/reference/inferTypes1.js | 20 + tests/baselines/reference/inferTypes1.symbols | 761 ++++++++++-------- tests/baselines/reference/inferTypes1.types | 41 + 4 files changed, 491 insertions(+), 370 deletions(-) diff --git a/tests/baselines/reference/inferTypes1.errors.txt b/tests/baselines/reference/inferTypes1.errors.txt index be16eb4c3f7..1de0ca2562f 100644 --- a/tests/baselines/reference/inferTypes1.errors.txt +++ b/tests/baselines/reference/inferTypes1.errors.txt @@ -1,23 +1,23 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(31,23): error TS2344: Type 'string' does not satisfy the constraint '(...args: any) => any'. tests/cases/conformance/types/conditional/inferTypes1.ts(32,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. Type 'Function' provides no match for the signature '(...args: any): any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(37,25): error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any) => any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(38,25): error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(38,25): error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(39,25): error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'. Type 'Function' provides no match for the signature 'new (...args: any): any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(46,25): error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(47,25): error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(47,25): error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(48,25): error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'. Type 'Function' provides no match for the signature '(x: any): any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(73,12): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. -tests/cases/conformance/types/conditional/inferTypes1.ts(74,15): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. -tests/cases/conformance/types/conditional/inferTypes1.ts(74,41): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. -tests/cases/conformance/types/conditional/inferTypes1.ts(74,51): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. -tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS2304: Cannot find name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS4081: Exported type alias 'T62' has or is using private name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS2304: Cannot find name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(82,44): error TS2344: Type 'U' does not satisfy the constraint 'string'. +tests/cases/conformance/types/conditional/inferTypes1.ts(74,12): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(75,41): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(75,51): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(76,15): error TS2304: Cannot find name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(76,15): error TS4081: Exported type alias 'T62' has or is using private name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(76,43): error TS2304: Cannot find name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(76,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(83,44): error TS2344: Type 'U' does not satisfy the constraint 'string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'. +tests/cases/conformance/types/conditional/inferTypes1.ts(145,40): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'. Type 'T' is not assignable to type 'symbol'. @@ -59,6 +59,7 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: ~~~~~~~~ !!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. !!! error TS2344: Type 'Function' provides no match for the signature '(...args: any): any'. + type T19 = ReturnType<(x: string, ...args: T) => T[]>; // T[] type U10 = InstanceType; // C type U11 = InstanceType; // any @@ -226,4 +227,14 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: type Test1 = EnsureIsString<"hello">; // "hello" type Test2 = EnsureIsString<42>; // never + + // Repros from #26856 + + function invoker (key: K, ...args: A) { + return any>> (obj: T): ReturnType => obj[key](...args) + } + + const result = invoker('test', true)({ test: (a: boolean) => 123 }) + + type Foo2 = ReturnType<(...args: A) => string>; \ No newline at end of file diff --git a/tests/baselines/reference/inferTypes1.js b/tests/baselines/reference/inferTypes1.js index f794bb014fa..d15933264e9 100644 --- a/tests/baselines/reference/inferTypes1.js +++ b/tests/baselines/reference/inferTypes1.js @@ -31,6 +31,7 @@ type T15 = ReturnType; // any type T16 = ReturnType; // never type T17 = ReturnType; // Error type T18 = ReturnType; // Error +type T19 = ReturnType<(x: string, ...args: T) => T[]>; // T[] type U10 = InstanceType; // C type U11 = InstanceType; // any @@ -166,6 +167,16 @@ type EnsureIsString = T extends MustBeString ? U : never; type Test1 = EnsureIsString<"hello">; // "hello" type Test2 = EnsureIsString<42>; // never + +// Repros from #26856 + +function invoker (key: K, ...args: A) { + return any>> (obj: T): ReturnType => obj[key](...args) +} + +const result = invoker('test', true)({ test: (a: boolean) => 123 }) + +type Foo2 = ReturnType<(...args: A) => string>; //// [inferTypes1.js] @@ -182,3 +193,12 @@ var C = /** @class */ (function () { }()); var z1 = ex.customClass; var z2 = ex.obj.nested.attr; +// Repros from #26856 +function invoker(key) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + return function (obj) { return obj[key].apply(obj, args); }; +} +var result = invoker('test', true)({ test: function (a) { return 123; } }); diff --git a/tests/baselines/reference/inferTypes1.symbols b/tests/baselines/reference/inferTypes1.symbols index ad5d6a2b68c..6abd0a2a36c 100644 --- a/tests/baselines/reference/inferTypes1.symbols +++ b/tests/baselines/reference/inferTypes1.symbols @@ -119,575 +119,624 @@ type T18 = ReturnType; // Error >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +type T19 = ReturnType<(x: string, ...args: T) => T[]>; // T[] +>T19 : Symbol(T19, Decl(inferTypes1.ts, 31, 32)) +>T : Symbol(T, Decl(inferTypes1.ts, 32, 9)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(inferTypes1.ts, 32, 40)) +>args : Symbol(args, Decl(inferTypes1.ts, 32, 50)) +>T : Symbol(T, Decl(inferTypes1.ts, 32, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 32, 9)) + type U10 = InstanceType; // C ->U10 : Symbol(U10, Decl(inferTypes1.ts, 31, 32)) +>U10 : Symbol(U10, Decl(inferTypes1.ts, 32, 71)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) >C : Symbol(C, Decl(inferTypes1.ts, 16, 1)) type U11 = InstanceType; // any ->U11 : Symbol(U11, Decl(inferTypes1.ts, 33, 34)) +>U11 : Symbol(U11, Decl(inferTypes1.ts, 34, 34)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) type U12 = InstanceType; // never ->U12 : Symbol(U12, Decl(inferTypes1.ts, 34, 29)) +>U12 : Symbol(U12, Decl(inferTypes1.ts, 35, 29)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) type U13 = InstanceType; // Error ->U13 : Symbol(U13, Decl(inferTypes1.ts, 35, 31)) +>U13 : Symbol(U13, Decl(inferTypes1.ts, 36, 31)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) type U14 = InstanceType; // Error ->U14 : Symbol(U14, Decl(inferTypes1.ts, 36, 32)) +>U14 : Symbol(U14, Decl(inferTypes1.ts, 37, 32)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) type ArgumentType any> = T extends (a: infer A) => any ? A : any; ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) ->T : Symbol(T, Decl(inferTypes1.ts, 39, 18)) ->x : Symbol(x, Decl(inferTypes1.ts, 39, 29)) ->T : Symbol(T, Decl(inferTypes1.ts, 39, 18)) ->a : Symbol(a, Decl(inferTypes1.ts, 39, 58)) ->A : Symbol(A, Decl(inferTypes1.ts, 39, 66)) ->A : Symbol(A, Decl(inferTypes1.ts, 39, 66)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) +>T : Symbol(T, Decl(inferTypes1.ts, 40, 18)) +>x : Symbol(x, Decl(inferTypes1.ts, 40, 29)) +>T : Symbol(T, Decl(inferTypes1.ts, 40, 18)) +>a : Symbol(a, Decl(inferTypes1.ts, 40, 58)) +>A : Symbol(A, Decl(inferTypes1.ts, 40, 66)) +>A : Symbol(A, Decl(inferTypes1.ts, 40, 66)) type T20 = ArgumentType<() => void>; // {} ->T20 : Symbol(T20, Decl(inferTypes1.ts, 39, 87)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) +>T20 : Symbol(T20, Decl(inferTypes1.ts, 40, 87)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) type T21 = ArgumentType<(x: string) => number>; // string ->T21 : Symbol(T21, Decl(inferTypes1.ts, 41, 36)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) ->x : Symbol(x, Decl(inferTypes1.ts, 42, 25)) - -type T22 = ArgumentType<(x?: string) => number>; // string | undefined ->T22 : Symbol(T22, Decl(inferTypes1.ts, 42, 47)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) +>T21 : Symbol(T21, Decl(inferTypes1.ts, 42, 36)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) >x : Symbol(x, Decl(inferTypes1.ts, 43, 25)) +type T22 = ArgumentType<(x?: string) => number>; // string | undefined +>T22 : Symbol(T22, Decl(inferTypes1.ts, 43, 47)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) +>x : Symbol(x, Decl(inferTypes1.ts, 44, 25)) + type T23 = ArgumentType<(...args: string[]) => number>; // string ->T23 : Symbol(T23, Decl(inferTypes1.ts, 43, 48)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) ->args : Symbol(args, Decl(inferTypes1.ts, 44, 25)) +>T23 : Symbol(T23, Decl(inferTypes1.ts, 44, 48)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) +>args : Symbol(args, Decl(inferTypes1.ts, 45, 25)) type T24 = ArgumentType<(x: string, y: string) => number>; // Error ->T24 : Symbol(T24, Decl(inferTypes1.ts, 44, 55)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) ->x : Symbol(x, Decl(inferTypes1.ts, 45, 25)) ->y : Symbol(y, Decl(inferTypes1.ts, 45, 35)) +>T24 : Symbol(T24, Decl(inferTypes1.ts, 45, 55)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) +>x : Symbol(x, Decl(inferTypes1.ts, 46, 25)) +>y : Symbol(y, Decl(inferTypes1.ts, 46, 35)) type T25 = ArgumentType; // Error ->T25 : Symbol(T25, Decl(inferTypes1.ts, 45, 58)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) +>T25 : Symbol(T25, Decl(inferTypes1.ts, 46, 58)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) type T26 = ArgumentType; // any ->T26 : Symbol(T26, Decl(inferTypes1.ts, 46, 34)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) +>T26 : Symbol(T26, Decl(inferTypes1.ts, 47, 34)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) type T27 = ArgumentType; // never ->T27 : Symbol(T27, Decl(inferTypes1.ts, 47, 29)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 37, 34)) +>T27 : Symbol(T27, Decl(inferTypes1.ts, 48, 29)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; ->X1 : Symbol(X1, Decl(inferTypes1.ts, 48, 31)) ->T : Symbol(T, Decl(inferTypes1.ts, 50, 8)) ->x : Symbol(x, Decl(inferTypes1.ts, 50, 19)) ->y : Symbol(y, Decl(inferTypes1.ts, 50, 27)) ->T : Symbol(T, Decl(inferTypes1.ts, 50, 8)) ->x : Symbol(x, Decl(inferTypes1.ts, 50, 51)) ->X : Symbol(X, Decl(inferTypes1.ts, 50, 60)) ->y : Symbol(y, Decl(inferTypes1.ts, 50, 63)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 50, 72)) ->X : Symbol(X, Decl(inferTypes1.ts, 50, 60)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 50, 72)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 49, 31)) +>T : Symbol(T, Decl(inferTypes1.ts, 51, 8)) +>x : Symbol(x, Decl(inferTypes1.ts, 51, 19)) +>y : Symbol(y, Decl(inferTypes1.ts, 51, 27)) +>T : Symbol(T, Decl(inferTypes1.ts, 51, 8)) +>x : Symbol(x, Decl(inferTypes1.ts, 51, 51)) +>X : Symbol(X, Decl(inferTypes1.ts, 51, 60)) +>y : Symbol(y, Decl(inferTypes1.ts, 51, 63)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 51, 72)) +>X : Symbol(X, Decl(inferTypes1.ts, 51, 60)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 51, 72)) type T30 = X1<{ x: any, y: any }>; // [any, any] ->T30 : Symbol(T30, Decl(inferTypes1.ts, 50, 92)) ->X1 : Symbol(X1, Decl(inferTypes1.ts, 48, 31)) ->x : Symbol(x, Decl(inferTypes1.ts, 52, 15)) ->y : Symbol(y, Decl(inferTypes1.ts, 52, 23)) +>T30 : Symbol(T30, Decl(inferTypes1.ts, 51, 92)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 49, 31)) +>x : Symbol(x, Decl(inferTypes1.ts, 53, 15)) +>y : Symbol(y, Decl(inferTypes1.ts, 53, 23)) type T31 = X1<{ x: number, y: string }>; // [number, string] ->T31 : Symbol(T31, Decl(inferTypes1.ts, 52, 34)) ->X1 : Symbol(X1, Decl(inferTypes1.ts, 48, 31)) ->x : Symbol(x, Decl(inferTypes1.ts, 53, 15)) ->y : Symbol(y, Decl(inferTypes1.ts, 53, 26)) - -type T32 = X1<{ x: number, y: string, z: boolean }>; // [number, string] ->T32 : Symbol(T32, Decl(inferTypes1.ts, 53, 40)) ->X1 : Symbol(X1, Decl(inferTypes1.ts, 48, 31)) +>T31 : Symbol(T31, Decl(inferTypes1.ts, 53, 34)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 49, 31)) >x : Symbol(x, Decl(inferTypes1.ts, 54, 15)) >y : Symbol(y, Decl(inferTypes1.ts, 54, 26)) ->z : Symbol(z, Decl(inferTypes1.ts, 54, 37)) + +type T32 = X1<{ x: number, y: string, z: boolean }>; // [number, string] +>T32 : Symbol(T32, Decl(inferTypes1.ts, 54, 40)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 49, 31)) +>x : Symbol(x, Decl(inferTypes1.ts, 55, 15)) +>y : Symbol(y, Decl(inferTypes1.ts, 55, 26)) +>z : Symbol(z, Decl(inferTypes1.ts, 55, 37)) type X2 = T extends { a: infer U, b: infer U } ? U : never; ->X2 : Symbol(X2, Decl(inferTypes1.ts, 54, 52)) ->T : Symbol(T, Decl(inferTypes1.ts, 56, 8)) ->T : Symbol(T, Decl(inferTypes1.ts, 56, 8)) ->a : Symbol(a, Decl(inferTypes1.ts, 56, 24)) ->U : Symbol(U, Decl(inferTypes1.ts, 56, 33), Decl(inferTypes1.ts, 56, 45)) ->b : Symbol(b, Decl(inferTypes1.ts, 56, 36)) ->U : Symbol(U, Decl(inferTypes1.ts, 56, 33), Decl(inferTypes1.ts, 56, 45)) ->U : Symbol(U, Decl(inferTypes1.ts, 56, 33), Decl(inferTypes1.ts, 56, 45)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) +>T : Symbol(T, Decl(inferTypes1.ts, 57, 8)) +>T : Symbol(T, Decl(inferTypes1.ts, 57, 8)) +>a : Symbol(a, Decl(inferTypes1.ts, 57, 24)) +>U : Symbol(U, Decl(inferTypes1.ts, 57, 33), Decl(inferTypes1.ts, 57, 45)) +>b : Symbol(b, Decl(inferTypes1.ts, 57, 36)) +>U : Symbol(U, Decl(inferTypes1.ts, 57, 33), Decl(inferTypes1.ts, 57, 45)) +>U : Symbol(U, Decl(inferTypes1.ts, 57, 33), Decl(inferTypes1.ts, 57, 45)) type T40 = X2<{}>; // never ->T40 : Symbol(T40, Decl(inferTypes1.ts, 56, 62)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 54, 52)) +>T40 : Symbol(T40, Decl(inferTypes1.ts, 57, 62)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) type T41 = X2<{ a: string }>; // never ->T41 : Symbol(T41, Decl(inferTypes1.ts, 58, 18)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 54, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 59, 15)) +>T41 : Symbol(T41, Decl(inferTypes1.ts, 59, 18)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 60, 15)) type T42 = X2<{ a: string, b: string }>; // string ->T42 : Symbol(T42, Decl(inferTypes1.ts, 59, 29)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 54, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 60, 15)) ->b : Symbol(b, Decl(inferTypes1.ts, 60, 26)) - -type T43 = X2<{ a: number, b: string }>; // string | number ->T43 : Symbol(T43, Decl(inferTypes1.ts, 60, 40)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 54, 52)) +>T42 : Symbol(T42, Decl(inferTypes1.ts, 60, 29)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) >a : Symbol(a, Decl(inferTypes1.ts, 61, 15)) >b : Symbol(b, Decl(inferTypes1.ts, 61, 26)) -type T44 = X2<{ a: number, b: string, c: boolean }>; // string | number ->T44 : Symbol(T44, Decl(inferTypes1.ts, 61, 40)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 54, 52)) +type T43 = X2<{ a: number, b: string }>; // string | number +>T43 : Symbol(T43, Decl(inferTypes1.ts, 61, 40)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) >a : Symbol(a, Decl(inferTypes1.ts, 62, 15)) >b : Symbol(b, Decl(inferTypes1.ts, 62, 26)) ->c : Symbol(c, Decl(inferTypes1.ts, 62, 37)) + +type T44 = X2<{ a: number, b: string, c: boolean }>; // string | number +>T44 : Symbol(T44, Decl(inferTypes1.ts, 62, 40)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 63, 15)) +>b : Symbol(b, Decl(inferTypes1.ts, 63, 26)) +>c : Symbol(c, Decl(inferTypes1.ts, 63, 37)) type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never; ->X3 : Symbol(X3, Decl(inferTypes1.ts, 62, 52)) ->T : Symbol(T, Decl(inferTypes1.ts, 64, 8)) ->T : Symbol(T, Decl(inferTypes1.ts, 64, 8)) ->a : Symbol(a, Decl(inferTypes1.ts, 64, 24)) ->x : Symbol(x, Decl(inferTypes1.ts, 64, 29)) ->U : Symbol(U, Decl(inferTypes1.ts, 64, 37), Decl(inferTypes1.ts, 64, 62)) ->b : Symbol(b, Decl(inferTypes1.ts, 64, 49)) ->x : Symbol(x, Decl(inferTypes1.ts, 64, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 64, 37), Decl(inferTypes1.ts, 64, 62)) ->U : Symbol(U, Decl(inferTypes1.ts, 64, 37), Decl(inferTypes1.ts, 64, 62)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) +>T : Symbol(T, Decl(inferTypes1.ts, 65, 8)) +>T : Symbol(T, Decl(inferTypes1.ts, 65, 8)) +>a : Symbol(a, Decl(inferTypes1.ts, 65, 24)) +>x : Symbol(x, Decl(inferTypes1.ts, 65, 29)) +>U : Symbol(U, Decl(inferTypes1.ts, 65, 37), Decl(inferTypes1.ts, 65, 62)) +>b : Symbol(b, Decl(inferTypes1.ts, 65, 49)) +>x : Symbol(x, Decl(inferTypes1.ts, 65, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 65, 37), Decl(inferTypes1.ts, 65, 62)) +>U : Symbol(U, Decl(inferTypes1.ts, 65, 37), Decl(inferTypes1.ts, 65, 62)) type T50 = X3<{}>; // never ->T50 : Symbol(T50, Decl(inferTypes1.ts, 64, 88)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 62, 52)) +>T50 : Symbol(T50, Decl(inferTypes1.ts, 65, 88)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) type T51 = X3<{ a: (x: string) => void }>; // never ->T51 : Symbol(T51, Decl(inferTypes1.ts, 66, 18)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 62, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 67, 15)) ->x : Symbol(x, Decl(inferTypes1.ts, 67, 20)) - -type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string ->T52 : Symbol(T52, Decl(inferTypes1.ts, 67, 42)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 62, 52)) +>T51 : Symbol(T51, Decl(inferTypes1.ts, 67, 18)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) >a : Symbol(a, Decl(inferTypes1.ts, 68, 15)) >x : Symbol(x, Decl(inferTypes1.ts, 68, 20)) ->b : Symbol(b, Decl(inferTypes1.ts, 68, 39)) ->x : Symbol(x, Decl(inferTypes1.ts, 68, 44)) -type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number ->T53 : Symbol(T53, Decl(inferTypes1.ts, 68, 66)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 62, 52)) +type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string +>T52 : Symbol(T52, Decl(inferTypes1.ts, 68, 42)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) >a : Symbol(a, Decl(inferTypes1.ts, 69, 15)) >x : Symbol(x, Decl(inferTypes1.ts, 69, 20)) >b : Symbol(b, Decl(inferTypes1.ts, 69, 39)) >x : Symbol(x, Decl(inferTypes1.ts, 69, 44)) -type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number ->T54 : Symbol(T54, Decl(inferTypes1.ts, 69, 66)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 62, 52)) +type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number +>T53 : Symbol(T53, Decl(inferTypes1.ts, 69, 66)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) >a : Symbol(a, Decl(inferTypes1.ts, 70, 15)) >x : Symbol(x, Decl(inferTypes1.ts, 70, 20)) >b : Symbol(b, Decl(inferTypes1.ts, 70, 39)) +>x : Symbol(x, Decl(inferTypes1.ts, 70, 44)) + +type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number +>T54 : Symbol(T54, Decl(inferTypes1.ts, 70, 66)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 71, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 71, 20)) +>b : Symbol(b, Decl(inferTypes1.ts, 71, 39)) type T60 = infer U; // Error ->T60 : Symbol(T60, Decl(inferTypes1.ts, 70, 57)) ->U : Symbol(U, Decl(inferTypes1.ts, 72, 16)) +>T60 : Symbol(T60, Decl(inferTypes1.ts, 71, 57)) +>U : Symbol(U, Decl(inferTypes1.ts, 73, 16)) type T61 = infer A extends infer B ? infer C : infer D; // Error ->T61 : Symbol(T61, Decl(inferTypes1.ts, 72, 19)) ->T : Symbol(T, Decl(inferTypes1.ts, 73, 9)) ->A : Symbol(A, Decl(inferTypes1.ts, 73, 19)) ->B : Symbol(B, Decl(inferTypes1.ts, 73, 35)) ->C : Symbol(C, Decl(inferTypes1.ts, 73, 45)) ->D : Symbol(D, Decl(inferTypes1.ts, 73, 55)) +>T61 : Symbol(T61, Decl(inferTypes1.ts, 73, 19)) +>T : Symbol(T, Decl(inferTypes1.ts, 74, 9)) +>A : Symbol(A, Decl(inferTypes1.ts, 74, 19)) +>B : Symbol(B, Decl(inferTypes1.ts, 74, 35)) +>C : Symbol(C, Decl(inferTypes1.ts, 74, 45)) +>D : Symbol(D, Decl(inferTypes1.ts, 74, 55)) type T62 = U extends (infer U)[] ? U : U; // Error ->T62 : Symbol(T62, Decl(inferTypes1.ts, 73, 58)) ->T : Symbol(T, Decl(inferTypes1.ts, 74, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 74, 30)) ->U : Symbol(U, Decl(inferTypes1.ts, 74, 30)) +>T62 : Symbol(T62, Decl(inferTypes1.ts, 74, 58)) +>T : Symbol(T, Decl(inferTypes1.ts, 75, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 75, 30)) +>U : Symbol(U, Decl(inferTypes1.ts, 75, 30)) type T63 = T extends (infer A extends infer B ? infer C : infer D) ? string : number; ->T63 : Symbol(T63, Decl(inferTypes1.ts, 74, 44)) ->T : Symbol(T, Decl(inferTypes1.ts, 75, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 75, 9)) ->A : Symbol(A, Decl(inferTypes1.ts, 75, 30)) ->B : Symbol(B, Decl(inferTypes1.ts, 75, 46)) ->C : Symbol(C, Decl(inferTypes1.ts, 75, 56)) ->D : Symbol(D, Decl(inferTypes1.ts, 75, 66)) +>T63 : Symbol(T63, Decl(inferTypes1.ts, 75, 44)) +>T : Symbol(T, Decl(inferTypes1.ts, 76, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 76, 9)) +>A : Symbol(A, Decl(inferTypes1.ts, 76, 30)) +>B : Symbol(B, Decl(inferTypes1.ts, 76, 46)) +>C : Symbol(C, Decl(inferTypes1.ts, 76, 56)) +>D : Symbol(D, Decl(inferTypes1.ts, 76, 66)) type T70 = { x: T }; ->T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) ->T : Symbol(T, Decl(inferTypes1.ts, 77, 9)) ->x : Symbol(x, Decl(inferTypes1.ts, 77, 30)) ->T : Symbol(T, Decl(inferTypes1.ts, 77, 9)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) +>T : Symbol(T, Decl(inferTypes1.ts, 78, 9)) +>x : Symbol(x, Decl(inferTypes1.ts, 78, 30)) +>T : Symbol(T, Decl(inferTypes1.ts, 78, 9)) type T71 = T extends T70 ? T70 : never; ->T71 : Symbol(T71, Decl(inferTypes1.ts, 77, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 78, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 78, 9)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) ->U : Symbol(U, Decl(inferTypes1.ts, 78, 33)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) ->U : Symbol(U, Decl(inferTypes1.ts, 78, 33)) +>T71 : Symbol(T71, Decl(inferTypes1.ts, 78, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 79, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 79, 9)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 79, 33)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 79, 33)) type T72 = { y: T }; ->T72 : Symbol(T72, Decl(inferTypes1.ts, 78, 54)) ->T : Symbol(T, Decl(inferTypes1.ts, 80, 9)) ->y : Symbol(y, Decl(inferTypes1.ts, 80, 30)) ->T : Symbol(T, Decl(inferTypes1.ts, 80, 9)) +>T72 : Symbol(T72, Decl(inferTypes1.ts, 79, 54)) +>T : Symbol(T, Decl(inferTypes1.ts, 81, 9)) +>y : Symbol(y, Decl(inferTypes1.ts, 81, 30)) +>T : Symbol(T, Decl(inferTypes1.ts, 81, 9)) type T73 = T extends T72 ? T70 : never; // Error ->T73 : Symbol(T73, Decl(inferTypes1.ts, 80, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 81, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 81, 9)) ->T72 : Symbol(T72, Decl(inferTypes1.ts, 78, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 81, 33)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) ->U : Symbol(U, Decl(inferTypes1.ts, 81, 33)) +>T73 : Symbol(T73, Decl(inferTypes1.ts, 81, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 82, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 82, 9)) +>T72 : Symbol(T72, Decl(inferTypes1.ts, 79, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 82, 33)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 82, 33)) type T74 = { x: T, y: U }; ->T74 : Symbol(T74, Decl(inferTypes1.ts, 81, 54)) ->T : Symbol(T, Decl(inferTypes1.ts, 83, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 83, 26)) ->x : Symbol(x, Decl(inferTypes1.ts, 83, 48)) ->T : Symbol(T, Decl(inferTypes1.ts, 83, 9)) ->y : Symbol(y, Decl(inferTypes1.ts, 83, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 83, 26)) +>T74 : Symbol(T74, Decl(inferTypes1.ts, 82, 54)) +>T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 84, 26)) +>x : Symbol(x, Decl(inferTypes1.ts, 84, 48)) +>T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) +>y : Symbol(y, Decl(inferTypes1.ts, 84, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 84, 26)) type T75 = T extends T74 ? T70 | T72 | T74 : never; ->T75 : Symbol(T75, Decl(inferTypes1.ts, 83, 62)) ->T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) ->T74 : Symbol(T74, Decl(inferTypes1.ts, 81, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) ->U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) ->U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) ->T72 : Symbol(T72, Decl(inferTypes1.ts, 78, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) ->T74 : Symbol(T74, Decl(inferTypes1.ts, 81, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) ->U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) +>T75 : Symbol(T75, Decl(inferTypes1.ts, 84, 62)) +>T : Symbol(T, Decl(inferTypes1.ts, 85, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 85, 9)) +>T74 : Symbol(T74, Decl(inferTypes1.ts, 82, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) +>U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) +>T72 : Symbol(T72, Decl(inferTypes1.ts, 79, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) +>T74 : Symbol(T74, Decl(inferTypes1.ts, 82, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) +>U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) type T76 = { x: T }; ->T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) ->T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 86, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) ->x : Symbol(x, Decl(inferTypes1.ts, 86, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) +>T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 87, 23)) +>T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) +>x : Symbol(x, Decl(inferTypes1.ts, 87, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) type T77 = T extends T76 ? T76 : never; ->T77 : Symbol(T77, Decl(inferTypes1.ts, 86, 48)) ->T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 87, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 87, 42)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 87, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 87, 42)) +>T77 : Symbol(T77, Decl(inferTypes1.ts, 87, 48)) +>T : Symbol(T, Decl(inferTypes1.ts, 88, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 88, 9)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 88, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 88, 42)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 88, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 88, 42)) type T78 = T extends T76 ? T76 : never; ->T78 : Symbol(T78, Decl(inferTypes1.ts, 87, 66)) ->T : Symbol(T, Decl(inferTypes1.ts, 88, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 88, 9)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 88, 33), Decl(inferTypes1.ts, 88, 42)) ->X : Symbol(X, Decl(inferTypes1.ts, 88, 33), Decl(inferTypes1.ts, 88, 42)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 88, 33), Decl(inferTypes1.ts, 88, 42)) ->X : Symbol(X, Decl(inferTypes1.ts, 88, 33), Decl(inferTypes1.ts, 88, 42)) +>T78 : Symbol(T78, Decl(inferTypes1.ts, 88, 66)) +>T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 89, 33), Decl(inferTypes1.ts, 89, 42)) +>X : Symbol(X, Decl(inferTypes1.ts, 89, 33), Decl(inferTypes1.ts, 89, 42)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 89, 33), Decl(inferTypes1.ts, 89, 42)) +>X : Symbol(X, Decl(inferTypes1.ts, 89, 33), Decl(inferTypes1.ts, 89, 42)) type Foo = [T, U]; ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 88, 66)) ->T : Symbol(T, Decl(inferTypes1.ts, 90, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 90, 26)) ->T : Symbol(T, Decl(inferTypes1.ts, 90, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 90, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 90, 26)) +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 89, 66)) +>T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 91, 26)) +>T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 91, 26)) type Bar = T extends Foo ? Foo : never; ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) ->T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 88, 66)) ->X : Symbol(X, Decl(inferTypes1.ts, 91, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 91, 42)) ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 88, 66)) ->X : Symbol(X, Decl(inferTypes1.ts, 91, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 91, 42)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) +>T : Symbol(T, Decl(inferTypes1.ts, 92, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 92, 9)) +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 89, 66)) +>X : Symbol(X, Decl(inferTypes1.ts, 92, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 92, 42)) +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 89, 66)) +>X : Symbol(X, Decl(inferTypes1.ts, 92, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 92, 42)) type T90 = Bar<[string, string]>; // [string, string] ->T90 : Symbol(T90, Decl(inferTypes1.ts, 91, 66)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) +>T90 : Symbol(T90, Decl(inferTypes1.ts, 92, 66)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) type T91 = Bar<[string, "a"]>; // [string, "a"] ->T91 : Symbol(T91, Decl(inferTypes1.ts, 93, 33)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) +>T91 : Symbol(T91, Decl(inferTypes1.ts, 94, 33)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"] ->T92 : Symbol(T92, Decl(inferTypes1.ts, 94, 30)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) ->x : Symbol(x, Decl(inferTypes1.ts, 95, 32)) +>T92 : Symbol(T92, Decl(inferTypes1.ts, 95, 30)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) +>x : Symbol(x, Decl(inferTypes1.ts, 96, 32)) type T93 = Bar<["a", string]>; // never ->T93 : Symbol(T93, Decl(inferTypes1.ts, 95, 46)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) +>T93 : Symbol(T93, Decl(inferTypes1.ts, 96, 46)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) type T94 = Bar<[number, number]>; // never ->T94 : Symbol(T94, Decl(inferTypes1.ts, 96, 30)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) +>T94 : Symbol(T94, Decl(inferTypes1.ts, 97, 30)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) // Example from #21496 type JsonifiedObject = { [K in keyof T]: Jsonified }; ->JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 97, 33)) ->T : Symbol(T, Decl(inferTypes1.ts, 101, 21)) ->K : Symbol(K, Decl(inferTypes1.ts, 101, 44)) ->T : Symbol(T, Decl(inferTypes1.ts, 101, 21)) ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 101, 77)) ->T : Symbol(T, Decl(inferTypes1.ts, 101, 21)) ->K : Symbol(K, Decl(inferTypes1.ts, 101, 44)) +>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 98, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 102, 21)) +>K : Symbol(K, Decl(inferTypes1.ts, 102, 44)) +>T : Symbol(T, Decl(inferTypes1.ts, 102, 21)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 102, 77)) +>T : Symbol(T, Decl(inferTypes1.ts, 102, 21)) +>K : Symbol(K, Decl(inferTypes1.ts, 102, 44)) type Jsonified = ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 101, 77)) ->T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 102, 77)) +>T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) T extends string | number | boolean | null ? T ->T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) ->T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) : T extends undefined | Function ? never // undefined and functions are removed ->T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) : T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date) ->T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) ->toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 106, 17)) ->R : Symbol(R, Decl(inferTypes1.ts, 106, 33)) ->R : Symbol(R, Decl(inferTypes1.ts, 106, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) +>toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 107, 17)) +>R : Symbol(R, Decl(inferTypes1.ts, 107, 33)) +>R : Symbol(R, Decl(inferTypes1.ts, 107, 33)) : T extends object ? JsonifiedObject ->T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) ->JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 97, 33)) ->T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) +>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 98, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) : "what is this"; type Example = { ->Example : Symbol(Example, Decl(inferTypes1.ts, 108, 21)) +>Example : Symbol(Example, Decl(inferTypes1.ts, 109, 21)) str: "literalstring", ->str : Symbol(str, Decl(inferTypes1.ts, 110, 16)) +>str : Symbol(str, Decl(inferTypes1.ts, 111, 16)) fn: () => void, ->fn : Symbol(fn, Decl(inferTypes1.ts, 111, 25)) +>fn : Symbol(fn, Decl(inferTypes1.ts, 112, 25)) date: Date, ->date : Symbol(date, Decl(inferTypes1.ts, 112, 19)) +>date : Symbol(date, Decl(inferTypes1.ts, 113, 19)) >Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) customClass: MyClass, ->customClass : Symbol(customClass, Decl(inferTypes1.ts, 113, 15)) ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 120, 1)) +>customClass : Symbol(customClass, Decl(inferTypes1.ts, 114, 15)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 121, 1)) obj: { ->obj : Symbol(obj, Decl(inferTypes1.ts, 114, 25)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 115, 25)) prop: "property", ->prop : Symbol(prop, Decl(inferTypes1.ts, 115, 10)) +>prop : Symbol(prop, Decl(inferTypes1.ts, 116, 10)) clz: MyClass, ->clz : Symbol(clz, Decl(inferTypes1.ts, 116, 25)) ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 120, 1)) +>clz : Symbol(clz, Decl(inferTypes1.ts, 117, 25)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 121, 1)) nested: { attr: Date } ->nested : Symbol(nested, Decl(inferTypes1.ts, 117, 21)) ->attr : Symbol(attr, Decl(inferTypes1.ts, 118, 17)) +>nested : Symbol(nested, Decl(inferTypes1.ts, 118, 21)) +>attr : Symbol(attr, Decl(inferTypes1.ts, 119, 17)) >Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) }, } declare class MyClass { ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 120, 1)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 121, 1)) toJSON(): "correct"; ->toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 122, 23)) +>toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 123, 23)) } type JsonifiedExample = Jsonified; ->JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 124, 1)) ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 101, 77)) ->Example : Symbol(Example, Decl(inferTypes1.ts, 108, 21)) +>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 125, 1)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 102, 77)) +>Example : Symbol(Example, Decl(inferTypes1.ts, 109, 21)) declare let ex: JsonifiedExample; ->ex : Symbol(ex, Decl(inferTypes1.ts, 127, 11)) ->JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 124, 1)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 128, 11)) +>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 125, 1)) const z1: "correct" = ex.customClass; ->z1 : Symbol(z1, Decl(inferTypes1.ts, 128, 5)) ->ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 113, 15)) ->ex : Symbol(ex, Decl(inferTypes1.ts, 127, 11)) ->customClass : Symbol(customClass, Decl(inferTypes1.ts, 113, 15)) +>z1 : Symbol(z1, Decl(inferTypes1.ts, 129, 5)) +>ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 114, 15)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 128, 11)) +>customClass : Symbol(customClass, Decl(inferTypes1.ts, 114, 15)) const z2: string = ex.obj.nested.attr; ->z2 : Symbol(z2, Decl(inferTypes1.ts, 129, 5)) ->ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 118, 17)) ->ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 117, 21)) ->ex.obj : Symbol(obj, Decl(inferTypes1.ts, 114, 25)) ->ex : Symbol(ex, Decl(inferTypes1.ts, 127, 11)) ->obj : Symbol(obj, Decl(inferTypes1.ts, 114, 25)) ->nested : Symbol(nested, Decl(inferTypes1.ts, 117, 21)) ->attr : Symbol(attr, Decl(inferTypes1.ts, 118, 17)) +>z2 : Symbol(z2, Decl(inferTypes1.ts, 130, 5)) +>ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 119, 17)) +>ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 118, 21)) +>ex.obj : Symbol(obj, Decl(inferTypes1.ts, 115, 25)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 128, 11)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 115, 25)) +>nested : Symbol(nested, Decl(inferTypes1.ts, 118, 21)) +>attr : Symbol(attr, Decl(inferTypes1.ts, 119, 17)) // Repros from #21631 type A1> = [T, U]; ->A1 : Symbol(A1, Decl(inferTypes1.ts, 129, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 133, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 133, 10)) ->A1 : Symbol(A1, Decl(inferTypes1.ts, 129, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 133, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 133, 10)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 130, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 134, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 134, 10)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 130, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 134, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 134, 10)) type B1 = S extends A1 ? [T, U] : never; ->B1 : Symbol(B1, Decl(inferTypes1.ts, 133, 44)) ->S : Symbol(S, Decl(inferTypes1.ts, 134, 8)) ->S : Symbol(S, Decl(inferTypes1.ts, 134, 8)) ->A1 : Symbol(A1, Decl(inferTypes1.ts, 129, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 134, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 134, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 134, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 134, 40)) +>B1 : Symbol(B1, Decl(inferTypes1.ts, 134, 44)) +>S : Symbol(S, Decl(inferTypes1.ts, 135, 8)) +>S : Symbol(S, Decl(inferTypes1.ts, 135, 8)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 130, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 135, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 135, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 135, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 135, 40)) type A2 = [T, U]; ->A2 : Symbol(A2, Decl(inferTypes1.ts, 134, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 136, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 136, 10)) ->T : Symbol(T, Decl(inferTypes1.ts, 136, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 136, 10)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 135, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 137, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 137, 10)) +>T : Symbol(T, Decl(inferTypes1.ts, 137, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 137, 10)) type B2 = S extends A2 ? [T, U] : never; ->B2 : Symbol(B2, Decl(inferTypes1.ts, 136, 36)) ->S : Symbol(S, Decl(inferTypes1.ts, 137, 8)) ->S : Symbol(S, Decl(inferTypes1.ts, 137, 8)) ->A2 : Symbol(A2, Decl(inferTypes1.ts, 134, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 137, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 137, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 137, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 137, 40)) +>B2 : Symbol(B2, Decl(inferTypes1.ts, 137, 36)) +>S : Symbol(S, Decl(inferTypes1.ts, 138, 8)) +>S : Symbol(S, Decl(inferTypes1.ts, 138, 8)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 135, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 138, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 138, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 138, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 138, 40)) type C2 = S extends A2 ? [T, U] : never; ->C2 : Symbol(C2, Decl(inferTypes1.ts, 137, 61)) ->S : Symbol(S, Decl(inferTypes1.ts, 138, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 138, 10)) ->S : Symbol(S, Decl(inferTypes1.ts, 138, 8)) ->A2 : Symbol(A2, Decl(inferTypes1.ts, 134, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 138, 47)) ->U : Symbol(U, Decl(inferTypes1.ts, 138, 10)) ->T : Symbol(T, Decl(inferTypes1.ts, 138, 47)) ->U : Symbol(U, Decl(inferTypes1.ts, 138, 10)) +>C2 : Symbol(C2, Decl(inferTypes1.ts, 138, 61)) +>S : Symbol(S, Decl(inferTypes1.ts, 139, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 139, 10)) +>S : Symbol(S, Decl(inferTypes1.ts, 139, 8)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 135, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 139, 47)) +>U : Symbol(U, Decl(inferTypes1.ts, 139, 10)) +>T : Symbol(T, Decl(inferTypes1.ts, 139, 47)) +>U : Symbol(U, Decl(inferTypes1.ts, 139, 10)) // Repro from #21735 type A = T extends string ? { [P in T]: void; } : T; ->A : Symbol(A, Decl(inferTypes1.ts, 138, 71)) ->T : Symbol(T, Decl(inferTypes1.ts, 142, 7)) ->T : Symbol(T, Decl(inferTypes1.ts, 142, 7)) ->P : Symbol(P, Decl(inferTypes1.ts, 142, 34)) ->T : Symbol(T, Decl(inferTypes1.ts, 142, 7)) ->T : Symbol(T, Decl(inferTypes1.ts, 142, 7)) - -type B = string extends T ? { [P in T]: void; } : T; // Error ->B : Symbol(B, Decl(inferTypes1.ts, 142, 55)) +>A : Symbol(A, Decl(inferTypes1.ts, 139, 71)) >T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) >T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) >P : Symbol(P, Decl(inferTypes1.ts, 143, 34)) >T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) >T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) +type B = string extends T ? { [P in T]: void; } : T; // Error +>B : Symbol(B, Decl(inferTypes1.ts, 143, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 144, 7)) +>T : Symbol(T, Decl(inferTypes1.ts, 144, 7)) +>P : Symbol(P, Decl(inferTypes1.ts, 144, 34)) +>T : Symbol(T, Decl(inferTypes1.ts, 144, 7)) +>T : Symbol(T, Decl(inferTypes1.ts, 144, 7)) + // Repro from #22302 type MatchingKeys = ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 143, 55)) ->T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) ->U : Symbol(U, Decl(inferTypes1.ts, 147, 20)) ->K : Symbol(K, Decl(inferTypes1.ts, 147, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 144, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) +>U : Symbol(U, Decl(inferTypes1.ts, 148, 20)) +>K : Symbol(K, Decl(inferTypes1.ts, 148, 23)) +>T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) K extends keyof T ? T[K] extends U ? K : never : never; ->K : Symbol(K, Decl(inferTypes1.ts, 147, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) ->K : Symbol(K, Decl(inferTypes1.ts, 147, 23)) ->U : Symbol(U, Decl(inferTypes1.ts, 147, 20)) ->K : Symbol(K, Decl(inferTypes1.ts, 147, 23)) +>K : Symbol(K, Decl(inferTypes1.ts, 148, 23)) +>T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) +>K : Symbol(K, Decl(inferTypes1.ts, 148, 23)) +>U : Symbol(U, Decl(inferTypes1.ts, 148, 20)) +>K : Symbol(K, Decl(inferTypes1.ts, 148, 23)) type VoidKeys = MatchingKeys; ->VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 148, 59)) ->T : Symbol(T, Decl(inferTypes1.ts, 150, 14)) ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 143, 55)) ->T : Symbol(T, Decl(inferTypes1.ts, 150, 14)) +>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 149, 59)) +>T : Symbol(T, Decl(inferTypes1.ts, 151, 14)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 144, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 151, 14)) interface test { ->test : Symbol(test, Decl(inferTypes1.ts, 150, 41)) +>test : Symbol(test, Decl(inferTypes1.ts, 151, 41)) a: 1, ->a : Symbol(test.a, Decl(inferTypes1.ts, 152, 16)) +>a : Symbol(test.a, Decl(inferTypes1.ts, 153, 16)) b: void ->b : Symbol(test.b, Decl(inferTypes1.ts, 153, 9)) +>b : Symbol(test.b, Decl(inferTypes1.ts, 154, 9)) } type T80 = MatchingKeys; ->T80 : Symbol(T80, Decl(inferTypes1.ts, 155, 1)) ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 143, 55)) ->test : Symbol(test, Decl(inferTypes1.ts, 150, 41)) +>T80 : Symbol(T80, Decl(inferTypes1.ts, 156, 1)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 144, 55)) +>test : Symbol(test, Decl(inferTypes1.ts, 151, 41)) type T81 = VoidKeys; ->T81 : Symbol(T81, Decl(inferTypes1.ts, 157, 36)) ->VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 148, 59)) ->test : Symbol(test, Decl(inferTypes1.ts, 150, 41)) +>T81 : Symbol(T81, Decl(inferTypes1.ts, 158, 36)) +>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 149, 59)) +>test : Symbol(test, Decl(inferTypes1.ts, 151, 41)) // Repro from #22221 type MustBeString = T; ->MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 158, 26)) ->T : Symbol(T, Decl(inferTypes1.ts, 162, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 162, 18)) +>MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 159, 26)) +>T : Symbol(T, Decl(inferTypes1.ts, 163, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 163, 18)) type EnsureIsString = T extends MustBeString ? U : never; ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 162, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 163, 20)) ->T : Symbol(T, Decl(inferTypes1.ts, 163, 20)) ->MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 158, 26)) ->U : Symbol(U, Decl(inferTypes1.ts, 163, 53)) ->U : Symbol(U, Decl(inferTypes1.ts, 163, 53)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 163, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 164, 20)) +>T : Symbol(T, Decl(inferTypes1.ts, 164, 20)) +>MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 159, 26)) +>U : Symbol(U, Decl(inferTypes1.ts, 164, 53)) +>U : Symbol(U, Decl(inferTypes1.ts, 164, 53)) type Test1 = EnsureIsString<"hello">; // "hello" ->Test1 : Symbol(Test1, Decl(inferTypes1.ts, 163, 69)) ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 162, 40)) +>Test1 : Symbol(Test1, Decl(inferTypes1.ts, 164, 69)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 163, 40)) type Test2 = EnsureIsString<42>; // never ->Test2 : Symbol(Test2, Decl(inferTypes1.ts, 165, 37)) ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 162, 40)) +>Test2 : Symbol(Test2, Decl(inferTypes1.ts, 166, 37)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 163, 40)) + +// Repros from #26856 + +function invoker (key: K, ...args: A) { +>invoker : Symbol(invoker, Decl(inferTypes1.ts, 167, 32)) +>K : Symbol(K, Decl(inferTypes1.ts, 171, 18)) +>A : Symbol(A, Decl(inferTypes1.ts, 171, 53)) +>key : Symbol(key, Decl(inferTypes1.ts, 171, 72)) +>K : Symbol(K, Decl(inferTypes1.ts, 171, 18)) +>args : Symbol(args, Decl(inferTypes1.ts, 171, 79)) +>A : Symbol(A, Decl(inferTypes1.ts, 171, 53)) + + return any>> (obj: T): ReturnType => obj[key](...args) +>T : Symbol(T, Decl(inferTypes1.ts, 172, 12)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(inferTypes1.ts, 171, 18)) +>args : Symbol(args, Decl(inferTypes1.ts, 172, 33)) +>A : Symbol(A, Decl(inferTypes1.ts, 171, 53)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 172, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 172, 12)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(inferTypes1.ts, 172, 12)) +>K : Symbol(K, Decl(inferTypes1.ts, 171, 18)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 172, 55)) +>key : Symbol(key, Decl(inferTypes1.ts, 171, 72)) +>args : Symbol(args, Decl(inferTypes1.ts, 171, 79)) +} + +const result = invoker('test', true)({ test: (a: boolean) => 123 }) +>result : Symbol(result, Decl(inferTypes1.ts, 175, 5)) +>invoker : Symbol(invoker, Decl(inferTypes1.ts, 167, 32)) +>test : Symbol(test, Decl(inferTypes1.ts, 175, 38)) +>a : Symbol(a, Decl(inferTypes1.ts, 175, 46)) + +type Foo2 = ReturnType<(...args: A) => string>; +>Foo2 : Symbol(Foo2, Decl(inferTypes1.ts, 175, 67)) +>A : Symbol(A, Decl(inferTypes1.ts, 177, 10)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(inferTypes1.ts, 177, 41)) +>A : Symbol(A, Decl(inferTypes1.ts, 177, 10)) diff --git a/tests/baselines/reference/inferTypes1.types b/tests/baselines/reference/inferTypes1.types index 8bcdf4a92cb..c3f51879979 100644 --- a/tests/baselines/reference/inferTypes1.types +++ b/tests/baselines/reference/inferTypes1.types @@ -83,6 +83,11 @@ type T17 = ReturnType; // Error type T18 = ReturnType; // Error >T18 : any +type T19 = ReturnType<(x: string, ...args: T) => T[]>; // T[] +>T19 : T[] +>x : string +>args : T + type U10 = InstanceType; // C >U10 : C >C : typeof C @@ -426,3 +431,39 @@ type Test1 = EnsureIsString<"hello">; // "hello" type Test2 = EnsureIsString<42>; // never >Test2 : never +// Repros from #26856 + +function invoker (key: K, ...args: A) { +>invoker : (key: K, ...args: A) => any>>(obj: T) => ReturnType +>key : K +>args : A + + return any>> (obj: T): ReturnType => obj[key](...args) +> any>> (obj: T): ReturnType => obj[key](...args) : any>>(obj: T) => ReturnType +>args : A +>obj : T +>obj[key](...args) : any +>obj[key] : T[K] +>obj : T +>key : K +>...args : any +>args : A +} + +const result = invoker('test', true)({ test: (a: boolean) => 123 }) +>result : number +>invoker('test', true)({ test: (a: boolean) => 123 }) : number +>invoker('test', true) : any>>(obj: T) => ReturnType +>invoker : (key: K, ...args: A) => any>>(obj: T) => ReturnType +>'test' : "test" +>true : true +>{ test: (a: boolean) => 123 } : { test: (a: boolean) => number; } +>test : (a: boolean) => number +>(a: boolean) => 123 : (a: boolean) => number +>a : boolean +>123 : 123 + +type Foo2 = ReturnType<(...args: A) => string>; +>Foo2 : string +>args : A + From 343e0f7fd980be44523fc5db9520e21ba4b0c1c4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 3 Feb 2019 08:19:22 -0800 Subject: [PATCH 36/42] Fix NarrowTypeByTypeof, NarrowTypeByInstanceof, isPropertyInitializedInConstructor --- src/compiler/checker.ts | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2e6259b668a..84d4132e61f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15045,11 +15045,6 @@ namespace ts { return false; } - function hasNarrowableDeclaredType(expr: Node) { - const type = getDeclaredTypeOfReference(expr); - return !!(type && type.flags & TypeFlags.Union); - } - function findDiscriminantProperties(sourceProperties: Symbol[], target: Type): Symbol[] | undefined { let result: Symbol[] | undefined; for (const sourceProperty of sourceProperties) { @@ -16107,9 +16102,9 @@ namespace ts { // We have '==', '!=', '====', or !==' operator with 'typeof xxx' and string literal operands const target = getReferenceCandidate(typeOfExpr.expression); if (!isMatchingReference(reference, target)) { - // For a reference of the form 'x.y', where 'x' has a narrowable declared type, a - // 'typeof x === ...' type guard resets the narrowed type of 'y' to its declared type. - if (containsMatchingReference(reference, target) && hasNarrowableDeclaredType(target)) { + // For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the + // narrowed type of 'y' to its declared type. + if (containsMatchingReference(reference, target)) { return declaredType; } return type; @@ -16264,9 +16259,9 @@ namespace ts { function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type { const left = getReferenceCandidate(expr.left); if (!isMatchingReference(reference, left)) { - // For a reference of the form 'x.y', where 'x' has a narrowable declared type, an - // 'x instanceof T' type guard resets the narrowed type of 'y' to its declared type. - if (containsMatchingReference(reference, left) && hasNarrowableDeclaredType(left)) { + // For a reference of the form 'x.y', an 'x instanceof T' type guard resets the + // narrowed type of 'y' to its declared type. + if (containsMatchingReference(reference, left)) { return declaredType; } return type; @@ -27221,7 +27216,7 @@ namespace ts { reference.expression.parent = reference; reference.parent = constructor; reference.flowNode = constructor.returnFlowNode; - const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); + const flowType = getFlowTypeOfReference(reference, getOptionalType(propType)); return !(getFalsyFlags(flowType) & TypeFlags.Undefined); } From 30fa6d08cc5da961632037bab4bc4f2355c32aa5 Mon Sep 17 00:00:00 2001 From: Jack Williams Date: Sun, 3 Feb 2019 16:49:52 +0000 Subject: [PATCH 37/42] Update baselines for types affected by JSON change --- .../destructuringInitializerContextualTypeFromContext.types | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/destructuringInitializerContextualTypeFromContext.types b/tests/baselines/reference/destructuringInitializerContextualTypeFromContext.types index 4018d4bed3f..d0ddb4918a0 100644 --- a/tests/baselines/reference/destructuringInitializerContextualTypeFromContext.types +++ b/tests/baselines/reference/destructuringInitializerContextualTypeFromContext.types @@ -50,9 +50,9 @@ const Child: SFC = ({ >`name: ${name} props: ${JSON.stringify(props)}` : string >name : "Apollo" | "Artemis" | "Dionysus" | "Persephone" >JSON.stringify(props) : string ->JSON.stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>JSON.stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >JSON : JSON ->stringify : { (value: any, replacer?: ((key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } +>stringify : { (value: any, replacer?: ((this: any, key: string, value: any) => any) | undefined, space?: string | number | undefined): string; (value: any, replacer?: (string | number)[] | null | undefined, space?: string | number | undefined): string; } >props : {} // Repro from #29189 From 415c725bb91606b1446ada82dca6bac5a6052d03 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 3 Feb 2019 15:23:07 -0800 Subject: [PATCH 38/42] Make exception for synthetic 'this.x' in narrowTypeByInstanceof --- src/compiler/checker.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 84d4132e61f..d5e4b29d44f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15045,6 +15045,10 @@ namespace ts { return false; } + function isSyntheticThisPropertyAccess(expr: Node) { + return isAccessExpression(expr) && expr.expression.kind === SyntaxKind.ThisKeyword && !!(expr.expression.flags & NodeFlags.Synthesized); + } + function findDiscriminantProperties(sourceProperties: Symbol[], target: Type): Symbol[] | undefined { let result: Symbol[] | undefined; for (const sourceProperty of sourceProperties) { @@ -16260,8 +16264,13 @@ namespace ts { const left = getReferenceCandidate(expr.left); if (!isMatchingReference(reference, left)) { // For a reference of the form 'x.y', an 'x instanceof T' type guard resets the - // narrowed type of 'y' to its declared type. - if (containsMatchingReference(reference, left)) { + // narrowed type of 'y' to its declared type. We do this because preceding 'x.y' + // references might reference a different 'y' property. However, we make an exception + // for property accesses where x is a synthetic 'this' expression, indicating that we + // were called from isPropertyInitializedInConstructor. Without this exception, + // initializations of 'this' properties that occur before a 'this instanceof XXX' + // check would not be considered. + if (containsMatchingReference(reference, left) && !isSyntheticThisPropertyAccess(reference)) { return declaredType; } return type; From 0c5471ba5cb1eab73661b21d9d9a5d19f7286f8a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 3 Feb 2019 15:23:21 -0800 Subject: [PATCH 39/42] Add regression test --- .../cases/compiler/narrowingOfDottedNames.ts | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/cases/compiler/narrowingOfDottedNames.ts b/tests/cases/compiler/narrowingOfDottedNames.ts index 4e504e4133e..299dfff3be7 100644 --- a/tests/cases/compiler/narrowingOfDottedNames.ts +++ b/tests/cases/compiler/narrowingOfDottedNames.ts @@ -57,3 +57,36 @@ class Foo2 constructor() { } } + +// Repro from #29513 + +class AInfo { + a_count: number = 1; +} + +class BInfo { + b_count: number = 1; +} + +class Base { + id: number = 0; +} + +class A2 extends Base { + info!: AInfo; +} + +class B2 extends Base { + info!: BInfo; +} + +let target: Base = null as any; + +while (target) { + if (target instanceof A2) { + target.info.a_count = 3; + } + else if (target instanceof B2) { + const j: BInfo = target.info; + } +} From 026225997e54dbaac834472d985d457b7c43dab6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 3 Feb 2019 15:23:49 -0800 Subject: [PATCH 40/42] Accept new baselines --- .../narrowingOfDottedNames.errors.txt | 33 +++++++ .../reference/narrowingOfDottedNames.js | 88 +++++++++++++++++++ .../reference/narrowingOfDottedNames.symbols | 72 +++++++++++++++ .../reference/narrowingOfDottedNames.types | 77 ++++++++++++++++ 4 files changed, 270 insertions(+) diff --git a/tests/baselines/reference/narrowingOfDottedNames.errors.txt b/tests/baselines/reference/narrowingOfDottedNames.errors.txt index f5bf833c4e0..1cc8fa4df8d 100644 --- a/tests/baselines/reference/narrowingOfDottedNames.errors.txt +++ b/tests/baselines/reference/narrowingOfDottedNames.errors.txt @@ -64,4 +64,37 @@ tests/cases/compiler/narrowingOfDottedNames.ts(54,5): error TS2564: Property 'x' constructor() { } } + + // Repro from #29513 + + class AInfo { + a_count: number = 1; + } + + class BInfo { + b_count: number = 1; + } + + class Base { + id: number = 0; + } + + class A2 extends Base { + info!: AInfo; + } + + class B2 extends Base { + info!: BInfo; + } + + let target: Base = null as any; + + while (target) { + if (target instanceof A2) { + target.info.a_count = 3; + } + else if (target instanceof B2) { + const j: BInfo = target.info; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/narrowingOfDottedNames.js b/tests/baselines/reference/narrowingOfDottedNames.js index 5d6ef2aaaa0..4b4d9ada399 100644 --- a/tests/baselines/reference/narrowingOfDottedNames.js +++ b/tests/baselines/reference/narrowingOfDottedNames.js @@ -56,11 +56,57 @@ class Foo2 constructor() { } } + +// Repro from #29513 + +class AInfo { + a_count: number = 1; +} + +class BInfo { + b_count: number = 1; +} + +class Base { + id: number = 0; +} + +class A2 extends Base { + info!: AInfo; +} + +class B2 extends Base { + info!: BInfo; +} + +let target: Base = null as any; + +while (target) { + if (target instanceof A2) { + target.info.a_count = 3; + } + else if (target instanceof B2) { + const j: BInfo = target.info; + } +} //// [narrowingOfDottedNames.js] "use strict"; // Repro from #8383 +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); var A = /** @class */ (function () { function A() { } @@ -110,3 +156,45 @@ var Foo2 = /** @class */ (function () { } return Foo2; }()); +// Repro from #29513 +var AInfo = /** @class */ (function () { + function AInfo() { + this.a_count = 1; + } + return AInfo; +}()); +var BInfo = /** @class */ (function () { + function BInfo() { + this.b_count = 1; + } + return BInfo; +}()); +var Base = /** @class */ (function () { + function Base() { + this.id = 0; + } + return Base; +}()); +var A2 = /** @class */ (function (_super) { + __extends(A2, _super); + function A2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return A2; +}(Base)); +var B2 = /** @class */ (function (_super) { + __extends(B2, _super); + function B2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return B2; +}(Base)); +var target = null; +while (target) { + if (target instanceof A2) { + target.info.a_count = 3; + } + else if (target instanceof B2) { + var j = target.info; + } +} diff --git a/tests/baselines/reference/narrowingOfDottedNames.symbols b/tests/baselines/reference/narrowingOfDottedNames.symbols index a045c83cae4..781c73f68fe 100644 --- a/tests/baselines/reference/narrowingOfDottedNames.symbols +++ b/tests/baselines/reference/narrowingOfDottedNames.symbols @@ -129,3 +129,75 @@ class Foo2 } } +// Repro from #29513 + +class AInfo { +>AInfo : Symbol(AInfo, Decl(narrowingOfDottedNames.ts, 56, 1)) + + a_count: number = 1; +>a_count : Symbol(AInfo.a_count, Decl(narrowingOfDottedNames.ts, 60, 13)) +} + +class BInfo { +>BInfo : Symbol(BInfo, Decl(narrowingOfDottedNames.ts, 62, 1)) + + b_count: number = 1; +>b_count : Symbol(BInfo.b_count, Decl(narrowingOfDottedNames.ts, 64, 13)) +} + +class Base { +>Base : Symbol(Base, Decl(narrowingOfDottedNames.ts, 66, 1)) + + id: number = 0; +>id : Symbol(Base.id, Decl(narrowingOfDottedNames.ts, 68, 12)) +} + +class A2 extends Base { +>A2 : Symbol(A2, Decl(narrowingOfDottedNames.ts, 70, 1)) +>Base : Symbol(Base, Decl(narrowingOfDottedNames.ts, 66, 1)) + + info!: AInfo; +>info : Symbol(A2.info, Decl(narrowingOfDottedNames.ts, 72, 23)) +>AInfo : Symbol(AInfo, Decl(narrowingOfDottedNames.ts, 56, 1)) +} + +class B2 extends Base { +>B2 : Symbol(B2, Decl(narrowingOfDottedNames.ts, 74, 1)) +>Base : Symbol(Base, Decl(narrowingOfDottedNames.ts, 66, 1)) + + info!: BInfo; +>info : Symbol(B2.info, Decl(narrowingOfDottedNames.ts, 76, 23)) +>BInfo : Symbol(BInfo, Decl(narrowingOfDottedNames.ts, 62, 1)) +} + +let target: Base = null as any; +>target : Symbol(target, Decl(narrowingOfDottedNames.ts, 80, 3)) +>Base : Symbol(Base, Decl(narrowingOfDottedNames.ts, 66, 1)) + +while (target) { +>target : Symbol(target, Decl(narrowingOfDottedNames.ts, 80, 3)) + + if (target instanceof A2) { +>target : Symbol(target, Decl(narrowingOfDottedNames.ts, 80, 3)) +>A2 : Symbol(A2, Decl(narrowingOfDottedNames.ts, 70, 1)) + + target.info.a_count = 3; +>target.info.a_count : Symbol(AInfo.a_count, Decl(narrowingOfDottedNames.ts, 60, 13)) +>target.info : Symbol(A2.info, Decl(narrowingOfDottedNames.ts, 72, 23)) +>target : Symbol(target, Decl(narrowingOfDottedNames.ts, 80, 3)) +>info : Symbol(A2.info, Decl(narrowingOfDottedNames.ts, 72, 23)) +>a_count : Symbol(AInfo.a_count, Decl(narrowingOfDottedNames.ts, 60, 13)) + } + else if (target instanceof B2) { +>target : Symbol(target, Decl(narrowingOfDottedNames.ts, 80, 3)) +>B2 : Symbol(B2, Decl(narrowingOfDottedNames.ts, 74, 1)) + + const j: BInfo = target.info; +>j : Symbol(j, Decl(narrowingOfDottedNames.ts, 87, 13)) +>BInfo : Symbol(BInfo, Decl(narrowingOfDottedNames.ts, 62, 1)) +>target.info : Symbol(B2.info, Decl(narrowingOfDottedNames.ts, 76, 23)) +>target : Symbol(target, Decl(narrowingOfDottedNames.ts, 80, 3)) +>info : Symbol(B2.info, Decl(narrowingOfDottedNames.ts, 76, 23)) + } +} + diff --git a/tests/baselines/reference/narrowingOfDottedNames.types b/tests/baselines/reference/narrowingOfDottedNames.types index 5638a349fd9..644aea6ba14 100644 --- a/tests/baselines/reference/narrowingOfDottedNames.types +++ b/tests/baselines/reference/narrowingOfDottedNames.types @@ -132,3 +132,80 @@ class Foo2 } } +// Repro from #29513 + +class AInfo { +>AInfo : AInfo + + a_count: number = 1; +>a_count : number +>1 : 1 +} + +class BInfo { +>BInfo : BInfo + + b_count: number = 1; +>b_count : number +>1 : 1 +} + +class Base { +>Base : Base + + id: number = 0; +>id : number +>0 : 0 +} + +class A2 extends Base { +>A2 : A2 +>Base : Base + + info!: AInfo; +>info : AInfo +} + +class B2 extends Base { +>B2 : B2 +>Base : Base + + info!: BInfo; +>info : BInfo +} + +let target: Base = null as any; +>target : Base +>null as any : any +>null : null + +while (target) { +>target : Base + + if (target instanceof A2) { +>target instanceof A2 : boolean +>target : Base +>A2 : typeof A2 + + target.info.a_count = 3; +>target.info.a_count = 3 : 3 +>target.info.a_count : number +>target.info : AInfo +>target : A2 +>info : AInfo +>a_count : number +>3 : 3 + } + else if (target instanceof B2) { +>target instanceof B2 : boolean +>target : Base +>B2 : typeof B2 + + const j: BInfo = target.info; +>j : BInfo +>target.info : BInfo +>target : B2 +>info : BInfo + } +} + From 530a09a6e235a104b4ff483f1bbd766a5f686277 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Mon, 4 Feb 2019 07:55:39 -0800 Subject: [PATCH 41/42] Update user baselines (#29682) --- tests/baselines/reference/user/assert.log | 20 +++++++++---------- tests/baselines/reference/user/async.log | 2 +- .../reference/user/create-react-app.log | 16 +++++++-------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/baselines/reference/user/assert.log b/tests/baselines/reference/user/assert.log index 87f6ac257bf..672c147428d 100644 --- a/tests/baselines/reference/user/assert.log +++ b/tests/baselines/reference/user/assert.log @@ -25,17 +25,17 @@ node_modules/assert/test.js(143,10): error TS2339: Property 'a' does not exist o node_modules/assert/test.js(149,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? node_modules/assert/test.js(157,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'never' has no compatible call signatures. node_modules/assert/test.js(161,5): error TS2552: Cannot find name 'test'. Did you mean 'tests'? -node_modules/assert/test.js(168,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(182,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(229,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(235,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(250,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(254,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(168,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(182,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(229,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(235,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(250,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(254,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. node_modules/assert/test.js(256,55): error TS2345: Argument of type 'TypeError' is not assignable to parameter of type 'string'. -node_modules/assert/test.js(262,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(279,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(285,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -node_modules/assert/test.js(320,5): error TS2582: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(262,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(279,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(285,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +node_modules/assert/test.js(320,5): error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. diff --git a/tests/baselines/reference/user/async.log b/tests/baselines/reference/user/async.log index 286b1102af3..1477ce5faa6 100644 --- a/tests/baselines/reference/user/async.log +++ b/tests/baselines/reference/user/async.log @@ -51,7 +51,7 @@ node_modules/async/autoInject.js(160,28): error TS2695: Left side of comma opera node_modules/async/autoInject.js(164,14): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/autoInject.js(168,6): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/cargo.js(62,12): error TS2304: Cannot find name 'AsyncFunction'. -node_modules/async/cargo.js(67,14): error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig. +node_modules/async/cargo.js(67,14): error TS2591: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig. node_modules/async/cargo.js(67,20): error TS1005: '}' expected. node_modules/async/cargo.js(92,11): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/compose.js(8,37): error TS2695: Left side of comma operator is unused and has no side effects. diff --git a/tests/baselines/reference/user/create-react-app.log b/tests/baselines/reference/user/create-react-app.log index 275a3140def..1b8a132fc39 100644 --- a/tests/baselines/reference/user/create-react-app.log +++ b/tests/baselines/reference/user/create-react-app.log @@ -15,9 +15,9 @@ packages/babel-preset-react-app/index.js(123,17): error TS2307: Cannot find modu packages/babel-preset-react-app/index.js(130,17): error TS2307: Cannot find module '@babel/plugin-transform-regenerator'. packages/babel-preset-react-app/index.js(137,15): error TS2307: Cannot find module '@babel/plugin-syntax-dynamic-import'. packages/babel-preset-react-app/index.js(140,17): error TS2307: Cannot find module 'babel-plugin-transform-dynamic-import'. -packages/confusing-browser-globals/test.js(14,1): error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +packages/confusing-browser-globals/test.js(14,1): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. packages/confusing-browser-globals/test.js(15,3): error TS2304: Cannot find name 'expect'. -packages/confusing-browser-globals/test.js(18,1): error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +packages/confusing-browser-globals/test.js(18,1): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. packages/confusing-browser-globals/test.js(19,3): error TS2304: Cannot find name 'expect'. packages/create-react-app/createReactApp.js(37,37): error TS2307: Cannot find module 'validate-npm-package-name'. packages/create-react-app/createReactApp.js(47,24): error TS2307: Cannot find module 'tar-pack'. @@ -35,18 +35,18 @@ packages/react-dev-utils/FileSizeReporter.js(16,24): error TS2307: Cannot find m packages/react-dev-utils/WebpackDevServerUtils.js(9,25): error TS2307: Cannot find module 'address'. packages/react-dev-utils/WebpackDevServerUtils.js(14,24): error TS2307: Cannot find module 'detect-port-alt'. packages/react-dev-utils/WebpackDevServerUtils.js(15,24): error TS2307: Cannot find module 'is-root'. -packages/react-dev-utils/__tests__/ignoredFiles.test.js(12,1): error TS2582: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. -packages/react-dev-utils/__tests__/ignoredFiles.test.js(13,3): error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(12,1): error TS2593: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(13,3): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. packages/react-dev-utils/__tests__/ignoredFiles.test.js(18,5): error TS2304: Cannot find name 'expect'. packages/react-dev-utils/__tests__/ignoredFiles.test.js(19,5): error TS2304: Cannot find name 'expect'. -packages/react-dev-utils/__tests__/ignoredFiles.test.js(22,3): error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(22,3): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. packages/react-dev-utils/__tests__/ignoredFiles.test.js(26,5): error TS2304: Cannot find name 'expect'. -packages/react-dev-utils/__tests__/ignoredFiles.test.js(29,3): error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(29,3): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. packages/react-dev-utils/__tests__/ignoredFiles.test.js(36,5): error TS2304: Cannot find name 'expect'. packages/react-dev-utils/__tests__/ignoredFiles.test.js(37,5): error TS2304: Cannot find name 'expect'. -packages/react-dev-utils/__tests__/ignoredFiles.test.js(40,3): error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(40,3): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. packages/react-dev-utils/__tests__/ignoredFiles.test.js(46,5): error TS2304: Cannot find name 'expect'. -packages/react-dev-utils/__tests__/ignoredFiles.test.js(49,3): error TS2582: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(49,3): error TS2593: Cannot find name 'it'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig. packages/react-dev-utils/__tests__/ignoredFiles.test.js(53,5): error TS2304: Cannot find name 'expect'. packages/react-dev-utils/browsersHelper.js(9,30): error TS2307: Cannot find module 'browserslist'. packages/react-dev-utils/browsersHelper.js(13,23): error TS2307: Cannot find module 'pkg-up'. From 2f9218f346bbc606cccc4aebfca1c2c4f3167fee Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 4 Feb 2019 15:25:41 -0800 Subject: [PATCH 42/42] DOM update February 2019 (#29690) * DOM update February 2019 * Update some baselines * Update mappedTypeRecursiveInference baselines --- src/lib/dom.generated.d.ts | 872 +++++++++++++----- src/lib/dom.iterable.generated.d.ts | 7 + src/lib/webworker.generated.d.ts | 184 +++- .../expressionTypeNodeShouldError.types | 12 +- .../intersectionsOfLargeUnions.types | 6 +- .../intersectionsOfLargeUnions2.types | 6 +- .../mappedTypeRecursiveInference.errors.txt | 30 + .../mappedTypeRecursiveInference.symbols | 10 - .../mappedTypeRecursiveInference.types | 28 +- .../modularizeLibrary_Dom.iterable.types | 4 +- .../parserOverloadOnConstants1.types | 8 +- 11 files changed, 886 insertions(+), 281 deletions(-) create mode 100644 tests/baselines/reference/mappedTypeRecursiveInference.errors.txt diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 03eb2a4a961..bb408a34976 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -183,6 +183,10 @@ interface ClientQueryOptions { type?: ClientTypes; } +interface ClipboardEventInit extends EventInit { + clipboardData?: DataTransfer | null; +} + interface CloseEventInit extends EventInit { code?: number; reason?: string; @@ -428,6 +432,10 @@ interface EventModifierInit extends UIEventInit { shiftKey?: boolean; } +interface EventSourceInit { + withCredentials?: boolean; +} + interface ExceptionInformation { domain?: string | null; } @@ -459,12 +467,16 @@ interface FocusOptions { preventScroll?: boolean; } +interface FullscreenOptions { + navigationUI?: FullscreenNavigationUI; +} + interface GainOptions extends AudioNodeOptions { gain?: number; } interface GamepadEventInit extends EventInit { - gamepad?: Gamepad; + gamepad: Gamepad; } interface GetNotificationOptions { @@ -599,15 +611,17 @@ interface MediaEncryptedEventInit extends EventInit { } interface MediaKeyMessageEventInit extends EventInit { - message?: ArrayBuffer | null; - messageType?: MediaKeyMessageType; + message: ArrayBuffer; + messageType: MediaKeyMessageType; } interface MediaKeySystemConfiguration { audioCapabilities?: MediaKeySystemMediaCapability[]; distinctiveIdentifier?: MediaKeysRequirement; initDataTypes?: string[]; + label?: string; persistentState?: MediaKeysRequirement; + sessionTypes?: string[]; videoCapabilities?: MediaKeySystemMediaCapability[]; } @@ -724,6 +738,8 @@ interface MouseEventInit extends EventModifierInit { buttons?: number; clientX?: number; clientY?: number; + movementX?: number; + movementY?: number; relatedTarget?: EventTarget | null; screenX?: number; screenY?: number; @@ -1442,6 +1458,11 @@ interface ServiceWorkerMessageEventInit extends EventInit { source?: ServiceWorker | MessagePort | null; } +interface ShadowRootInit { + delegatesFocus?: boolean; + mode: ShadowRootMode; +} + interface StereoPannerOptions extends AudioNodeOptions { pan?: number; } @@ -1609,6 +1630,7 @@ interface EventListener { (evt: Event): void; } +/** The ANGLE_instanced_arrays extension is part of the WebGL API and allows to draw the same object, or groups of similar objects multiple times, if they share the same vertex data, primitive count and type. */ interface ANGLE_instanced_arrays { drawArraysInstancedANGLE(mode: GLenum, first: GLint, count: GLsizei, primcount: GLsizei): void; drawElementsInstancedANGLE(mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr, primcount: GLsizei): void; @@ -1616,6 +1638,7 @@ interface ANGLE_instanced_arrays { readonly VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: GLenum; } +/** The AbortController interface represents a controller object that allows you to abort one or more DOM requests as and when desired. */ interface AbortController { /** * Returns the AbortSignal object associated with this object. @@ -1634,16 +1657,17 @@ declare var AbortController: { }; interface AbortSignalEventMap { - "abort": ProgressEvent; + "abort": Event; } +/** The AbortSignal interface represents a signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object. */ interface AbortSignal extends EventTarget { /** * Returns true if this AbortSignal's AbortController has signaled to abort, and false * otherwise. */ readonly aborted: boolean; - onabort: ((this: AbortSignal, ev: ProgressEvent) => any) | null; + onabort: ((this: AbortSignal, ev: Event) => any) | null; addEventListener(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | EventListenerOptions): void; @@ -1688,6 +1712,7 @@ interface AesCmacParams extends Algorithm { length: number; } +/** The AnalyserNode interface represents a node able to provide real-time frequency and time-domain analysis information. It is an AudioNode that passes the audio stream unchanged from the input to the output, but allows you to take the generated data, process it, and create audio visualizations. */ interface AnalyserNode extends AudioNode { fftSize: number; readonly frequencyBinCount: number; @@ -1756,6 +1781,7 @@ declare var AnimationEffect: { new(): AnimationEffect; }; +/** The AnimationEvent interface represents events providing information related to animations. */ interface AnimationEvent extends Event { readonly animationName: string; readonly elapsedTime: number; @@ -1845,6 +1871,7 @@ declare var ApplicationCache: { readonly UPDATEREADY: number; }; +/** This type represents a DOM element's attribute as an object. In most DOM methods, you will probably directly retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g., Element.getAttributeNode()) or means of iterating give Attr types. */ interface Attr extends Node { readonly localName: string; readonly name: string; @@ -1860,6 +1887,7 @@ declare var Attr: { new(): Attr; }; +/** Objects of these types are designed to hold small audio snippets, typically less than 45 s. For longer sounds, objects implementing the MediaElementAudioSourceNode are more suitable. The buffer contains data in the following format:  non-interleaved IEEE754 32-bit linear PCM with a nominal range between -1 and +1, that is, 32bits floating point buffer, with each samples between -1.0 and 1.0. If the AudioBuffer has multiple channels, they are stored in separate buffer. */ interface AudioBuffer { readonly duration: number; readonly length: number; @@ -1875,6 +1903,7 @@ declare var AudioBuffer: { new(options: AudioBufferOptions): AudioBuffer; }; +/** The AudioBufferSourceNode interface is an AudioScheduledSourceNode which represents an audio source consisting of in-memory audio data, stored in an AudioBuffer. It's especially useful for playing back audio which has particularly stringent timing accuracy requirements, such as for sounds that must match a specific rhythm and can be kept in memory rather than being played from disk or the network. */ interface AudioBufferSourceNode extends AudioScheduledSourceNode { buffer: AudioBuffer | null; readonly detune: AudioParam; @@ -1894,6 +1923,7 @@ declare var AudioBufferSourceNode: { new(context: BaseAudioContext, options?: AudioBufferSourceOptions): AudioBufferSourceNode; }; +/** The AudioContext interface represents an audio-processing graph built from audio modules linked together, each represented by an AudioNode. */ interface AudioContext extends BaseAudioContext { readonly baseLatency: number; readonly outputLatency: number; @@ -1915,6 +1945,7 @@ declare var AudioContext: { new(contextOptions?: AudioContextOptions): AudioContext; }; +/** AudioDestinationNode has no output (as it is the output, no more AudioNode can be linked after it in the audio graph) and one input. The number of channels in the input must be between 0 and the maxChannelCount value or an exception is raised. */ interface AudioDestinationNode extends AudioNode { readonly maxChannelCount: number; } @@ -1924,6 +1955,7 @@ declare var AudioDestinationNode: { new(): AudioDestinationNode; }; +/** The AudioListener interface represents the position and orientation of the unique person listening to the audio scene, and is used in audio spatialization. All PannerNodes spatialize in relation to the AudioListener stored in the BaseAudioContext.listener attribute. */ interface AudioListener { readonly forwardX: AudioParam; readonly forwardY: AudioParam; @@ -1945,6 +1977,7 @@ declare var AudioListener: { new(): AudioListener; }; +/** The AudioNode interface is a generic interface for representing an audio processing module. Examples include: */ interface AudioNode extends EventTarget { channelCount: number; channelCountMode: ChannelCountMode; @@ -1968,6 +2001,7 @@ declare var AudioNode: { new(): AudioNode; }; +/** The Web Audio API's AudioParam interface represents an audio-related parameter, usually a parameter of an AudioNode (such as GainNode.gain). */ interface AudioParam { automationRate: AutomationRate; readonly defaultValue: number; @@ -1997,6 +2031,7 @@ declare var AudioParamMap: { new(): AudioParamMap; }; +/** The Web Audio API AudioProcessingEvent represents events that occur when a ScriptProcessorNode input buffer is ready to be processed. */ interface AudioProcessingEvent extends Event { readonly inputBuffer: AudioBuffer; readonly outputBuffer: AudioBuffer; @@ -2027,13 +2062,14 @@ declare var AudioScheduledSourceNode: { new(): AudioScheduledSourceNode; }; +/** The AudioTrack interface represents a single audio track from one of the HTML media elements,