diff --git a/.mailmap b/.mailmap index 73ebed0cc7c..97941bcdf5a 100644 --- a/.mailmap +++ b/.mailmap @@ -248,4 +248,23 @@ rdosanjh # Raj Dosanjh gdh1995 # Dahan Gong cedvdb # @cedvdb kpreisser # K. Preißer -e-cloud # @e-cloud \ No newline at end of file +e-cloud # @e-cloud +Andrew Casey Andrew Casey +Andrew Stegmaier +Benny Neugebauer +Blaine Bublitz +Charles Pierce +Daniel Król +Diogo Franco (Kovensky) +Donald Pipowitch +Halasi Tamás +Ika +Joe Chung +Kate Miháliková +Mohsen Azimi +Noel Varanda +Reiner Dolp +t_ # @t_ +TravCav # @TravCav +Vladimir Kurchatkin +William Orr \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 33e44a349aa..4a99aaf2237 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,9 +16,6 @@ matrix: branches: only: - master - - release-2.1 - - release-2.2 - - release-2.3 install: - npm uninstall typescript --no-save diff --git a/AUTHORS.md b/AUTHORS.md index 4772d5371fa..824c696ce4f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -15,7 +15,9 @@ TypeScript is authored by: * Anders Hejlsberg * Andreas Martin * Andrej Baran +* Andrew Casey * Andrew Ochsner +* Andrew Stegmaier * Andrew Z Allen * András Parditka * Andy Hanson @@ -31,7 +33,9 @@ TypeScript is authored by: * Ben Duffield * Ben Mosher * Benjamin Bock +* Benny Neugebauer * Bill Ticehurst +* Blaine Bublitz * Blake Embrey * @bootstraponline * Bowden Kelly @@ -39,6 +43,7 @@ TypeScript is authored by: * Bryan Forbes * Caitlin Potter * @cedvdb +* Charles Pierce * Charly POLY * Chris Bubernak * Christophe Vidal @@ -52,6 +57,7 @@ TypeScript is authored by: * Dan Corder * Dan Quirk * Daniel Hollocher +* Daniel Król * Daniel Lehenbauer * Daniel Rosenwasser * David Kmenta @@ -60,9 +66,11 @@ TypeScript is authored by: * David Souther * Denis Nedelyaev * Dick van den Brink +* Diogo Franco (Kovensky) * Dirk Bäumer * Dirk Holtwick * Dom Chen +* Donald Pipowitch * Doug Ilijev * @e-cloud * Elisée Maurer @@ -89,12 +97,14 @@ TypeScript is authored by: * Guilherme Oenning * Guillaume Salles * Guy Bedford +* Halasi Tamás * Harald Niesche * Hendrik Liebau * Herrington Darkholme * Homa Wong * Iain Monro * Igor Novozhilov +* Ika * Ingvar Stepanyan * Isiah Meadows * Ivo Gabe de Wolff @@ -111,6 +121,7 @@ TypeScript is authored by: * Jeffrey Morlan * Jesse Schalken * Jiri Tobisek +* Joe Chung * Joel Day * Joey Wilson * Johannes Rieken @@ -131,6 +142,7 @@ TypeScript is authored by: * K. Preißer * Kagami Sascha Rosylight * Kanchalai Tanglertsampan +* Kate Miháliková * Keith Mashinter * Ken Howard * Kenji Imamula @@ -159,6 +171,7 @@ TypeScript is authored by: * Mike Busyrev * Mine Starks * Mohamed Hegazy +* Mohsen Azimi * Myles Megyesi * Natalie Coley * Nathan Shively-Sanders @@ -166,6 +179,7 @@ TypeScript is authored by: * Nicolas Henry * Nima Zahedi * Noah Chen +* Noel Varanda * Noj Vek * Oleg Mihailik * Oleksandr Chekhovskyi @@ -186,6 +200,7 @@ TypeScript is authored by: * Punya Biswal * Rado Kirov * Raj Dosanjh +* Reiner Dolp * Richard Karmazín * Richard Knoll * Richard Sentino @@ -213,6 +228,7 @@ TypeScript is authored by: * Sudheesh Singanamalla * Sébastien Arod * @T18970237136 +* @t_ * Tarik Ozket * Tetsuharu Ohzeki * Thomas Loubiou @@ -225,13 +241,16 @@ TypeScript is authored by: * togru * Tomas Grubliauskas * Torben Fitschen +* @TravCav * TruongSinh Tran-Nguyen * Vadi Taslim * Vidar Tonaas Fauske * Viktor Zozulyak * Vilic Vane +* Vladimir Kurchatkin * Vladimir Matveev * Wesley Wigham +* William Orr * York Yao * @yortus * Yuichi Nukiyama diff --git a/Gulpfile.ts b/Gulpfile.ts index d856254296e..63faf992599 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -39,25 +39,25 @@ Error.stackTraceLimit = 1000; const cmdLineOptions = minimist(process.argv.slice(2), { boolean: ["debug", "inspect", "light", "colors", "lint", "soft"], - string: ["browser", "tests", "host", "reporter", "stackTraceLimit"], + string: ["browser", "tests", "host", "reporter", "stackTraceLimit", "timeout"], alias: { b: "browser", - d: "debug", - t: "tests", - test: "tests", + d: "debug", "debug-brk": "debug", + i: "inspect", "inspect-brk": "inspect", + t: "tests", test: "tests", r: "reporter", - color: "colors", - f: "files", - file: "files", + c: "colors", color: "colors", + f: "files", file: "files", w: "workers", }, default: { soft: false, colors: process.env.colors || process.env.color || true, - debug: process.env.debug || process.env.d, - inspect: process.env.inspect, + debug: process.env.debug || process.env["debug-brk"] || process.env.d, + inspect: process.env.inspect || process.env["inspect-brk"] || process.env.i, host: process.env.TYPESCRIPT_HOST || process.env.host || "node", browser: process.env.browser || process.env.b || "IE", + timeout: process.env.timeout || 40000, tests: process.env.test || process.env.tests || process.env.t, light: process.env.light || false, reporter: process.env.reporter || process.env.r, @@ -594,11 +594,11 @@ function restoreSavedNodeEnv() { process.env.NODE_ENV = savedNodeEnv; } -let testTimeout = 40000; function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) { const lintFlag = cmdLineOptions["lint"]; cleanTestDirs((err) => { if (err) { console.error(err); failWithStatus(err, 1); } + let testTimeout = cmdLineOptions["timeout"]; const debug = cmdLineOptions["debug"]; const inspect = cmdLineOptions["inspect"]; const tests = cmdLineOptions["tests"]; @@ -637,12 +637,6 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer if (!runInParallel) { const args = []; - if (inspect) { - args.push("--inspect"); - } - if (inspect || debug) { - args.push("--debug-brk"); - } args.push("-R", reporter); if (tests) { args.push("-g", `"${tests}"`); @@ -653,7 +647,15 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: else { args.push("--no-colors"); } - args.push("-t", testTimeout); + if (inspect) { + args.unshift("--inspect-brk"); + } + else if (debug) { + args.unshift("--debug-brk"); + } + else { + args.push("-t", testTimeout); + } args.push(run); setNodeEnvToDevelopment(); exec(mocha, args, lintThenFinish, function(e, status) { @@ -745,7 +747,7 @@ declare module "convert-source-map" { export function fromSource(source: string, largeSource?: boolean): SourceMapConverter; } -gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => { +gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile, run], (done) => { const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true)); return testProject.src() .pipe(newer("built/local/bundle.js")) @@ -838,6 +840,7 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like ' }); gulp.task("generate-code-coverage", "Generates code coverage data via istanbul", ["tests"], (done) => { + const testTimeout = cmdLineOptions["timeout"]; exec("istanbul", ["cover", "node_modules/mocha/bin/_mocha", "--", "-R", "min", "-t", testTimeout.toString(), run], done, done); }); diff --git a/Jakefile.js b/Jakefile.js index 439fced0720..730754f4256 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -25,6 +25,8 @@ var LKGDirectory = "lib/"; var copyright = "CopyrightNotice.txt"; var thirdParty = "ThirdPartyNoticeText.txt"; +var defaultTestTimeout = 40000; + // add node_modules to path so we don't need global modules, prefer the modules by adding them first var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter; if (process.env.path !== undefined) { @@ -74,6 +76,10 @@ function measure(marker) { console.log("travis_time:end:" + marker.id + ":start=" + toNs(marker.stamp) + ",finish=" + toNs(total) + ",duration=" + toNs(diff) + "\r"); } +function removeConstModifierFromEnumDeclarations(text) { + return text.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4'); +} + var compilerSources = filesFromConfig("./src/compiler/tsconfig.json"); var servicesSources = filesFromConfig("./src/services/tsconfig.json"); var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json")); @@ -551,7 +557,7 @@ compileFile(servicesFile, servicesSources, [builtLocalDirectory, copyright].conc // Stanalone/web definition file using global 'ts' namespace jake.cpR(standaloneDefinitionsFile, nodeDefinitionsFile, { silent: true }); var definitionFileContents = fs.readFileSync(nodeDefinitionsFile).toString(); - definitionFileContents = definitionFileContents.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4'); + definitionFileContents = removeConstModifierFromEnumDeclarations(definitionFileContents) fs.writeFileSync(standaloneDefinitionsFile, definitionFileContents); // Official node package definition file, pointed to by 'typings' in package.json @@ -611,6 +617,7 @@ compileFile( fs.readFileSync(tsserverLibraryDefinitionFile).toString() + "\r\nexport = ts;" + "\r\nexport as namespace ts;"; + tsserverLibraryDefinitionFileContents = removeConstModifierFromEnumDeclarations(tsserverLibraryDefinitionFileContents); fs.writeFileSync(tsserverLibraryDefinitionFile, tsserverLibraryDefinitionFileContents); }); @@ -800,9 +807,10 @@ function runConsoleTests(defaultReporter, runInParallel) { cleanTestDirs(); } - var debug = process.env.debug || process.env.d; - var inspect = process.env.inspect; - tests = process.env.test || process.env.tests || process.env.t; + var debug = process.env.debug || process.env["debug-brk"] || process.env.d; + var inspect = process.env.inspect || process.env["inspect-brk"] || process.env.i; + var testTimeout = process.env.timeout || defaultTestTimeout; + var tests = process.env.test || process.env.tests || process.env.t; var light = process.env.light || false; var stackTraceLimit = process.env.stackTraceLimit; var testConfigFile = 'test.config'; @@ -820,7 +828,7 @@ function runConsoleTests(defaultReporter, runInParallel) { } while (fs.existsSync(taskConfigsFolder)); fs.mkdirSync(taskConfigsFolder); - workerCount = process.env.workerCount || os.cpus().length; + workerCount = process.env.workerCount || process.env.p || os.cpus().length; } if (tests || light || taskConfigsFolder) { @@ -841,12 +849,6 @@ function runConsoleTests(defaultReporter, runInParallel) { if (!runInParallel) { var startTime = mark(); var args = []; - if (inspect) { - args.push("--inspect"); - } - if (inspect || debug) { - args.push("--debug-brk"); - } args.push("-R", reporter); if (tests) { args.push("-g", `"${tests}"`); @@ -860,7 +862,15 @@ function runConsoleTests(defaultReporter, runInParallel) { if (bail) { args.push("--bail"); } - args.push("-t", testTimeout); + if (inspect) { + args.unshift("--inspect-brk"); + } + else if (debug) { + args.unshift("--debug-brk"); + } + else { + args.push("-t", testTimeout); + } args.push(run); var cmd = "mocha " + args.join(" "); @@ -925,7 +935,6 @@ function runConsoleTests(defaultReporter, runInParallel) { } } -var testTimeout = 20000; desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true."); task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function () { runConsoleTests('min', /*runInParallel*/ true); @@ -938,6 +947,7 @@ task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { desc("Generates code coverage data via instanbul"); task("generate-code-coverage", ["tests", builtLocalDirectory], function () { + var testTimeout = process.env.timeout || defaultTestTimeout; var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run; console.log(cmd); exec(cmd); @@ -949,7 +959,7 @@ var nodeServerInFile = "tests/webTestServer.ts"; compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true, lib: "es6" }); desc("Runs browserify on run.js to produce a file suitable for running tests in the browser"); -task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() { +task("browserify", ["tests", run, builtLocalDirectory, nodeServerOutFile], function() { var cmd = 'browserify built/local/run.js -t ./scripts/browserify-optional -d -o built/local/bundle.js'; exec(cmd); }, { async: true }); diff --git a/issue_template.md b/issue_template.md index 29190e79763..b5872a0f9fa 100644 --- a/issue_template.md +++ b/issue_template.md @@ -2,7 +2,7 @@ -**TypeScript Version:** 2.2.1 / nightly (2.2.0-dev.201xxxxx) +**TypeScript Version:** 2.4.0 / nightly (2.5.0-dev.201xxxxx) **Code** diff --git a/package.json b/package.json index c62fa46853b..5b11935992f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "typescript", "author": "Microsoft Corp.", "homepage": "http://typescriptlang.org/", - "version": "2.4.0", + "version": "2.5.0", "license": "Apache-2.0", "description": "TypeScript is a language for application scale JavaScript development", "keywords": [ diff --git a/scripts/buildProtocol.ts b/scripts/buildProtocol.ts index 37ebd0105ae..e03338bf60d 100644 --- a/scripts/buildProtocol.ts +++ b/scripts/buildProtocol.ts @@ -113,7 +113,7 @@ class DeclarationsWalker { } } -function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string): string { +function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptServicesDts: string) { const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: [], stripInternal: true }; /** @@ -163,14 +163,17 @@ function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string) protocolDts += "\nimport protocol = ts.server.protocol;"; protocolDts += "\nexport = protocol;"; protocolDts += "\nexport as namespace protocol;"; + // do sanity check and try to compile generated text as standalone program const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false); const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()]; + + ts.sys.writeFile(outputFile, protocolDts); + if (diagnostics.length) { const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file.fileName} line ${d.start}`).join("\n"); throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`); } - return protocolDts; } if (process.argv.length < 5) { @@ -181,5 +184,4 @@ if (process.argv.length < 5) { const protocolTs = process.argv[2]; const typeScriptServicesDts = process.argv[3]; const outputFile = process.argv[4]; -const generatedProtocolDts = generateProtocolFile(protocolTs, typeScriptServicesDts); -ts.sys.writeFile(outputFile, generatedProtocolDts); +writeProtocolFile(outputFile, protocolTs, typeScriptServicesDts); diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 22209e2e41e..ba5022a7b3c 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -612,7 +612,7 @@ namespace ts { break; case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: - bindForInOrForOfStatement(node); + bindForInOrForOfStatement(node); break; case SyntaxKind.IfStatement: bindIfStatement(node); @@ -950,7 +950,7 @@ namespace ts { currentFlow = finishFlowLabel(postLoopLabel); } - function bindForInOrForOfStatement(node: ForInStatement | ForOfStatement): void { + function bindForInOrForOfStatement(node: ForInOrOfStatement): void { const preLoopLabel = createLoopLabel(); const postLoopLabel = createBranchLabel(); addAntecedent(preLoopLabel, currentFlow); @@ -1328,7 +1328,7 @@ namespace ts { function bindVariableDeclarationFlow(node: VariableDeclaration) { bindEachChild(node); - if (node.initializer || node.parent.parent.kind === SyntaxKind.ForInStatement || node.parent.parent.kind === SyntaxKind.ForOfStatement) { + if (node.initializer || isForInOrOfStatement(node.parent.parent)) { bindInitializedVariableFlow(node); } } @@ -1521,7 +1521,7 @@ namespace ts { // All the children of these container types are never visible through another // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, // they're only accessed 'lexically' (i.e. from code that exists underneath - // their container in the tree. To accomplish this, we simply add their declared + // their container in the tree). To accomplish this, we simply add their declared // symbol to the 'locals' of the container. These symbols can then be found as // the type checker walks up the containers, checking them for matching names. return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); @@ -2053,7 +2053,10 @@ namespace ts { case SyntaxKind.TypePredicate: return checkTypePredicate(node as TypePredicateNode); case SyntaxKind.TypeParameter: - return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + if (node.parent.kind !== ts.SyntaxKind.JSDocTemplateTag || isInJavaScriptFile(node)) { + return declareSymbolAndAddToSymbolTable(node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + } + return; case SyntaxKind.Parameter: return bindParameter(node); case SyntaxKind.VariableDeclaration: @@ -2135,8 +2138,10 @@ namespace ts { case SyntaxKind.EnumDeclaration: return bindEnumDeclaration(node); case SyntaxKind.ModuleDeclaration: - return bindModuleDeclaration(node); - + if (node.parent.kind !== ts.SyntaxKind.JSDocTypedefTag || isInJavaScriptFile(node)) { + return bindModuleDeclaration(node); + } + return undefined; // Jsx-attributes case SyntaxKind.JsxAttributes: return bindJsxAttributes(node); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0679e5a958b..acaa8283a2a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -810,16 +810,8 @@ namespace ts { break; } - switch (declaration.parent.parent.kind) { - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - // ForIn/ForOf case - use site should not be used in expression part - if (isSameScopeDescendentOf(usage, (declaration.parent.parent).expression, container)) { - return true; - } - } - - return false; + // ForIn/ForOf case - use site should not be used in expression part + return isForInOrOfStatement(declaration.parent.parent) && isSameScopeDescendentOf(usage, declaration.parent.parent.expression, container); } function isUsedInFunctionOrInstanceProperty(usage: Node, declaration: Node, container?: Node): boolean { @@ -1479,8 +1471,15 @@ namespace ts { } } + /** + * Indicates that a symbol is an alias that does not merge with a local declaration. + */ + function isNonLocalAlias(symbol: Symbol, excludes = SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace) { + return symbol && (symbol.flags & (SymbolFlags.Alias | excludes)) === SymbolFlags.Alias; + } + function resolveSymbol(symbol: Symbol, dontResolveAlias?: boolean): Symbol { - const shouldResolve = !dontResolveAlias && symbol && symbol.flags & SymbolFlags.Alias && !(symbol.flags & (SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace)); + const shouldResolve = !dontResolveAlias && isNonLocalAlias(symbol); return shouldResolve ? resolveAlias(symbol) : symbol; } @@ -2831,6 +2830,17 @@ namespace ts { function symbolToParameterDeclaration(parameterSymbol: Symbol, context: NodeBuilderContext): ParameterDeclaration { const parameterDeclaration = getDeclarationOfKind(parameterSymbol, SyntaxKind.Parameter); + if (isTransientSymbol(parameterSymbol) && parameterSymbol.isRestParameter) { + // special-case synthetic rest parameters in JS files + return createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + parameterSymbol.isRestParameter ? createToken(SyntaxKind.DotDotDotToken) : undefined, + "args", + /*questionToken*/ undefined, + typeToTypeNodeHelper(anyArrayType, context), + /*initializer*/ undefined); + } const modifiers = parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(getSynthesizedClone); const dotDotDotToken = isRestParameter(parameterDeclaration) ? createToken(SyntaxKind.DotDotDotToken) : undefined; const name = parameterDeclaration.name ? @@ -3229,9 +3239,15 @@ namespace ts { writer.writeStringLiteral(literalTypeToString(type)); } else if (type.flags & TypeFlags.Index) { + if (flags & TypeFormatFlags.InElementType) { + writePunctuation(writer, SyntaxKind.OpenParenToken); + } writer.writeKeyword("keyof"); writeSpace(writer); writeType((type).type, TypeFormatFlags.InElementType); + if (flags & TypeFormatFlags.InElementType) { + writePunctuation(writer, SyntaxKind.CloseParenToken); + } } else if (type.flags & TypeFlags.IndexedAccess) { writeType((type).objectType, TypeFormatFlags.InElementType); @@ -4188,16 +4204,6 @@ namespace ts { // Return the inferred type for a variable, parameter, or property declaration function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration, includeOptionality: boolean): Type { - if (declaration.flags & NodeFlags.JavaScriptFile) { - // If this is a variable in a JavaScript file, then use the JSDoc type (if it has - // one as its type), otherwise fallback to the below standard TS codepaths to - // try to figure it out. - const type = getTypeForDeclarationFromJSDocComment(declaration); - if (type && type !== unknownType) { - return type; - } - } - // A variable declared in a for..in statement is of type string, or of type keyof T when the // right hand expression is of a type parameter type. if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) { @@ -4219,8 +4225,9 @@ namespace ts { } // Use type from type annotation if one is present - if (declaration.type) { - const declaredType = getTypeFromTypeNode(declaration.type); + const typeNode = getEffectiveTypeAnnotationNode(declaration); + if (typeNode) { + const declaredType = getTypeFromTypeNode(typeNode); return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality); } @@ -4511,10 +4518,11 @@ namespace ts { function getAnnotatedAccessorType(accessor: AccessorDeclaration): Type { if (accessor) { if (accessor.kind === SyntaxKind.GetAccessor) { - return accessor.type && getTypeFromTypeNode(accessor.type); + const getterTypeAnnotation = getEffectiveReturnTypeNode(accessor); + return getterTypeAnnotation && getTypeFromTypeNode(getterTypeAnnotation); } else { - const setterTypeAnnotation = getSetAccessorTypeAnnotationNode(accessor); + const setterTypeAnnotation = getEffectiveSetAccessorTypeAnnotationNode(accessor); return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation); } } @@ -4667,7 +4675,7 @@ namespace ts { function reportCircularityError(symbol: Symbol) { // Check if variable has type annotation that circularly references the variable itself - if ((symbol.valueDeclaration).type) { + if (getEffectiveTypeAnnotationNode(symbol.valueDeclaration)) { error(symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); return unknownType; @@ -4824,12 +4832,9 @@ namespace ts { } function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[], location: Node): Signature[] { - let signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location); - if (typeArgumentNodes) { - const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); - signatures = map(signatures, sig => getSignatureInstantiation(sig, typeArguments)); - } - return signatures; + const signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location); + const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); + return sameMap(signatures, sig => some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments) : sig); } /** @@ -5253,14 +5258,18 @@ namespace ts { // A variable-like declaration is considered independent (free of this references) if it has a type annotation // that specifies an independent type, or if it has no type annotation and no initializer (and thus of type any). function isIndependentVariableLikeDeclaration(node: VariableLikeDeclaration): boolean { - return node.type && isIndependentType(node.type) || !node.type && !node.initializer; + const typeNode = getEffectiveTypeAnnotationNode(node); + return typeNode ? isIndependentType(typeNode) : !node.initializer; } // A function-like declaration is considered independent (free of this references) if it has a return type // annotation that is considered independent and if each parameter is considered independent. function isIndependentFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean { - if (node.kind !== SyntaxKind.Constructor && (!node.type || !isIndependentType(node.type))) { - return false; + if (node.kind !== SyntaxKind.Constructor) { + const typeNode = getEffectiveReturnTypeNode(node); + if (!typeNode || !isIndependentType(typeNode)) { + return false; + } } for (const parameter of node.parameters) { if (!isIndependentVariableLikeDeclaration(parameter)) { @@ -5973,7 +5982,7 @@ namespace ts { typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType; } else { - const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameter(decl) && decl.default); + const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameterDeclaration(decl) && decl.default); typeParameter.default = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType; } } @@ -6170,24 +6179,16 @@ namespace ts { return undefined; } - function getTypeParametersFromJSDocTemplate(declaration: SignatureDeclaration): TypeParameter[] { - if (declaration.flags & NodeFlags.JavaScriptFile) { - const templateTag = getJSDocTemplateTag(declaration); - if (templateTag) { - return getTypeParametersFromDeclaration(templateTag.typeParameters); - } - } - - return undefined; - } - // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual // type checking functions). - function getTypeParametersFromDeclaration(typeParameterDeclarations: TypeParameterDeclaration[]): TypeParameter[] { - const result: TypeParameter[] = []; - forEach(typeParameterDeclarations, node => { + function getTypeParametersFromDeclaration(declaration: DeclarationWithTypeParameters): TypeParameter[] { + let result: TypeParameter[]; + forEach(getEffectiveTypeParameterDeclarations(declaration), node => { const tp = getDeclaredTypeOfTypeParameter(node.symbol); if (!contains(result, tp)) { + if (!result) { + result = []; + } result.push(tp); } }); @@ -6383,15 +6384,22 @@ namespace ts { const classType = declaration.kind === SyntaxKind.Constructor ? getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent).symbol)) : undefined; - const typeParameters = classType ? classType.localTypeParameters : - declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) : - getTypeParametersFromJSDocTemplate(declaration); + const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration); const returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType); const typePredicate = declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ? createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) : undefined; + // JS functions get a free rest parameter if they reference `arguments` + let hasRestLikeParameter = hasRestParameter(declaration); + if (!hasRestLikeParameter && isInJavaScriptFile(declaration) && !hasJSDocParameterTags(declaration) && containsArgumentsReference(declaration)) { + hasRestLikeParameter = true; + const syntheticArgsSymbol = createSymbol(SymbolFlags.Variable, "args"); + syntheticArgsSymbol.type = anyArrayType; + syntheticArgsSymbol.isRestParameter = true; + parameters.push(syntheticArgsSymbol); + } - links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasLiteralTypes); + links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestLikeParameter, hasLiteralTypes); } return links.resolvedSignature; } @@ -6403,15 +6411,10 @@ namespace ts { else if (classType) { return classType; } - else if (declaration.type) { - return getTypeFromTypeNode(declaration.type); - } - if (declaration.flags & NodeFlags.JavaScriptFile) { - const type = getReturnTypeFromJSDocComment(declaration); - if (type && type !== unknownType) { - return type; - } + const typeNode = getEffectiveReturnTypeNode(declaration); + if (typeNode) { + return getTypeFromTypeNode(typeNode); } // TypeScript 1.0 spec (April 2014): @@ -6426,14 +6429,14 @@ namespace ts { } } - function containsArgumentsReference(declaration: FunctionLikeDeclaration): boolean { + function containsArgumentsReference(declaration: SignatureDeclaration): boolean { const links = getNodeLinks(declaration); if (links.containsArgumentsReference === undefined) { if (links.flags & NodeCheckFlags.CaptureArguments) { links.containsArgumentsReference = true; } else { - links.containsArgumentsReference = traverse(declaration.body); + links.containsArgumentsReference = traverse((declaration as FunctionLikeDeclaration).body); } } return links.containsArgumentsReference; @@ -6820,21 +6823,46 @@ namespace ts { return undefined; } - function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName) { + function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName, meaning: SymbolFlags) { if (!typeReferenceName) { return unknownSymbol; } - return resolveEntityName(typeReferenceName, SymbolFlags.Type) || unknownSymbol; + return resolveEntityName(typeReferenceName, meaning) || unknownSymbol; } function getTypeReferenceType(node: TypeReferenceType, symbol: Symbol) { const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced. - if (symbol === unknownSymbol) { return unknownType; } + const type = getTypeReferenceTypeWorker(node, symbol, typeArguments); + if (type) { + return type; + } + + if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) { + // A JSDocTypeReference may have resolved to a value (as opposed to a type). If + // the symbol is a constructor function, return the inferred class type; otherwise, + // the type of this reference is just the type of the value we resolved to. + const valueType = getTypeOfSymbol(symbol); + if (valueType.symbol && !isInferredClassType(valueType)) { + const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments); + if (referenceType) { + return referenceType; + } + } + + // Resolve the type reference as a Type for the purpose of reporting errors. + resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type); + return valueType; + } + + return getTypeFromNonGenericTypeReference(node, symbol); + } + + function getTypeReferenceTypeWorker(node: TypeReferenceType, symbol: Symbol, typeArguments: Type[]): Type | undefined { if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments); } @@ -6843,14 +6871,9 @@ namespace ts { return getTypeFromTypeAliasReference(node, symbol, typeArguments); } - if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) { - // A JSDocTypeReference may have resolved to a value (as opposed to a type). In - // that case, the type of this reference is just the type of the value we resolved - // to. - return getTypeOfSymbol(symbol); + if (symbol.flags & SymbolFlags.Function && node.kind === SyntaxKind.JSDocTypeReference && (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) { + return getInferredClassType(symbol); } - - return getTypeFromNonGenericTypeReference(node, symbol); } function getPrimitiveTypeFromJSDocTypeReference(node: JSDocTypeReference): Type { @@ -6893,22 +6916,13 @@ namespace ts { if (!links.resolvedType) { let symbol: Symbol; let type: Type; + let meaning = SymbolFlags.Type; if (node.kind === SyntaxKind.JSDocTypeReference) { - type = getPrimitiveTypeFromJSDocTypeReference(node); - if (!type) { - const typeReferenceName = getTypeReferenceName(node); - symbol = resolveTypeReferenceName(typeReferenceName); - type = getTypeReferenceType(node, symbol); - } + type = getPrimitiveTypeFromJSDocTypeReference(node); + meaning |= SymbolFlags.Value; } - else { - // We only support expressions that are simple qualified names. For other expressions this produces undefined. - const typeNameOrExpression: EntityNameOrEntityNameExpression = node.kind === SyntaxKind.TypeReference - ? (node).typeName - : isEntityNameExpression((node).expression) - ? (node).expression - : undefined; - symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol; + if (!type) { + symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning); type = getTypeReferenceType(node, symbol); } // Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the @@ -7145,6 +7159,7 @@ namespace ts { containsAny?: boolean; containsUndefined?: boolean; containsNull?: boolean; + containsNever?: boolean; containsNonWideningType?: boolean; containsString?: boolean; containsNumber?: boolean; @@ -7346,10 +7361,13 @@ namespace ts { else if (type.flags & TypeFlags.Any) { typeSet.containsAny = true; } + else if (type.flags & TypeFlags.Never) { + typeSet.containsNever = true; + } else if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) { typeSet.containsEmptyObject = true; } - else if (!(type.flags & TypeFlags.Never) && (strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { + else if ((strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { if (type.flags & TypeFlags.Object) { typeSet.containsObjectType = true; } @@ -7387,6 +7405,9 @@ namespace ts { } const typeSet = [] as TypeSet; addTypesToIntersection(typeSet, types); + if (typeSet.containsNever) { + return neverType; + } if (typeSet.containsAny) { return anyType; } @@ -7648,11 +7669,9 @@ namespace ts { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } - left = filterType(left, t => !(t.flags & TypeFlags.Nullable)); if (left.flags & TypeFlags.Never) { return right; } - right = filterType(right, t => !(t.flags & TypeFlags.Nullable)); if (right.flags & TypeFlags.Never) { return left; } @@ -7703,7 +7722,7 @@ namespace ts { const declarations: Declaration[] = concatenate(leftProp.declarations, rightProp.declarations); const flags = SymbolFlags.Property | (leftProp.flags & SymbolFlags.Optional); const result = createSymbol(flags, leftProp.name); - result.type = getUnionType([getTypeOfSymbol(leftProp), rightType]); + result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, TypeFacts.NEUndefined)]); result.leftSpread = leftProp; result.rightSpread = rightProp; result.declarations = declarations; @@ -8039,7 +8058,7 @@ namespace ts { const result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), - instantiateType(signature.resolvedReturnType, mapper), + /*resolvedReturnType*/ undefined, freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes); result.target = signature; @@ -8146,9 +8165,9 @@ namespace ts { case SyntaxKind.ClassExpression: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.TypeAliasDeclaration: - const declaration = node as DeclarationWithTypeParameters; - if (declaration.typeParameters) { - for (const d of declaration.typeParameters) { + const typeParameters = getEffectiveTypeParameterDeclarations(node as DeclarationWithTypeParameters); + if (typeParameters) { + for (const d of typeParameters) { if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) { return true; } @@ -8303,7 +8322,7 @@ namespace ts { return false; } // Functions with any parameters that lack type annotations are context sensitive. - if (forEach(node.parameters, p => !p.type)) { + if (forEach(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) { return true; } // For arrow functions we now know we're not context sensitive. @@ -8387,10 +8406,6 @@ namespace ts { return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1); } - function checkTypeSubtypeOf(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { - return checkTypeRelatedTo(source, target, subtypeRelation, errorNode, headMessage, containingMessageChain); - } - function checkTypeAssignableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain); } @@ -8430,10 +8445,9 @@ namespace ts { return Ternary.False; } - // Spec 1.0 Section 3.8.3 & 3.8.4: - // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N - source = getErasedSignature(source); - target = getErasedSignature(target); + if (source.typeParameters) { + source = instantiateSignatureInContextOf(source, target); + } let result = Ternary.True; @@ -8947,7 +8961,11 @@ namespace ts { reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target)); } else { - errorNode = prop.valueDeclaration; + // use the property's value declaration if the property is assigned inside the literal itself + const objectLiteralDeclaration = source.symbol && firstOrUndefined(source.symbol.declarations); + if (prop.valueDeclaration && findAncestor(prop.valueDeclaration, d => d === objectLiteralDeclaration)) { + errorNode = prop.valueDeclaration; + } reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(target)); } @@ -9469,23 +9487,33 @@ namespace ts { const saveErrorInfo = errorInfo; if (getObjectFlags(source) & ObjectFlags.Instantiated && getObjectFlags(target) & ObjectFlags.Instantiated && source.symbol === target.symbol) { - // We instantiations of the same anonymous type (which typically will be the type of a method). - // Simply do a pairwise comparison of the signatures in the two signature lists instead of the - // much more expensive N * M comparison matrix we explore below. + // We have instantiations of the same anonymous type (which typically will be the type of a + // method). Simply do a pairwise comparison of the signatures in the two signature lists instead + // of the much more expensive N * M comparison matrix we explore below. We erase type parameters + // as they are known to always be the same. for (let i = 0; i < targetSignatures.length; i++) { - const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], reportErrors); + const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors); if (!related) { return Ternary.False; } result &= related; } } + else if (sourceSignatures.length === 1 && targetSignatures.length === 1) { + // For simple functions (functions with a single signature) we only erase type parameters for + // the comparable relation. Otherwise, if the source signature is generic, we instantiate it + // in the context of the target signature before checking the relationship. Ideally we'd do + // this regardless of the number of signatures, but the potential costs are prohibitive due + // to the quadratic nature of the logic below. + const eraseGenerics = relation === comparableRelation || compilerOptions.noStrictGenericChecks; + result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors); + } else { outer: for (const t of targetSignatures) { // Only elaborate errors from the first failure let shouldElaborateErrors = reportErrors; for (const s of sourceSignatures) { - const related = signatureRelatedTo(s, t, shouldElaborateErrors); + const related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors); if (related) { result &= related; errorInfo = saveErrorInfo; @@ -9508,8 +9536,9 @@ namespace ts { /** * See signatureAssignableTo, compareSignaturesIdentical */ - function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary { - return compareSignaturesRelated(source, target, /*checkAsCallback*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo); + function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean): Ternary { + return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, + /*checkAsCallback*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo); } function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary { @@ -9822,13 +9851,6 @@ namespace ts { return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1; } - function isSupertypeOfEach(candidate: Type, types: Type[]): boolean { - for (const t of types) { - if (candidate !== t && !isTypeSubtypeOf(t, candidate)) return false; - } - return true; - } - function literalTypesWithSameBaseType(types: Type[]): boolean { let commonBaseType: Type; for (const t of types) { @@ -9843,11 +9865,13 @@ namespace ts { return true; } - // When the candidate types are all literal types with the same base type, the common - // supertype is a union of those literal types. Otherwise, the common supertype is the - // first type that is a supertype of each of the other types. + // When the candidate types are all literal types with the same base type, return a union + // of those literal types. Otherwise, return the leftmost type for which no type to the + // right is a supertype. function getSupertypeOrUnion(types: Type[]): Type { - return literalTypesWithSameBaseType(types) ? getUnionType(types) : forEach(types, t => isSupertypeOfEach(t, types) ? t : undefined); + return literalTypesWithSameBaseType(types) ? + getUnionType(types) : + reduceLeft(types, (s, t) => isTypeSubtypeOf(s, t) ? t : s); } function getCommonSupertype(types: Type[]): Type { @@ -9855,52 +9879,9 @@ namespace ts { return getSupertypeOrUnion(types); } const primaryTypes = filter(types, t => !(t.flags & TypeFlags.Nullable)); - if (!primaryTypes.length) { - return getUnionType(types, /*subtypeReduction*/ true); - } - const supertype = getSupertypeOrUnion(primaryTypes); - return supertype && getNullableType(supertype, getFalsyFlagsOfTypes(types) & TypeFlags.Nullable); - } - - function reportNoCommonSupertypeError(types: Type[], errorLocation: Node, errorMessageChainHead: DiagnosticMessageChain): void { - // The downfallType/bestSupertypeDownfallType is the first type that caused a particular candidate - // to not be the common supertype. So if it weren't for this one downfallType (and possibly others), - // the type in question could have been the common supertype. - let bestSupertype: Type; - let bestSupertypeDownfallType: Type; - let bestSupertypeScore = 0; - - for (let i = 0; i < types.length; i++) { - let score = 0; - let downfallType: Type = undefined; - for (let j = 0; j < types.length; j++) { - if (isTypeSubtypeOf(types[j], types[i])) { - score++; - } - else if (!downfallType) { - downfallType = types[j]; - } - } - - Debug.assert(!!downfallType, "If there is no common supertype, each type should have a downfallType"); - - if (score > bestSupertypeScore) { - bestSupertype = types[i]; - bestSupertypeDownfallType = downfallType; - bestSupertypeScore = score; - } - - // types.length - 1 is the maximum score, given that getCommonSupertype returned false - if (bestSupertypeScore === types.length - 1) { - break; - } - } - - // In the following errors, the {1} slot is before the {0} slot because checkTypeSubtypeOf supplies the - // subtype as the first argument to the error - checkTypeSubtypeOf(bestSupertypeDownfallType, bestSupertype, errorLocation, - Diagnostics.Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0, - errorMessageChainHead); + return primaryTypes.length ? + getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & TypeFlags.Nullable) : + getUnionType(types, /*subtypeReduction*/ true); } function isArrayType(type: Type): boolean { @@ -10262,7 +10243,7 @@ namespace ts { const objectFlags = getObjectFlags(type); return !!(type.flags & TypeFlags.TypeVariable || objectFlags & ObjectFlags.Reference && forEach((type).typeArguments, couldContainTypeVariables) || - objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) || + objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) || objectFlags & ObjectFlags.Mapped || type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeVariables(type)); } @@ -10609,7 +10590,6 @@ namespace ts { function getInferredType(context: InferenceContext, index: number): Type { const inference = context.inferences[index]; let inferredType = inference.inferredType; - let inferenceSucceeded: boolean; if (!inferredType) { if (inference.candidates) { // We widen inferred literal types if @@ -10625,53 +10605,40 @@ namespace ts { // for inferences coming from return types in order to avoid common supertype failures. const unionOrSuperType = context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? getUnionType(baseCandidates, /*subtypeReduction*/ true) : getCommonSupertype(baseCandidates); - inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : unknownType; - inferenceSucceeded = !!unionOrSuperType; + inferredType = getWidenedType(unionOrSuperType); + } + else if (context.flags & InferenceFlags.NoDefault) { + // We use silentNeverType as the wildcard that signals no inferences. + inferredType = silentNeverType; } else { - if (context.flags & InferenceFlags.NoDefault) { - // We use silentNeverType as the wildcard that signals no inferences. - inferredType = silentNeverType; + // Infer either the default or the empty object type when no inferences were + // made. It is important to remember that in this case, inference still + // succeeds, meaning there is no error for not having inference candidates. An + // inference error only occurs when there are *conflicting* candidates, i.e. + // candidates with no common supertype. + const defaultType = getDefaultFromTypeParameter(inference.typeParameter); + if (defaultType) { + // Instantiate the default type. Any forward reference to a type + // parameter should be instantiated to the empty object type. + inferredType = instantiateType(defaultType, + combineTypeMappers( + createBackreferenceMapper(context.signature.typeParameters, index), + context)); } else { - // Infer either the default or the empty object type when no inferences were - // made. It is important to remember that in this case, inference still - // succeeds, meaning there is no error for not having inference candidates. An - // inference error only occurs when there are *conflicting* candidates, i.e. - // candidates with no common supertype. - const defaultType = getDefaultFromTypeParameter(inference.typeParameter); - if (defaultType) { - // Instantiate the default type. Any forward reference to a type - // parameter should be instantiated to the empty object type. - inferredType = instantiateType(defaultType, - combineTypeMappers( - createBackreferenceMapper(context.signature.typeParameters, index), - context)); - } - else { - inferredType = context.flags & InferenceFlags.AnyDefault ? anyType : emptyObjectType; - } + inferredType = context.flags & InferenceFlags.AnyDefault ? anyType : emptyObjectType; } - inferenceSucceeded = true; } inference.inferredType = inferredType; - // Only do the constraint check if inference succeeded (to prevent cascading errors) - if (inferenceSucceeded) { - const constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]); - if (constraint) { - const instantiatedConstraint = instantiateType(constraint, context); - if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { - inference.inferredType = inferredType = instantiatedConstraint; - } + const constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]); + if (constraint) { + const instantiatedConstraint = instantiateType(constraint, context); + if (!isTypeAssignableTo(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + inference.inferredType = inferredType = instantiatedConstraint; } } - else if (context.failedTypeParameterIndex === undefined || context.failedTypeParameterIndex > index) { - // If inference failed, it is necessary to record the index of the failed type parameter (the one we are on). - // It might be that inference has already failed on a later type parameter on a previous call to inferTypeArguments. - // So if this failure is on preceding type parameter, this type parameter is the new failure index. - context.failedTypeParameterIndex = index; - } } return inferredType; } @@ -12028,7 +11995,9 @@ namespace ts { return getTypeOfSymbol(symbol); } - if (symbol.flags & SymbolFlags.Alias && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) { + // We should only mark aliases as referenced if there isn't a local value declaration + // for the symbol. + if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) { markAliasSymbolAsReferenced(symbol); } @@ -12720,8 +12689,15 @@ namespace ts { function getContextualTypeForInitializerExpression(node: Expression): Type { const declaration = node.parent; if (node === declaration.initializer) { - if (declaration.type) { - return getTypeFromTypeNode(declaration.type); + const typeNode = getEffectiveTypeAnnotationNode(declaration); + if (typeNode) { + return getTypeFromTypeNode(typeNode); + } + if (isInJavaScriptFile(declaration)) { + const jsDocType = getTypeForDeclarationFromJSDocComment(declaration); + if (jsDocType) { + return jsDocType; + } } if (declaration.kind === SyntaxKind.Parameter) { const type = getContextuallyTypedParameterType(declaration); @@ -12735,12 +12711,13 @@ namespace ts { if (isBindingPattern(declaration.parent)) { const parentDeclaration = declaration.parent.parent; const name = declaration.propertyName || declaration.name; - if (parentDeclaration.kind !== SyntaxKind.BindingElement && - parentDeclaration.type && - !isBindingPattern(name)) { - const text = getTextOfPropertyName(name); - if (text) { - return getTypeOfPropertyOfType(getTypeFromTypeNode(parentDeclaration.type), text); + if (parentDeclaration.kind !== SyntaxKind.BindingElement) { + const parentTypeNode = getEffectiveTypeAnnotationNode(parentDeclaration); + if (parentTypeNode && !isBindingPattern(name)) { + const text = getTextOfPropertyName(name); + if (text) { + return getTypeOfPropertyOfType(getTypeFromTypeNode(parentTypeNode), text); + } } } } @@ -12794,9 +12771,9 @@ namespace ts { function getContextualReturnType(functionDecl: FunctionLikeDeclaration): Type { // If the containing function has a return type annotation, is a constructor, or is a get accessor whose // corresponding set accessor has a type annotation, return statements in the function are contextually typed - if (functionDecl.type || - functionDecl.kind === SyntaxKind.Constructor || - functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) { + if (functionDecl.kind === SyntaxKind.Constructor || + getEffectiveReturnTypeNode(functionDecl) || + isGetAccessorWithAnnotatedSetAccessor(functionDecl)) { return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); } @@ -13065,13 +13042,13 @@ namespace ts { return node ? node.contextualMapper : identityMapper; } - // If the given type is an object or union type, if that type has a single signature, and if - // that signature is non-generic, return the signature. Otherwise return undefined. - function getNonGenericSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature { + // If the given type is an object or union type with a single signature, and if that signature has at + // least as many parameters as the given function, return the signature. Otherwise return undefined. + function getContextualCallSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature { const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call); if (signatures.length === 1) { const signature = signatures[0]; - if (!signature.typeParameters && !isAritySmaller(signature, node)) { + if (!isAritySmaller(signature, node)) { return signature; } } @@ -13122,12 +13099,12 @@ namespace ts { return undefined; } if (!(type.flags & TypeFlags.Union)) { - return getNonGenericSignature(type, node); + return getContextualCallSignature(type, node); } let signatureList: Signature[]; const types = (type).types; for (const current of types) { - const signature = getNonGenericSignature(current, node); + const signature = getContextualCallSignature(current, node); if (signature) { if (!signatureList) { // This signature will contribute to contextual union signature @@ -14193,9 +14170,13 @@ namespace ts { /** * Check if a property with the given name is known anywhere in the given type. In an object type, a property - * is considered known if the object type is empty and the check is for assignability, if the object type has - * index signatures, or if the property is actually declared in the object type. In a union or intersection - * type, a property is considered known if it is known in any constituent type. + * is considered known if + * 1. the object type is empty and the check is for assignability, or + * 2. if the object type has index signatures, or + * 3. if the property is actually declared in the object type + * (this means that 'toString', for example, is not usually a known property). + * 4. In a union or intersection type, + * a property is considered known if it is known in any constituent type. * @param targetType a type to search a given name in * @param name a property name to search * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType @@ -14205,7 +14186,7 @@ namespace ts { const resolved = resolveStructuredTypeMembers(targetType); if (resolved.stringIndexInfo || resolved.numberIndexInfo && isNumericLiteralName(name) || - getPropertyOfType(targetType, name) || + getPropertyOfObjectType(targetType, name) || isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) { // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. return true; @@ -14617,12 +14598,31 @@ namespace ts { ? (node).expression : (node).left; - const type = checkExpression(left); + return isValidPropertyAccessWithType(node, left, propertyName, getWidenedType(checkExpression(left))); + } + + function isValidPropertyAccessWithType( + node: PropertyAccessExpression | QualifiedName, + left: LeftHandSideExpression | QualifiedName, + propertyName: string, + type: Type): boolean { + if (type !== unknownType && !isTypeAny(type)) { - const prop = getPropertyOfType(getWidenedType(type), propertyName); + const prop = getPropertyOfType(type, propertyName); if (prop) { return checkPropertyAccessibility(node, left, type, prop); } + + // In js files properties of unions are allowed in completion + if (isInJavaScriptFile(left) && (type.flags & TypeFlags.Union)) { + for (const elementType of (type).types) { + if (isValidPropertyAccessWithType(node, left, propertyName, elementType)) { + return true; + } + } + } + + return false; } return true; } @@ -14943,12 +14943,15 @@ namespace ts { } // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec) - function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper: TypeMapper): Signature { + function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper): Signature { const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes); forEachMatchingParameterType(contextualSignature, signature, (source, target) => { // Type parameters from outer context referenced by source type are fixed by instantiation of the source type - inferTypes(context.inferences, instantiateType(source, contextualMapper), target); + inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target); }); + if (!contextualMapper) { + inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), InferencePriority.ReturnType); + } return getSignatureInstantiation(signature, getInferredTypes(context)); } @@ -14966,17 +14969,6 @@ namespace ts { } } - // On this call to inferTypeArguments, we may get more inferences for certain type parameters that were not - // fixed last time. This means that a type parameter that failed inference last time may succeed this time, - // or vice versa. Therefore, the failedTypeParameterIndex is useless if it points to an unfixed type parameter, - // because it may change. So here we reset it. However, getInferredType will not revisit any type parameters - // that were previously fixed. So if a fixed type parameter failed previously, it will fail again because - // it will contain the exact same set of inferences. So if we reset the index from a fixed type parameter, - // we will lose information that we won't recover this time around. - if (context.failedTypeParameterIndex !== undefined && !context.inferences[context.failedTypeParameterIndex].isFixed) { - context.failedTypeParameterIndex = undefined; - } - // If a contextual type is available, infer from that type to the return type of the call expression. For // example, given a 'function wrap(cb: (x: T) => U): (x: T) => U' and a call expression // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the @@ -14987,11 +14979,21 @@ namespace ts { // We clone the contextual mapper to avoid disturbing a resolution in progress for an // outer call expression. Effectively we just want a snapshot of whatever has been // inferred for any outer call expression so far. - const mapper = cloneTypeMapper(getContextualMapper(node)); - const instantiatedType = instantiateType(contextualType, mapper); - const returnType = getReturnTypeOfSignature(signature); - // Inferences made from return types have lower priority than all other inferences. - inferTypes(context.inferences, instantiatedType, returnType, InferencePriority.ReturnType); + const instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node))); + // If the contextual type is a generic function type with a single call signature, we + // instantiate the type with its own type parameters and type arguments. This ensures that + // the type parameters are not erased to type any during type inference such that they can + // be inferred as actual types from the contextual type. For example: + // declare function arrayMap(f: (x: T) => U): (a: T[]) => U[]; + // const boxElements: (a: A[]) => { value: A }[] = arrayMap(value => ({ value })); + // Above, the type of the 'value' parameter is inferred to be 'A'. + const contextualSignature = getSingleCallSignature(instantiatedType); + const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ? + getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters)) : + instantiatedType; + const inferenceTargetType = getReturnTypeOfSignature(signature); + // Inferences made from return types have lower priority than all other inferences. + inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType); } } @@ -15490,21 +15492,6 @@ namespace ts { } } - if (signatures.length === 1) { - const declaration = signatures[0].declaration; - if (declaration && isInJavaScriptFile(declaration) && !hasJSDocParameterTags(declaration)) { - if (containsArgumentsReference(declaration)) { - const signatureWithRest = cloneSignature(signatures[0]); - const syntheticArgsSymbol = createSymbol(SymbolFlags.Variable, "args"); - syntheticArgsSymbol.type = anyArrayType; - syntheticArgsSymbol.isRestParameter = true; - signatureWithRest.parameters = concatenate(signatureWithRest.parameters, [syntheticArgsSymbol]); - signatureWithRest.hasRestParameter = true; - signatures = [signatureWithRest]; - } - } - } - const candidates = candidatesOutArray || []; // reorderCandidates fills up the candidates array directly reorderCandidates(signatures, candidates); @@ -15550,9 +15537,9 @@ namespace ts { // was fine. So if there is any overload that is only incorrect because of an // argument, we will report an error on that one. // - // function foo(s: string) {} - // function foo(n: number) {} // Report argument error on this overload - // function foo() {} + // function foo(s: string): void; + // function foo(n: number): void; // Report argument error on this overload + // function foo(): void; // foo(true); // // If none of the overloads even made it that far, there are two possibilities. @@ -15560,13 +15547,12 @@ namespace ts { // report an error on that. Or none of the overloads even had correct arity, // in which case give an arity error. // - // function foo(x: T, y: T) {} // Report type argument inference error - // function foo() {} - // foo(0, true); + // function foo(x: T): void; // Report type argument error + // function foo(): void; + // foo(0); // let candidateForArgumentError: Signature; let candidateForTypeArgumentError: Signature; - let resultOfFailedInference: InferenceContext; let result: Signature; // If we are in signature help, a trailing comma indicates that we intend to provide another argument, @@ -15588,10 +15574,6 @@ namespace ts { result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma); } if (!result) { - // Reinitialize these pointers for round two - candidateForArgumentError = undefined; - candidateForTypeArgumentError = undefined; - resultOfFailedInference = undefined; result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma); } if (result) { @@ -15615,25 +15597,8 @@ namespace ts { checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true); } else if (candidateForTypeArgumentError) { - if (!isTaggedTemplate && !isDecorator && typeArguments) { - const typeArguments = (node).typeArguments; - checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNode), /*reportErrors*/ true, fallbackError); - } - else { - Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0); - const failedTypeParameter = candidateForTypeArgumentError.typeParameters[resultOfFailedInference.failedTypeParameterIndex]; - const inferenceCandidates = resultOfFailedInference.inferences[resultOfFailedInference.failedTypeParameterIndex].candidates; - - let diagnosticChainHead = chainDiagnosticMessages(/*details*/ undefined, // details will be provided by call to reportNoCommonSupertypeError - Diagnostics.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly, - typeToString(failedTypeParameter)); - - if (fallbackError) { - diagnosticChainHead = chainDiagnosticMessages(diagnosticChainHead, fallbackError); - } - - reportNoCommonSupertypeError(inferenceCandidates, (node).tagName || (node).expression || (node).tag, diagnosticChainHead); - } + const typeArguments = (node).typeArguments; + checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNode), /*reportErrors*/ true, fallbackError); } else if (typeArguments && every(signatures, sig => length(sig.typeParameters) !== typeArguments.length)) { let min = Number.POSITIVE_INFINITY; @@ -15687,35 +15652,36 @@ namespace ts { return resolveErrorCall(node); function chooseOverload(candidates: Signature[], relation: Map, signatureHelpTrailingComma = false) { + candidateForArgumentError = undefined; + candidateForTypeArgumentError = undefined; for (const originalCandidate of candidates) { if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) { continue; } let candidate: Signature; - let typeArgumentsAreValid: boolean; - const inferenceContext = originalCandidate.typeParameters - ? createInferenceContext(originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : 0) - : undefined; + const inferenceContext = originalCandidate.typeParameters ? + createInferenceContext(originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : 0) : + undefined; while (true) { candidate = originalCandidate; if (candidate.typeParameters) { - let typeArgumentTypes: Type[] | undefined; + let typeArgumentTypes: Type[]; if (typeArguments) { typeArgumentTypes = fillMissingTypeArguments(map(typeArguments, getTypeFromTypeNode), candidate.typeParameters, getMinTypeArgumentCount(candidate.typeParameters)); - typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false); + if (!checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false)) { + candidateForTypeArgumentError = originalCandidate; + break; + } } else { typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext); - typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex === undefined; - } - if (!typeArgumentsAreValid) { - break; } candidate = getSignatureInstantiation(candidate, typeArgumentTypes); } if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { + candidateForArgumentError = candidate; break; } const index = excludeArgument ? indexOf(excludeArgument, /*value*/ true) : -1; @@ -15724,28 +15690,6 @@ namespace ts { } excludeArgument[index] = false; } - - // A post-mortem of this iteration of the loop. The signature was not applicable, - // so we want to track it as a candidate for reporting an error. If the candidate - // had no type parameters, or had no issues related to type arguments, we can - // report an error based on the arguments. If there was an issue with type - // arguments, then we can only report an error based on the type arguments. - if (originalCandidate.typeParameters) { - const instantiatedCandidate = candidate; - if (typeArgumentsAreValid) { - candidateForArgumentError = instantiatedCandidate; - } - else { - candidateForTypeArgumentError = originalCandidate; - if (!typeArguments) { - resultOfFailedInference = inferenceContext; - } - } - } - else { - Debug.assert(originalCandidate === candidate); - candidateForArgumentError = originalCandidate; - } } return undefined; @@ -15898,7 +15842,7 @@ namespace ts { const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call); if (callSignatures.length) { const signature = resolveCall(node, callSignatures, candidatesOutArray); - if (getReturnTypeOfSignature(signature) !== voidType) { + if (!isJavaScriptConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) { error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword); } if (getThisTypeOfSignature(signature) === voidType) { @@ -16125,14 +16069,40 @@ namespace ts { return getNodeLinks(node).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(node); } + /** + * Indicates whether a declaration can be treated as a constructor in a JavaScript + * file. + */ + function isJavaScriptConstructor(node: Declaration): boolean { + if (isInJavaScriptFile(node)) { + // If the node has a @class tag, treat it like a constructor. + if (getJSDocClassTag(node)) return true; + + // If the symbol of the node has members, treat it like a constructor. + const symbol = isFunctionDeclaration(node) || isFunctionExpression(node) ? getSymbolOfNode(node) : + isVariableDeclaration(node) && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) : + undefined; + + return symbol && symbol.members !== undefined; + } + + return false; + } + function getInferredClassType(symbol: Symbol) { const links = getSymbolLinks(symbol); if (!links.inferredClassType) { - links.inferredClassType = createAnonymousType(symbol, symbol.members, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined); + links.inferredClassType = createAnonymousType(symbol, symbol.members || emptySymbols, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined); } return links.inferredClassType; } + function isInferredClassType(type: Type) { + return type.symbol + && getObjectFlags(type) & ObjectFlags.Anonymous + && getSymbolLinks(type.symbol).inferredClassType === type; + } + /** * Syntactically and semantically checks a call or new expression. * @param node The call/new expression to be checked. @@ -16168,7 +16138,7 @@ namespace ts { if (funcSymbol && isDeclarationOfFunctionOrClassExpression(funcSymbol)) { funcSymbol = getSymbolOfNode((funcSymbol.valueDeclaration).initializer); } - if (funcSymbol && funcSymbol.members && funcSymbol.flags & SymbolFlags.Function) { + if (funcSymbol && funcSymbol.flags & SymbolFlags.Function && (funcSymbol.members || getJSDocClassTag(funcSymbol.valueDeclaration))) { return getInferredClassType(funcSymbol); } else if (noImplicitAny) { @@ -16304,37 +16274,43 @@ namespace ts { return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType; } - function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper, checkMode: CheckMode) { + function inferFromAnnotatedParameters(signature: Signature, context: Signature, mapper: TypeMapper) { const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0); - if (checkMode === CheckMode.Inferential) { - for (let i = 0; i < len; i++) { - const declaration = signature.parameters[i].valueDeclaration; - if (declaration.type) { - inferTypes((mapper).inferences, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i)); + for (let i = 0; i < len; i++) { + const declaration = signature.parameters[i].valueDeclaration; + if (declaration.type) { + const typeNode = getEffectiveTypeAnnotationNode(declaration); + if (typeNode) { + inferTypes((mapper).inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i)); } } } + } + + function assignContextualParameterTypes(signature: Signature, context: Signature) { + signature.typeParameters = context.typeParameters; if (context.thisParameter) { const parameter = signature.thisParameter; if (!parameter || parameter.valueDeclaration && !(parameter.valueDeclaration).type) { if (!parameter) { signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined); } - assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper, checkMode); + assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter)); } } + const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0); for (let i = 0; i < len; i++) { const parameter = signature.parameters[i]; - if (!(parameter.valueDeclaration).type) { + if (!getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) { const contextualParameterType = getTypeAtPosition(context, i); - assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode); + assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType); } } if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) { const parameter = lastOrUndefined(signature.parameters); - if (!(parameter.valueDeclaration).type) { + if (!getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) { const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters)); - assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode); + assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType); } } } @@ -16354,10 +16330,10 @@ namespace ts { } } - function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper, checkMode: CheckMode) { + function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type) { const links = getSymbolLinks(parameter); if (!links.type) { - links.type = instantiateType(contextualType, mapper); + links.type = contextualType; const name = getNameOfDeclaration(parameter.valueDeclaration); // if inference didn't come up with anything but {}, fall back to the binding pattern if present. if (links.type === emptyObjectType && @@ -16366,47 +16342,6 @@ namespace ts { } assignBindingElementTypes(parameter.valueDeclaration); } - else if (checkMode === CheckMode.Inferential) { - // Even if the parameter already has a type, it might be because it was given a type while - // processing the function as an argument to a prior signature during overload resolution. - // If this was the case, it may have caused some type parameters to be fixed. So here, - // we need to ensure that type parameters at the same positions get fixed again. This is - // done by calling instantiateType to attach the mapper to the contextualType, and then - // calling inferTypes to force a walk of contextualType so that all the correct fixing - // happens. The choice to pass in links.type may seem kind of arbitrary, but it serves - // to make sure that all the correct positions in contextualType are reached by the walk. - // Here is an example: - // - // interface Base { - // baseProp; - // } - // interface Derived extends Base { - // toBase(): Base; - // } - // - // var derived: Derived; - // - // declare function foo(x: T, func: (p: T) => T): T; - // declare function foo(x: T, func: (p: T) => T): T; - // - // var result = foo(derived, d => d.toBase()); - // - // We are typing d while checking the second overload. But we've already given d - // a type (Derived) from the first overload. However, we still want to fix the - // T in the second overload so that we do not infer Base as a candidate for T - // (inferring Base would make type argument inference inconsistent between the two - // overloads). - inferTypes((mapper).inferences, links.type, instantiateType(contextualType, mapper)); - } - } - - function getReturnTypeFromJSDocComment(func: SignatureDeclaration | FunctionDeclaration): Type { - const returnTag = getJSDocReturnTag(func); - if (returnTag && returnTag.typeExpression) { - return getTypeFromTypeNode(returnTag.typeExpression.type); - } - - return undefined; } function createPromiseType(promisedType: Type): Type { @@ -16634,16 +16569,16 @@ namespace ts { const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn; if (returnType && returnType.flags & TypeFlags.Never) { - error(func.type, Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point); + error(getEffectiveReturnTypeNode(func), Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point); } else if (returnType && !hasExplicitReturn) { // minimal check: function has syntactic return type annotation and no explicit return statements in the body // this function does not conform to the specification. // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present - error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value); + error(getEffectiveReturnTypeNode(func), Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value); } else if (returnType && strictNullChecks && !isTypeAssignableTo(undefinedType, returnType)) { - error(func.type, Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); + error(getEffectiveReturnTypeNode(func), Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); } else if (compilerOptions.noImplicitReturns) { if (!returnType) { @@ -16658,7 +16593,7 @@ namespace ts { return; } } - error(func.type || func, Diagnostics.Not_all_code_paths_return_a_value); + error(getEffectiveReturnTypeNode(func) || func, Diagnostics.Not_all_code_paths_return_a_value); } } @@ -16679,37 +16614,35 @@ namespace ts { const links = getNodeLinks(node); const type = getTypeOfSymbol(node.symbol); - const contextSensitive = isContextSensitive(node); - const mightFixTypeParameters = contextSensitive && checkMode === CheckMode.Inferential; // Check if function expression is contextually typed and assign parameter types if so. - // See the comment in assignTypeToParameterAndFixTypeParameters to understand why we need to - // check mightFixTypeParameters. - if (mightFixTypeParameters || !(links.flags & NodeCheckFlags.ContextChecked)) { + if (!(links.flags & NodeCheckFlags.ContextChecked)) { const contextualSignature = getContextualSignature(node); // If a type check is started at a function expression that is an argument of a function call, obtaining the // contextual type may recursively get back to here during overload resolution of the call. If so, we will have // already assigned contextual types. - const contextChecked = !!(links.flags & NodeCheckFlags.ContextChecked); - if (mightFixTypeParameters || !contextChecked) { + if (!(links.flags & NodeCheckFlags.ContextChecked)) { links.flags |= NodeCheckFlags.ContextChecked; if (contextualSignature) { const signature = getSignaturesOfType(type, SignatureKind.Call)[0]; - if (contextSensitive) { - assignContextualParameterTypes(signature, contextualSignature, getContextualMapper(node), checkMode); + if (isContextSensitive(node)) { + const contextualMapper = getContextualMapper(node); + if (checkMode === CheckMode.Inferential) { + inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper); + } + const instantiatedContextualSignature = contextualMapper === identityMapper ? + contextualSignature : instantiateSignature(contextualSignature, contextualMapper); + assignContextualParameterTypes(signature, instantiatedContextualSignature); } - if (mightFixTypeParameters || !node.type && !signature.resolvedReturnType) { + if (!getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) { const returnType = getReturnTypeFromBody(node, checkMode); if (!signature.resolvedReturnType) { signature.resolvedReturnType = returnType; } } } - - if (!contextChecked) { - checkSignatureDeclaration(node); - checkNodeDeferred(node); - } + checkSignatureDeclaration(node); + checkNodeDeferred(node); } } @@ -16726,10 +16659,11 @@ namespace ts { Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node)); const functionFlags = getFunctionFlags(node); - const returnOrPromisedType = node.type && + const returnTypeNode = getEffectiveReturnTypeNode(node); + const returnOrPromisedType = returnTypeNode && ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async ? checkAsyncFunctionReturnType(node) : // Async function - getTypeFromTypeNode(node.type)); // AsyncGenerator function, Generator function, or normal function + getTypeFromTypeNode(returnTypeNode)); // AsyncGenerator function, Generator function, or normal function if ((functionFlags & FunctionFlags.Generator) === 0) { // Async function or normal function // return is not necessary in the body of generators @@ -16737,7 +16671,7 @@ namespace ts { } if (node.body) { - if (!node.type) { + if (!returnTypeNode) { // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors // we need. An example is the noImplicitAny errors resulting from widening the return expression // of a function. Because checking of function expression bodies is deferred, there was never an @@ -16800,8 +16734,9 @@ namespace ts { (expr as PropertyAccessExpression | ElementAccessExpression).expression.kind === SyntaxKind.ThisKeyword) { // Look for if this is the constructor for the class that `symbol` is a property of. const func = getContainingFunction(expr); - if (!(func && func.kind === SyntaxKind.Constructor)) + if (!(func && func.kind === SyntaxKind.Constructor)) { return true; + } // If func.parent is a class and symbol is a (readonly) property of that class, or // if func is a constructor and symbol is a (readonly) parameter property declared in it, // then symbol is writeable here. @@ -16828,7 +16763,7 @@ namespace ts { function checkReferenceExpression(expr: Expression, invalidReferenceMessage: DiagnosticMessage): boolean { // References are combinations of identifiers, parentheses, and property accesses. - const node = skipParentheses(expr); + const node = skipOuterExpressions(expr, OuterExpressionKinds.Assertions | OuterExpressionKinds.Parentheses); if (node.kind !== SyntaxKind.Identifier && node.kind !== SyntaxKind.PropertyAccessExpression && node.kind !== SyntaxKind.ElementAccessExpression) { error(expr, invalidReferenceMessage); return false; @@ -17522,8 +17457,9 @@ namespace ts { // There is no point in doing an assignability check if the function // has no explicit return type because the return type is directly computed // from the yield expressions. - if (func.type) { - const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(func.type), (functionFlags & FunctionFlags.Async) !== 0) || anyType; + const returnType = getEffectiveReturnTypeNode(func); + if (returnType) { + const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), (functionFlags & FunctionFlags.Async) !== 0) || anyType; if (nodeIsYieldStar) { checkTypeAssignableTo( functionFlags & FunctionFlags.Async @@ -17679,7 +17615,7 @@ namespace ts { if (signature && signature.typeParameters) { const contextualType = getApparentTypeOfContextualType(node); if (contextualType) { - const contextualSignature = getSingleCallSignature(contextualType); + const contextualSignature = getSingleCallSignature(getNonNullableType(contextualType)); if (contextualSignature && !contextualSignature.typeParameters) { return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node))); } @@ -18051,13 +17987,15 @@ namespace ts { forEach(node.parameters, checkParameter); + // TODO(rbuckton): Should we start checking JSDoc types? if (node.type) { checkSourceElement(node.type); } if (produceDiagnostics) { checkCollisionWithArgumentsInGeneratedCode(node); - if (noImplicitAny && !node.type) { + const returnTypeNode = getEffectiveReturnTypeNode(node); + if (noImplicitAny && !returnTypeNode) { switch (node.kind) { case SyntaxKind.ConstructSignature: error(node, Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); @@ -18068,12 +18006,12 @@ namespace ts { } } - if (node.type) { + if (returnTypeNode) { const functionFlags = getFunctionFlags(node); if ((functionFlags & (FunctionFlags.Invalid | FunctionFlags.Generator)) === FunctionFlags.Generator) { - const returnType = getTypeFromTypeNode(node.type); + const returnType = getTypeFromTypeNode(returnTypeNode); if (returnType === voidType) { - error(node.type, Diagnostics.A_generator_cannot_have_a_void_type_annotation); + error(returnTypeNode, Diagnostics.A_generator_cannot_have_a_void_type_annotation); } else { const generatorElementType = getIteratedTypeOfGenerator(returnType, (functionFlags & FunctionFlags.Async) !== 0) || anyType; @@ -18087,7 +18025,7 @@ namespace ts { // interface BadGenerator extends Iterable, Iterator { } // function* g(): BadGenerator { } // Iterable and Iterator have different types! // - checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type); + checkTypeAssignableTo(iterableIteratorInstantiation, returnType, returnTypeNode); } } else if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { @@ -19099,7 +19037,8 @@ namespace ts { // then(...): Promise; // } // - const returnType = getTypeFromTypeNode(node.type); + const returnTypeNode = getEffectiveReturnTypeNode(node); + const returnType = getTypeFromTypeNode(returnTypeNode); if (languageVersion >= ScriptTarget.ES2015) { if (returnType === unknownType) { @@ -19109,21 +19048,21 @@ namespace ts { if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) { // The promise type was not a valid type reference to the global promise type, so we // report an error and return the unknown type. - error(node.type, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); + error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); return unknownType; } } else { // Always mark the type node as referenced if it points to a value - markTypeNodeAsReferenced(node.type); + markTypeNodeAsReferenced(returnTypeNode); if (returnType === unknownType) { return unknownType; } - const promiseConstructorName = getEntityNameFromTypeNode(node.type); + const promiseConstructorName = getEntityNameFromTypeNode(returnTypeNode); if (promiseConstructorName === undefined) { - error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType)); + error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType)); return unknownType; } @@ -19131,10 +19070,10 @@ namespace ts { const promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : unknownType; if (promiseConstructorType === unknownType) { if (promiseConstructorName.kind === SyntaxKind.Identifier && promiseConstructorName.text === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) { - error(node.type, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); + error(returnTypeNode, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); } else { - error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); + error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); } return unknownType; } @@ -19143,11 +19082,11 @@ namespace ts { if (globalPromiseConstructorLikeType === emptyObjectType) { // If we couldn't resolve the global PromiseConstructorLike type we cannot verify // compatibility with __awaiter. - error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); + error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName)); return unknownType; } - if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node.type, + if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) { return unknownType; } @@ -19292,7 +19231,8 @@ namespace ts { } function getParameterTypeNodeForDecoratorCheck(node: ParameterDeclaration): TypeNode { - return node.dotDotDotToken ? getRestParameterElementType(node.type) : node.type; + const typeNode = getEffectiveTypeAnnotationNode(node); + return isRestParameter(node) ? getRestParameterElementType(typeNode) : typeNode; } /** Check the decorators of a node */ @@ -19338,14 +19278,15 @@ namespace ts { markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter)); } - markDecoratorMedataDataTypeNodeAsReferenced((node).type); + markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveReturnTypeNode(node)); break; case SyntaxKind.PropertyDeclaration: - markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node)); + markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveTypeAnnotationNode(node)); break; + case SyntaxKind.Parameter: - markDecoratorMedataDataTypeNodeAsReferenced((node).type); + markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node)); break; } } @@ -19355,8 +19296,8 @@ namespace ts { function checkFunctionDeclaration(node: FunctionDeclaration): void { if (produceDiagnostics) { - checkFunctionOrMethodDeclaration(node) || checkGrammarForGenerator(node); - + checkFunctionOrMethodDeclaration(node); + checkGrammarForGenerator(node); checkCollisionWithCapturedSuperVariable(node, node.name); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithCapturedNewTargetVariable(node, node.name); @@ -19410,14 +19351,15 @@ namespace ts { checkSourceElement(node.body); + const returnTypeNode = getEffectiveReturnTypeNode(node); if ((functionFlags & FunctionFlags.Generator) === 0) { // Async function or normal function - const returnOrPromisedType = node.type && (functionFlags & FunctionFlags.Async + const returnOrPromisedType = returnTypeNode && (functionFlags & FunctionFlags.Async ? checkAsyncFunctionReturnType(node) // Async function - : getTypeFromTypeNode(node.type)); // normal function + : getTypeFromTypeNode(returnTypeNode)); // normal function checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType); } - if (produceDiagnostics && !node.type) { + if (produceDiagnostics && !returnTypeNode) { // Report an implicit any error if there is no body, no explicit return type, and node is not a private method // in an ambient context if (noImplicitAny && nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) { @@ -19522,9 +19464,7 @@ namespace ts { function errorUnusedLocal(node: Node, name: string) { if (isIdentifierThatStartsWithUnderScore(node)) { const declaration = getRootDeclaration(node.parent); - if (declaration.kind === SyntaxKind.VariableDeclaration && - (declaration.parent.parent.kind === SyntaxKind.ForInStatement || - declaration.parent.parent.kind === SyntaxKind.ForOfStatement)) { + if (declaration.kind === SyntaxKind.VariableDeclaration && isForInOrOfStatement(declaration.parent.parent)) { return; } } @@ -20217,7 +20157,7 @@ namespace ts { } } - function checkForInOrForOfVariableDeclaration(iterationStatement: ForInStatement | ForOfStatement): void { + function checkForInOrForOfVariableDeclaration(iterationStatement: ForInOrOfStatement): void { const variableDeclarationList = iterationStatement.initializer; // checkGrammarForInOrForOfStatement will check that there is exactly one declaration. if (variableDeclarationList.declarations.length >= 1) { @@ -20547,7 +20487,8 @@ namespace ts { } function isGetAccessorWithAnnotatedSetAccessor(node: FunctionLikeDeclaration) { - return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor))); + return node.kind === SyntaxKind.GetAccessor + && getEffectiveSetAccessorTypeAnnotationNode(getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)) !== undefined; } function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean { @@ -20591,7 +20532,7 @@ namespace ts { error(node, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } - else if (func.type || isGetAccessorWithAnnotatedSetAccessor(func)) { + else if (getEffectiveReturnTypeNode(func) || isGetAccessorWithAnnotatedSetAccessor(func)) { if (functionFlags & FunctionFlags.Async) { // Async function const promisedType = getPromisedTypeOfPromise(returnType); const awaitedType = checkAwaitedType(exprType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); @@ -21010,7 +20951,7 @@ namespace ts { const staticBaseType = getApparentType(baseConstructorType); checkBaseTypeAccessibility(staticBaseType, baseTypeNode); checkSourceElement(baseTypeNode.expression); - if (baseTypeNode.typeArguments) { + if (some(baseTypeNode.typeArguments)) { forEach(baseTypeNode.typeArguments, checkSourceElement); for (const constructor of getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode)) { if (!checkTypeArgumentConstraints(constructor.typeParameters, baseTypeNode.typeArguments)) { @@ -21729,7 +21670,10 @@ namespace ts { } // Don't allow to re-export something with no value side when `--isolatedModules` is set. - if (node.kind === SyntaxKind.ExportSpecifier && compilerOptions.isolatedModules && !(target.flags & SymbolFlags.Value)) { + if (compilerOptions.isolatedModules + && node.kind === SyntaxKind.ExportSpecifier + && !(target.flags & SymbolFlags.Value) + && !isInAmbientContext(node)) { error(node, Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided); } } @@ -21833,6 +21777,10 @@ namespace ts { if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) { error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol)); } + + if (modulekind !== ModuleKind.System && modulekind !== ModuleKind.ES2015) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar); + } } } } @@ -22487,10 +22435,16 @@ namespace ts { } if (entityName.parent!.kind === SyntaxKind.JSDocParameterTag) { - const parameter = ts.getParameterFromJSDoc(entityName.parent as JSDocParameterTag); + const parameter = getParameterFromJSDoc(entityName.parent as JSDocParameterTag); return parameter && parameter.symbol; } + if (entityName.parent.kind === SyntaxKind.TypeParameter && entityName.parent.parent.kind === SyntaxKind.JSDocTemplateTag) { + Debug.assert(!isInJavaScriptFile(entityName)); // Otherwise `isDeclarationName` would have been true. + const typeParameter = getTypeParameterFromJsDoc(entityName.parent as TypeParameterDeclaration & { parent: JSDocTemplateTag }); + return typeParameter && typeParameter.symbol; + } + if (isPartOfExpression(entityName)) { if (nodeIsMissing(entityName)) { // Missing entity name. @@ -22601,14 +22555,12 @@ namespace ts { return undefined; case SyntaxKind.StringLiteral: - // External module name in an import declaration - if ((isExternalModuleImportEqualsDeclaration(node.parent.parent) && - getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) || - ((node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration) && - (node.parent).moduleSpecifier === node)) { - return resolveExternalModuleName(node, node); - } - if (isInJavaScriptFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) { + // 1). import x = require("./mo/*gotToDefinitionHere*/d") + // 2). External module name in an import declaration + // 3). Dynamic import call or require in javascript + if ((isExternalModuleImportEqualsDeclaration(node.parent.parent) && getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) || + ((node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration) && (node.parent).moduleSpecifier === node) || + ((isInJavaScriptFile(node) && isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) || isImportCall(node.parent))) { return resolveExternalModuleName(node, node); } // falls through @@ -22914,7 +22866,9 @@ namespace ts { node = getParseTreeNode(node, isIdentifier); if (node) { const symbol = getReferencedValueSymbol(node); - if (symbol && symbol.flags & SymbolFlags.Alias) { + // We should only get the declaration of an alias if there isn't a local value + // declaration for the symbol + if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value)) { return getDeclarationOfAliasSymbol(symbol); } } @@ -23084,6 +23038,13 @@ namespace ts { !(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier); } + function isOptionalUninitializedParameterProperty(parameter: ParameterDeclaration) { + return strictNullChecks && + isOptionalParameter(parameter) && + !parameter.initializer && + !!(getModifierFlags(parameter) & ModifierFlags.ParameterPropertyModifier); + } + function getNodeCheckFlags(node: Node): NodeCheckFlags { return getNodeLinks(node).flags; } @@ -23293,6 +23254,7 @@ namespace ts { isDeclarationVisible, isImplementationOfOverload, isRequiredInitializedParameter, + isOptionalUninitializedParameterProperty, writeTypeOfDeclaration, writeReturnTypeOfSignatureDeclaration, writeTypeOfExpression, @@ -23505,7 +23467,8 @@ namespace ts { case ExternalEmitHelpers.AsyncGenerator: return "__asyncGenerator"; case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator"; case ExternalEmitHelpers.AsyncValues: return "__asyncValues"; - default: Debug.fail("Unrecognized helper."); + case ExternalEmitHelpers.ExportStar: return "__exportStar"; + default: Debug.fail("Unrecognized helper"); } } @@ -23971,6 +23934,11 @@ namespace ts { const sourceFile = getSourceFileOfNode(node); return grammarErrorAtPos(sourceFile, types.pos, 0, Diagnostics._0_list_cannot_be_empty, listType); } + return forEach(types, checkGrammarExpressionWithTypeArguments); + } + + function checkGrammarExpressionWithTypeArguments(node: ExpressionWithTypeArguments) { + return checkGrammarTypeArguments(node, node.typeArguments); } function checkGrammarClassDeclarationHeritageClauses(node: ClassLikeDeclaration) { @@ -24180,7 +24148,7 @@ namespace ts { } } - function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInStatement | ForOfStatement): boolean { + function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInOrOfStatement): boolean { if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) { return true; } @@ -24748,13 +24716,9 @@ namespace ts { switch (name.parent.kind) { case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: - if ((name.parent as ImportOrExportSpecifier).propertyName) { - return true; - } - // falls through + return true; default: return isDeclarationName(name); - } } } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c402fb39fcb..7b508351aec 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -620,6 +620,12 @@ namespace ts { category: Diagnostics.Advanced_Options, description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files }, + { + name: "noStrictGenericChecks", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types, + }, { // A list of plugins to load in the language service name: "plugins", @@ -2094,10 +2100,12 @@ namespace ts { } // Remove any subpaths under an existing recursively watched directory. - for (const key in wildcardDirectories) if (hasProperty(wildcardDirectories, key)) { - for (const recursiveKey of recursiveKeys) { - if (key !== recursiveKey && containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) { - delete wildcardDirectories[key]; + for (const key in wildcardDirectories) { + if (hasProperty(wildcardDirectories, key)) { + for (const recursiveKey of recursiveKeys) { + if (key !== recursiveKey && containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) { + delete wildcardDirectories[key]; + } } } } @@ -2185,10 +2193,12 @@ namespace ts { /* @internal */ export function convertCompilerOptionsForTelemetry(opts: ts.CompilerOptions): ts.CompilerOptions { const out: ts.CompilerOptions = {}; - for (const key in opts) if (opts.hasOwnProperty(key)) { - const type = getOptionFromName(key); - if (type !== undefined) { // Ignore unknown options - out[key] = getOptionValueWithEmptyStrings(opts[key], type); + for (const key in opts) { + if (opts.hasOwnProperty(key)) { + const type = getOptionFromName(key); + if (type !== undefined) { // Ignore unknown options + out[key] = getOptionValueWithEmptyStrings(opts[key], type); + } } } return out; diff --git a/src/compiler/core.ts b/src/compiler/core.ts index c1724a807d1..8e5bf017924 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -3,7 +3,7 @@ namespace ts { /** The version of the TypeScript compiler release */ - export const version = "2.4.0"; + export const version = "2.5.0"; } /* @internal */ @@ -51,8 +51,10 @@ namespace ts { // Copies keys/values from template. Note that for..in will not throw if // template is undefined, and instead will just exit the loop. - for (const key in template) if (hasOwnProperty.call(template, key)) { - map.set(key, template[key]); + for (const key in template) { + if (hasOwnProperty.call(template, key)) { + map.set(key, template[key]); + } } return map; @@ -521,8 +523,8 @@ namespace ts { return result || array; } - export function mapDefined(array: ReadonlyArray, mapFn: (x: T, i: number) => T | undefined): ReadonlyArray { - const result: T[] = []; + export function mapDefined(array: ReadonlyArray, mapFn: (x: T, i: number) => U | undefined): U[] { + const result: U[] = []; for (let i = 0; i < array.length; i++) { const item = array[i]; const mapped = mapFn(item, i); @@ -977,9 +979,12 @@ namespace ts { */ export function getOwnKeys(map: MapLike): string[] { const keys: string[] = []; - for (const key in map) if (hasOwnProperty.call(map, key)) { - keys.push(key); + for (const key in map) { + if (hasOwnProperty.call(map, key)) { + keys.push(key); + } } + return keys; } @@ -1042,8 +1047,10 @@ namespace ts { export function assign>(t: T1, ...args: any[]): any; export function assign>(t: T1, ...args: any[]) { for (const arg of args) { - for (const p in arg) if (hasProperty(arg, p)) { - t[p] = arg[p]; + for (const p in arg) { + if (hasProperty(arg, p)) { + t[p] = arg[p]; + } } } return t; @@ -1058,13 +1065,19 @@ namespace ts { export function equalOwnProperties(left: MapLike, right: MapLike, equalityComparer?: (left: T, right: T) => boolean) { if (left === right) return true; if (!left || !right) return false; - for (const key in left) if (hasOwnProperty.call(left, key)) { - if (!hasOwnProperty.call(right, key) === undefined) return false; - if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key]) return false; + for (const key in left) { + if (hasOwnProperty.call(left, key)) { + if (!hasOwnProperty.call(right, key) === undefined) return false; + if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key]) return false; + } } - for (const key in right) if (hasOwnProperty.call(right, key)) { - if (!hasOwnProperty.call(left, key)) return false; + + for (const key in right) { + if (hasOwnProperty.call(right, key)) { + if (!hasOwnProperty.call(left, key)) return false; + } } + return true; } @@ -1106,12 +1119,18 @@ namespace ts { export function extend(first: T1, second: T2): T1 & T2 { const result: T1 & T2 = {}; - for (const id in second) if (hasOwnProperty.call(second, id)) { - (result as any)[id] = (second as any)[id]; + for (const id in second) { + if (hasOwnProperty.call(second, id)) { + (result as any)[id] = (second as any)[id]; + } } - for (const id in first) if (hasOwnProperty.call(first, id)) { - (result as any)[id] = (first as any)[id]; + + for (const id in first) { + if (hasOwnProperty.call(first, id)) { + (result as any)[id] = (first as any)[id]; + } } + return result; } @@ -2112,13 +2131,13 @@ namespace ts { export function getScriptKindFromFileName(fileName: string): ScriptKind { const ext = fileName.substr(fileName.lastIndexOf(".")); switch (ext.toLowerCase()) { - case ".js": + case Extension.Js: return ScriptKind.JS; - case ".jsx": + case Extension.Jsx: return ScriptKind.JSX; - case ".ts": + case Extension.Ts: return ScriptKind.TS; - case ".tsx": + case Extension.Tsx: return ScriptKind.TSX; case ".json": return ScriptKind.JSON; @@ -2130,10 +2149,10 @@ namespace ts { /** * List of supported extensions in order of file resolution precedence. */ - export const supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"]; + export const supportedTypeScriptExtensions = [Extension.Ts, Extension.Tsx, Extension.Dts]; /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */ - export const supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"]; - export const supportedJavascriptExtensions = [".js", ".jsx"]; + export const supportedTypescriptExtensionsForExtractExtension = [Extension.Dts, Extension.Ts, Extension.Tsx]; + export const supportedJavascriptExtensions = [Extension.Js, Extension.Jsx]; const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions); export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: JsFileExtensionInfo[]): string[] { @@ -2141,7 +2160,7 @@ namespace ts { if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions; } - const extensions = allSupportedExtensions.slice(0); + const extensions: string[] = allSupportedExtensions.slice(0); for (const extInfo of extraFileExtensions) { if (extensions.indexOf(extInfo.extension) === -1) { extensions.push(extInfo.extension); @@ -2220,7 +2239,7 @@ namespace ts { } } - const extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".jsx"]; + const extensionsToRemove = [Extension.Dts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx]; export function removeFileExtension(path: string): string { for (const ext of extensionsToRemove) { const extensionless = tryRemoveExtension(path, ext); @@ -2251,6 +2270,7 @@ namespace ts { getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol; getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type; getSignatureConstructor(): new (checker: TypeChecker) => Signature; + getSourceMapSourceConstructor(): new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; } function Symbol(this: Symbol, flags: SymbolFlags, name: string) { @@ -2281,6 +2301,12 @@ namespace ts { this.original = undefined; } + function SourceMapSource(this: SourceMapSource, fileName: string, text: string, skipTrivia?: (pos: number) => number) { + this.fileName = fileName; + this.text = text; + this.skipTrivia = skipTrivia || (pos => pos); + } + export let objectAllocator: ObjectAllocator = { getNodeConstructor: () => Node, getTokenConstructor: () => Node, @@ -2288,7 +2314,8 @@ namespace ts { getSourceFileConstructor: () => Node, getSymbolConstructor: () => Symbol, getTypeConstructor: () => Type, - getSignatureConstructor: () => Signature + getSignatureConstructor: () => Signature, + getSourceMapSourceConstructor: () => SourceMapSource, }; export const enum AssertionLevel { @@ -2466,7 +2493,7 @@ namespace ts { /** True if an extension is one of the supported TypeScript extensions. */ export function extensionIsTypeScript(ext: Extension): boolean { - return ext <= Extension.LastTypeScriptExtension; + return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts; } /** @@ -2481,21 +2508,7 @@ namespace ts { Debug.fail(`File ${path} has unknown extension.`); } export function tryGetExtensionFromPath(path: string): Extension | undefined { - if (fileExtensionIs(path, ".d.ts")) { - return Extension.Dts; - } - if (fileExtensionIs(path, ".ts")) { - return Extension.Ts; - } - if (fileExtensionIs(path, ".tsx")) { - return Extension.Tsx; - } - if (fileExtensionIs(path, ".js")) { - return Extension.Js; - } - if (fileExtensionIs(path, ".jsx")) { - return Extension.Jsx; - } + return find(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || find(supportedJavascriptExtensions, e => fileExtensionIs(path, e)); } export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 987157843b6..753080cc6a0 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -335,9 +335,12 @@ namespace ts { write(": "); // use the checker's type, not the declared type, - // for non-optional initialized parameters that aren't a parameter property + // for optional parameter properties + // and also for non-optional initialized parameters that aren't a parameter property + // these types may need to add `undefined`. const shouldUseResolverType = declaration.kind === SyntaxKind.Parameter && - resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration); + (resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration) || + resolver.isOptionalUninitializedParameterProperty(declaration as ParameterDeclaration)); if (type && !shouldUseResolverType) { // Write the type emitType(type); @@ -596,7 +599,7 @@ namespace ts { currentIdentifiers = node.identifiers; isCurrentFileExternalModule = isExternalModule(node); enclosingDeclaration = node; - emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComents*/ true); + emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComments*/ true); emitLines(node.statements); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c9dd01f241d..c5c90dc6278 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3286,6 +3286,10 @@ "category": "Message", "code": 6184 }, + "Disable strict checking of generic signatures in function types.": { + "category": "Message", + "code": 6185 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 @@ -3629,7 +3633,11 @@ "category": "Message", "code": 90024 }, - + "Prefix '{0}' with an underscore.": { + "category": "Message", + "code": 90025 + }, + "Convert function to an ES2015 class": { "category": "Message", "code": 95001 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index e0a323e0742..65cbee9873a 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -29,7 +29,7 @@ namespace ts { if (sourceFiles.length) { const jsFilePath = options.outFile || options.out; const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); - const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : ""; + const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + Extension.Dts : ""; action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles); } } @@ -50,19 +50,19 @@ namespace ts { // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve - function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): string { + function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): Extension { if (options.jsx === JsxEmit.Preserve) { if (isSourceFileJavaScript(sourceFile)) { - if (fileExtensionIs(sourceFile.fileName, ".jsx")) { - return ".jsx"; + if (fileExtensionIs(sourceFile.fileName, Extension.Jsx)) { + return Extension.Jsx; } } else if (sourceFile.languageVariant === LanguageVariant.JSX) { // TypeScript source file preserving JSX syntax - return ".jsx"; + return Extension.Jsx; } } - return ".js"; + return Extension.Js; } function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) { @@ -1023,7 +1023,7 @@ namespace ts { function emitConstructorType(node: ConstructorTypeNode) { write("new "); emitTypeParameters(node, node.typeParameters); - emitParametersForArrow(node, node.parameters); + emitParameters(node, node.parameters); write(" => "); emit(node.type); } @@ -2347,11 +2347,25 @@ namespace ts { emitList(parentNode, parameters, ListFormat.Parameters); } - function emitParametersForArrow(parentNode: Node, parameters: NodeArray) { - if (parameters && - parameters.length === 1 && - parameters[0].type === undefined && - parameters[0].pos === parentNode.pos) { + function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { + const parameter = singleOrUndefined(parameters); + return parameter + && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter + && !(isArrowFunction(parentNode) && parentNode.type) // arrow function may not have return type annotation + && !some(parentNode.decorators) // parent may not have decorators + && !some(parentNode.modifiers) // parent may not have modifiers + && !some(parentNode.typeParameters) // parent may not have type parameters + && !some(parameter.decorators) // parameter may not have decorators + && !some(parameter.modifiers) // parameter may not have modifiers + && !parameter.dotDotDotToken // parameter may not be rest + && !parameter.questionToken // parameter may not be optional + && !parameter.type // parameter may not have a type annotation + && !parameter.initializer // parameter may not have an initializer + && isIdentifier(parameter.name); // parameter name must be identifier + } + + function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) { + if (canEmitSimpleArrowHead(parentNode, parameters)) { emit(parameters[0]); } else { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 6fd0abfdbfc..ed3ed36e79a 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -228,7 +228,7 @@ namespace ts { // Signature elements - export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) { + export function createTypeParameterDeclaration(name: string | Identifier, constraint?: TypeNode, defaultType?: TypeNode) { const node = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration; node.name = asName(name); node.constraint = constraint; @@ -2306,15 +2306,24 @@ namespace ts { /** * Sets a custom text range to use when emitting source maps. */ - export function setSourceMapRange(node: T, range: TextRange | undefined) { + export function setSourceMapRange(node: T, range: SourceMapRange | undefined) { getOrCreateEmitNode(node).sourceMapRange = range; return node; } + let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; + + /** + * Create an external source map source file reference + */ + export function createSourceMapSource(fileName: string, text: string, skipTrivia?: (pos: number) => number): SourceMapSource { + return new (SourceMapSource || (SourceMapSource = objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia); + } + /** * Gets the TextRange to use for source maps for a token of a node. */ - export function getTokenSourceMapRange(node: Node, token: SyntaxKind): TextRange | undefined { + export function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined { const emitNode = node.emitNode; const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges; return tokenSourceMapRanges && tokenSourceMapRanges[token]; @@ -2323,7 +2332,7 @@ namespace ts { /** * Sets the TextRange to use for source maps for a token of a node. */ - export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: TextRange | undefined) { + export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined) { const emitNode = getOrCreateEmitNode(node); const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []); tokenSourceMapRanges[token] = range; @@ -3823,23 +3832,34 @@ namespace ts { return emitNode && emitNode.externalHelpersModuleName; } - export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions) { - if (compilerOptions.importHelpers && (isExternalModule(node) || compilerOptions.isolatedModules)) { + export function getOrCreateExternalHelpersModuleNameIfNeeded(node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean) { + if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) { const externalHelpersModuleName = getExternalHelpersModuleName(node); if (externalHelpersModuleName) { return externalHelpersModuleName; } - const helpers = getEmitHelpers(node); - if (helpers) { - for (const helper of helpers) { - if (!helper.scoped) { - const parseNode = getOriginalNode(node, isSourceFile); - const emitNode = getOrCreateEmitNode(parseNode); - return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText)); + const moduleKind = getEmitModuleKind(compilerOptions); + let create = hasExportStarsToExportValues + && moduleKind !== ModuleKind.System + && moduleKind !== ModuleKind.ES2015; + if (!create) { + const helpers = getEmitHelpers(node); + if (helpers) { + for (const helper of helpers) { + if (!helper.scoped) { + create = true; + break; + } } } } + + if (create) { + const parseNode = getOriginalNode(node, isSourceFile); + const emitNode = getOrCreateEmitNode(parseNode); + return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText)); + } } } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 4c6616c36d4..4ea590977e1 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -815,15 +815,15 @@ namespace ts { switch (extensions) { case Extensions.DtsOnly: - return tryExtension(".d.ts", Extension.Dts); + return tryExtension(Extension.Dts); case Extensions.TypeScript: - return tryExtension(".ts", Extension.Ts) || tryExtension(".tsx", Extension.Tsx) || tryExtension(".d.ts", Extension.Dts); + return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || tryExtension(Extension.Dts); case Extensions.JavaScript: - return tryExtension(".js", Extension.Js) || tryExtension(".jsx", Extension.Jsx); + return tryExtension(Extension.Js) || tryExtension(Extension.Jsx); } - function tryExtension(ext: string, extension: Extension): Resolved | undefined { - const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); + function tryExtension(extension: Extension): Resolved | undefined { + const path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state); return path && { path, extension }; } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 2cc1508cf41..0f08d677910 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -14,7 +14,7 @@ namespace ts { else if (kind === SyntaxKind.Identifier) { return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, pos, end); } - else if (kind < SyntaxKind.FirstNode) { + else if (!isNodeKind(kind)) { return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, pos, end); } else { @@ -489,7 +489,11 @@ namespace ts { // becoming detached from any SourceFile). It is recommended that this SourceFile not // be used once 'update' is called on it. export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile { - return IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); + const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); + // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import. + // We will manually port the flag to the new source file. + newSourceFile.flags |= (sourceFile.flags & NodeFlags.PossiblyContainsDynamicImport); + return newSourceFile; } /* @internal */ @@ -714,7 +718,7 @@ namespace ts { sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement); Debug.assert(token() === SyntaxKind.EndOfFileToken); - sourceFile.endOfFileToken = parseTokenNode(); + sourceFile.endOfFileToken = addJSDocComment(parseTokenNode() as EndOfFileToken); setExternalModuleIndicator(sourceFile); @@ -793,7 +797,7 @@ namespace ts { sourceFile.languageVersion = languageVersion; sourceFile.fileName = normalizePath(fileName); sourceFile.languageVariant = getLanguageVariant(scriptKind); - sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, ".d.ts"); + sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, Extension.Dts); sourceFile.scriptKind = scriptKind; return sourceFile; @@ -1132,7 +1136,7 @@ namespace ts { pos = scanner.getStartPos(); } - return kind >= SyntaxKind.FirstNode ? new NodeConstructor(kind, pos, pos) : + return isNodeKind(kind) ? new NodeConstructor(kind, pos, pos) : kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, pos, pos) : new TokenConstructor(kind, pos, pos); } @@ -3001,7 +3005,7 @@ namespace ts { // for now we just check if the next token is an identifier. More heuristics // can be added here later as necessary. We just need to make sure that we // don't accidentally consume something legal. - return lookAhead(nextTokenIsIdentifierOrKeywordOrNumberOnSameLine); + return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); } return false; @@ -3519,7 +3523,7 @@ namespace ts { } // here we are using similar heuristics as 'isYieldExpression' - return lookAhead(nextTokenIsIdentifierOnSameLine); + return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); } return false; @@ -3734,7 +3738,7 @@ namespace ts { // For example: // var foo3 = require("subfolder // import * as foo1 from "module-from-node -> we want this import to be a statement rather than import call expression - sourceFile.flags |= NodeFlags.PossiblyContainDynamicImport; + sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport; expression = parseTokenNode(); } else { @@ -4728,9 +4732,9 @@ namespace ts { return token() === SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak(); } - function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() { + function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() { nextToken(); - return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral) && !scanner.hasPrecedingLineBreak(); + return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak(); } function isDeclaration(): boolean { @@ -6566,6 +6570,10 @@ namespace ts { case "augments": tag = parseAugmentsTag(atToken, tagName); break; + case "class": + case "constructor": + tag = parseClassTag(atToken, tagName); + break; case "arg": case "argument": case "param": @@ -6692,14 +6700,12 @@ namespace ts { }); } - function parseBracketNameInPropertyAndParamTag() { - let name: Identifier; - let isBracketed: boolean; + function parseBracketNameInPropertyAndParamTag(): { name: Identifier, isBracketed: boolean } { // Looking for something like '[foo]' or 'foo' - if (parseOptionalToken(SyntaxKind.OpenBracketToken)) { - name = parseJSDocIdentifierName(); + const isBracketed = parseOptional(SyntaxKind.OpenBracketToken); + const name = parseJSDocIdentifierName(/*createIfMissing*/ true); + if (isBracketed) { skipWhitespace(); - isBracketed = true; // May have an optional default, e.g. '[foo = 42]' if (parseOptionalToken(SyntaxKind.EqualsToken)) { @@ -6708,9 +6714,7 @@ namespace ts { parseExpected(SyntaxKind.CloseBracketToken); } - else if (tokenIsIdentifierOrKeyword(token())) { - name = parseJSDocIdentifierName(); - } + return { name, isBracketed }; } @@ -6721,20 +6725,12 @@ namespace ts { const { name, isBracketed } = parseBracketNameInPropertyAndParamTag(); skipWhitespace(); - if (!name) { - parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected); - return undefined; - } - let preName: Identifier, postName: Identifier; if (typeExpression) { postName = name; } else { preName = name; - } - - if (!typeExpression) { typeExpression = tryParseTypeExpression(); } @@ -6785,6 +6781,13 @@ namespace ts { return finishNode(result); } + function parseClassTag(atToken: AtToken, tagName: Identifier): JSDocClassTag { + const tag = createNode(SyntaxKind.JSDocClassTag, atToken.pos); + tag.atToken = atToken; + tag.tagName = tagName; + return finishNode(tag); + } + function parseTypedefTag(atToken: AtToken, tagName: Identifier): JSDocTypedefTag { const typeExpression = tryParseTypeExpression(); skipWhitespace(); @@ -6878,7 +6881,7 @@ namespace ts { jsDocNamespaceNode.flags |= flags; jsDocNamespaceNode.name = typeNameOrNamespaceName; jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(NodeFlags.NestedNamespace); - return jsDocNamespaceNode; + return finishNode(jsDocNamespaceNode); } if (typeNameOrNamespaceName && flags & NodeFlags.NestedNamespace) { @@ -6969,14 +6972,19 @@ namespace ts { return currentToken = scanner.scanJSDocToken(); } - function parseJSDocIdentifierName(): Identifier { - return createJSDocIdentifier(tokenIsIdentifierOrKeyword(token())); + function parseJSDocIdentifierName(createIfMissing = false): Identifier { + return createJSDocIdentifier(tokenIsIdentifierOrKeyword(token()), createIfMissing); } - function createJSDocIdentifier(isIdentifier: boolean): Identifier { + function createJSDocIdentifier(isIdentifier: boolean, createIfMissing: boolean): Identifier { if (!isIdentifier) { - parseErrorAtCurrentToken(Diagnostics.Identifier_expected); - return undefined; + if (createIfMissing) { + return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); + } + else { + parseErrorAtCurrentToken(Diagnostics.Identifier_expected); + return undefined; + } } const pos = scanner.getTokenPos(); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 17a3e4b16f6..bbc0fa09780 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1384,7 +1384,7 @@ namespace ts { for (const node of file.statements) { collectModuleReferences(node, /*inAmbientModule*/ false); - if ((file.flags & NodeFlags.PossiblyContainDynamicImport) || isJavaScriptFile) { + if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) { collectDynamicImportOrRequireCalls(node); } } @@ -1500,7 +1500,7 @@ namespace ts { } const sourceFileWithAddedExtension = forEach(supportedExtensions, extension => getSourceFile(fileName + extension)); - if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.File_0_not_found, fileName + ".ts"); + if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.File_0_not_found, fileName + Extension.Ts); return sourceFileWithAddedExtension; } } diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 68a36c40a80..dd43b3c8263 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -363,7 +363,7 @@ namespace ts { }; } - export function getLineAndCharacterOfPosition(sourceFile: SourceFile, position: number): LineAndCharacter { + export function getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: number): LineAndCharacter { return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); } diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index d743f488e75..ffef485581b 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -22,7 +22,7 @@ namespace ts { * * @param sourceFile The source file. */ - setSourceFile(sourceFile: SourceFile): void; + setSourceFile(sourceFile: SourceMapSource): void; /** * Emits a mapping. @@ -81,7 +81,7 @@ namespace ts { export function createSourceMapWriter(host: EmitHost, writer: EmitTextWriter): SourceMapWriter { const compilerOptions = host.getCompilerOptions(); const extendedDiagnostics = compilerOptions.extendedDiagnostics; - let currentSourceFile: SourceFile; + let currentSource: SourceMapSource; let currentSourceText: string; let sourceMapDir: string; // The directory in which sourcemap will be @@ -109,6 +109,13 @@ namespace ts { getSourceMappingURL, }; + /** + * Skips trivia such as comments and white-space that can optionally overriden by the source map source + */ + function skipSourceTrivia(pos: number): number { + return currentSource.skipTrivia ? currentSource.skipTrivia(pos) : skipTrivia(currentSourceText, pos); + } + /** * Initialize the SourceMapWriter for a new output file. * @@ -125,7 +132,7 @@ namespace ts { reset(); } - currentSourceFile = undefined; + currentSource = undefined; currentSourceText = undefined; // Current source map file and its index in the sources list @@ -192,7 +199,7 @@ namespace ts { return; } - currentSourceFile = undefined; + currentSource = undefined; sourceMapDir = undefined; sourceMapSourceIndex = undefined; lastRecordedSourceMapSpan = undefined; @@ -263,7 +270,7 @@ namespace ts { performance.mark("beforeSourcemap"); } - const sourceLinePos = getLineAndCharacterOfPosition(currentSourceFile, pos); + const sourceLinePos = getLineAndCharacterOfPosition(currentSource, pos); // Convert the location to be one-based. sourceLinePos.line++; @@ -320,14 +327,22 @@ namespace ts { if (node) { const emitNode = node.emitNode; const emitFlags = emitNode && emitNode.flags; - const { pos, end } = emitNode && emitNode.sourceMapRange || node; + const range = emitNode && emitNode.sourceMapRange; + const { pos, end } = range || node; + let source = range && range.source; + const oldSource = currentSource; + if (source === oldSource) source = undefined; + + if (source) setSourceFile(source); if (node.kind !== SyntaxKind.NotEmittedStatement && (emitFlags & EmitFlags.NoLeadingSourceMap) === 0 && pos >= 0) { - emitPos(skipTrivia(currentSourceText, pos)); + emitPos(skipSourceTrivia(pos)); } + if (source) setSourceFile(oldSource); + if (emitFlags & EmitFlags.NoNestedSourceMaps) { disabled = true; emitCallback(hint, node); @@ -337,11 +352,15 @@ namespace ts { emitCallback(hint, node); } + if (source) setSourceFile(source); + if (node.kind !== SyntaxKind.NotEmittedStatement && (emitFlags & EmitFlags.NoTrailingSourceMap) === 0 && end >= 0) { emitPos(end); } + + if (source) setSourceFile(oldSource); } } @@ -362,7 +381,7 @@ namespace ts { const emitFlags = emitNode && emitNode.flags; const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token]; - tokenPos = skipTrivia(currentSourceText, range ? range.pos : tokenPos); + tokenPos = skipSourceTrivia(range ? range.pos : tokenPos); if ((emitFlags & EmitFlags.NoTokenLeadingSourceMaps) === 0 && tokenPos >= 0) { emitPos(tokenPos); } @@ -382,13 +401,13 @@ namespace ts { * * @param sourceFile The source file. */ - function setSourceFile(sourceFile: SourceFile) { + function setSourceFile(sourceFile: SourceMapSource) { if (disabled) { return; } - currentSourceFile = sourceFile; - currentSourceText = currentSourceFile.text; + currentSource = sourceFile; + currentSourceText = currentSource.text; // Add the file to tsFilePaths // If sourceroot option: Use the relative path corresponding to the common directory path @@ -396,7 +415,7 @@ namespace ts { const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir; const source = getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, - currentSourceFile.fileName, + currentSource.fileName, host.getCurrentDirectory(), host.getCanonicalFileName, /*isAbsolutePathAnUrl*/ true); @@ -407,10 +426,10 @@ namespace ts { sourceMapData.sourceMapSources.push(source); // The one that can be used from program to get the actual source file - sourceMapData.inputSourceFileNames.push(currentSourceFile.fileName); + sourceMapData.inputSourceFileNames.push(currentSource.fileName); if (compilerOptions.inlineSources) { - sourceMapData.sourceMapSourcesContent.push(currentSourceFile.text); + sourceMapData.sourceMapSourcesContent.push(currentSource.text); } } } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 1abebe937e6..cd14f3b2801 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -35,6 +35,10 @@ namespace ts { getDirectories(path: string): string[]; readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[]; getModifiedTime?(path: string): Date; + /** + * This should be cryptographically secure. + * A good implementation is node.js' `crypto.createHash`. (https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm) + */ createHash?(data: string): string; getMemoryUsage?(): number; exit(exitCode?: number): void; diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index 076fde6b249..d61195ad74b 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -240,7 +240,7 @@ namespace ts { function hoistVariableDeclaration(name: Identifier): void { Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization."); Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed."); - const decl = createVariableDeclaration(name); + const decl = setEmitFlags(createVariableDeclaration(name), EmitFlags.NoNestedSourceMaps); if (!lexicalEnvironmentVariableDeclarations) { lexicalEnvironmentVariableDeclarations = [decl]; } diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 7acbd3126b4..4146574fe12 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3401,28 +3401,19 @@ namespace ts { classBodyStart++; } - // We reuse the comment and source-map positions from the original variable statement - // and class alias, while converting the function declaration for the class constructor - // into an expression. + // The next statement is the function declaration. + statements.push(funcStatements[classBodyStart]); + classBodyStart++; + + // Add the class alias following the declaration. statements.push( - updateVariableStatement( - varStatement, - /*modifiers*/ undefined, - updateVariableDeclarationList(varStatement.declarationList, [ - updateVariableDeclaration(variable, - variable.name, - /*type*/ undefined, - updateBinary(aliasAssignment, - aliasAssignment.left, - convertFunctionDeclarationToExpression( - cast(funcStatements[classBodyStart], isFunctionDeclaration) - ) - ) - ) - ]) + createStatement( + createAssignment( + aliasAssignment.left, + cast(variable.name, isIdentifier) + ) ) ); - classBodyStart++; } // Find the trailing 'return' statement (4) diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 9aadd6bc686..d0049e72f0b 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -640,10 +640,13 @@ namespace ts { return undefined; } - return createStatement( - inlineExpressions( - map(variables, transformInitializedVariable) - ) + return setSourceMapRange( + createStatement( + inlineExpressions( + map(variables, transformInitializedVariable) + ) + ), + node ); } } @@ -1281,9 +1284,12 @@ namespace ts { } function transformInitializedVariable(node: VariableDeclaration) { - return createAssignment( - getSynthesizedClone(node.name), - visitNode(node.initializer, visitor, isExpression) + return setSourceMapRange( + createAssignment( + setSourceMapRange(getSynthesizedClone(node.name), node.name), + visitNode(node.initializer, visitor, isExpression) + ), + node ); } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index b2e1c1c70a9..6141f52f5f4 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -103,7 +103,7 @@ namespace ts { addRange(statements, endLexicalEnvironment()); const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements)); - if (currentModuleInfo.hasExportStarsToExportValues) { + if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) { // If we have any `export * from ...` declarations // we need to inform the emitter to add the __export helper. addEmitHelper(updated, exportStarHelper); @@ -408,7 +408,7 @@ namespace ts { addRange(statements, endLexicalEnvironment()); const body = createBlock(statements, /*multiLine*/ true); - if (currentModuleInfo.hasExportStarsToExportValues) { + if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) { // If we have any `export * from ...` declarations // we need to inform the emitter to add the __export helper. addEmitHelper(body, exportStarHelper); @@ -514,14 +514,14 @@ namespace ts { function visitImportCallExpression(node: ImportCall): Expression { switch (compilerOptions.module) { - case ModuleKind.CommonJS: - return transformImportCallExpressionCommonJS(node); case ModuleKind.AMD: return transformImportCallExpressionAMD(node); case ModuleKind.UMD: return transformImportCallExpressionUMD(node); + case ModuleKind.CommonJS: + default: + return transformImportCallExpressionCommonJS(node); } - Debug.fail("All supported module kind in this transformation step should have been handled"); } function transformImportCallExpressionUMD(node: ImportCall): Expression { @@ -833,15 +833,7 @@ namespace ts { // export * from "mod"; return setTextRange( createStatement( - createCall( - createIdentifier("__export"), - /*typeArguments*/ undefined, - [ - moduleKind !== ModuleKind.AMD - ? createRequireCall(node) - : generatedName - ] - ) + createExportStarHelper(context, moduleKind !== ModuleKind.AMD ? createRequireCall(node) : generatedName) ), node ); @@ -1598,9 +1590,17 @@ namespace ts { text: ` function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; - }` + } + ` }; + function createExportStarHelper(context: TransformationContext, module: Expression) { + const compilerOptions = context.getCompilerOptions(); + return compilerOptions.importHelpers + ? createCall(getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, createIdentifier("exports")]) + : createCall(createIdentifier("__export"), /*typeArguments*/ undefined, [module]); + } + // emit helper for dynamic import const dynamicImportUMDHelper: EmitHelper = { name: "typescript:dynamicimport-sync-require", diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 709d13759c5..a39115a788e 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -25,17 +25,6 @@ namespace ts { let exportEquals: ExportAssignment = undefined; let hasExportStarsToExportValues = false; - const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions); - const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration( - /*decorators*/ undefined, - /*modifiers*/ undefined, - createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), - createLiteral(externalHelpersModuleNameText)); - - if (externalHelpersImportDeclaration) { - externalImports.push(externalHelpersImportDeclaration); - } - for (const node of sourceFile.statements) { switch (node.kind) { case SyntaxKind.ImportDeclaration: @@ -146,6 +135,17 @@ namespace ts { } } + const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues); + const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)), + createLiteral(externalHelpersModuleNameText)); + + if (externalHelpersImportDeclaration) { + externalImports.unshift(externalHelpersImportDeclaration); + } + return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration }; } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index f78e3cc2405..3b2422bfe08 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -655,6 +655,10 @@ namespace ts { } } +if (ts.Debug.isDebugging) { + ts.Debug.enableDebugInfo(); +} + if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) { ts.sys.tryEnableSourceMapsForHost(); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a01cec5b2a8..ac64624e1a6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -374,6 +374,7 @@ namespace ts { JSDocComment, JSDocTag, JSDocAugmentsTag, + JSDocClassTag, JSDocParameterTag, JSDocReturnTag, JSDocTypeTag, @@ -424,7 +425,7 @@ namespace ts { FirstNode = QualifiedName, FirstJSDocNode = JSDocTypeExpression, LastJSDocNode = JSDocLiteralType, - FirstJSDocTagNode = JSDocComment, + FirstJSDocTagNode = JSDocTag, LastJSDocTagNode = JSDocLiteralType } @@ -450,13 +451,16 @@ namespace ts { ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node - // This flag will be set to true when the parse encounter dynamic import so that post-parsing process of module resolution - // will not walk the tree if the flag is not set. However, this flag is just a approximation because once it is set, the flag never get reset. - // (hence it is named "possiblyContainDynamicImport"). - // During editing, if dynamic import is remove, incremental parsing will *NOT* update this flag. This will then causes walking of the tree during module resolution. - // However, the removal operation should not occur often and in the case of the removal, it is likely that users will add back the import anyway. - // The advantage of this approach is its simplicity. For the case of batch compilation, we garuntee that users won't have to pay the price of walking the tree if dynamic import isn't used. - PossiblyContainDynamicImport = 1 << 19, + // This flag will be set when the parser encounters a dynamic import expression so that module resolution + // will not have to walk the tree if the flag is not set. However, this flag is just a approximation because + // once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport"). + // During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed + // during module resolution. However, the removal operation should not occur often and in the case of the + // removal, it is likely that users will add the import anyway. + // The advantage of this approach is its simplicity. For the case of batch compilation, + // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used. + /* @internal */ + PossiblyContainsDynamicImport = 1 << 19, BlockScoped = Let | Const, @@ -1704,6 +1708,8 @@ namespace ts { incrementor?: Expression; } + export type ForInOrOfStatement = ForInStatement | ForOfStatement; + export interface ForInStatement extends IterationStatement { kind: SyntaxKind.ForInStatement; initializer: ForInitializer; @@ -1793,7 +1799,7 @@ namespace ts { block: Block; } - export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration; + export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag; export interface ClassLikeDeclaration extends NamedDeclaration { name?: Identifier; @@ -2132,6 +2138,10 @@ namespace ts { typeExpression: JSDocTypeExpression; } + export interface JSDocClassTag extends JSDocTag { + kind: SyntaxKind.JSDocClassTag; + } + export interface JSDocTemplateTag extends JSDocTag { kind: SyntaxKind.JSDocTemplateTag; typeParameters: NodeArray; @@ -2809,6 +2819,7 @@ namespace ts { collectLinkedAliases(node: Identifier): Node[]; isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; + isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean; writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void; @@ -3401,8 +3412,6 @@ namespace ts { signature: Signature; // Generic signature for which inferences are made inferences: InferenceInfo[]; // Inferences made for each type parameter flags: InferenceFlags; // Inference flags - failedTypeParameterIndex?: number; // Index of type parameter for which inference failed - // It is optional because in contextual signature instantiation, nothing fails } /* @internal */ @@ -3520,6 +3529,7 @@ namespace ts { noImplicitAny?: boolean; // Always combine with strict property noImplicitReturns?: boolean; noImplicitThis?: boolean; // Always combine with strict property + noStrictGenericChecks?: boolean; noUnusedLocals?: boolean; noUnusedParameters?: boolean; noImplicitUseStrict?: boolean; @@ -3882,13 +3892,12 @@ namespace ts { extension: Extension; } - export enum Extension { - Ts, - Tsx, - Dts, - Js, - Jsx, - LastTypeScriptExtension = Dts + export const enum Extension { + Ts = ".ts", + Tsx = ".tsx", + Dts = ".d.ts", + Js = ".js", + Jsx = ".jsx" } export interface ResolvedModuleWithFailedLookupLocations { @@ -4017,18 +4026,29 @@ namespace ts { ES2015FunctionSyntaxMask = ContainsCapturedLexicalThis | ContainsDefaultValueAssignments, } + export interface SourceMapRange extends TextRange { + source?: SourceMapSource; + } + + export interface SourceMapSource { + fileName: string; + text: string; + /* @internal */ lineMap: number[]; + skipTrivia?: (pos: number) => number; + } + /* @internal */ export interface EmitNode { - annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup. - flags?: EmitFlags; // Flags that customize emit - leadingComments?: SynthesizedComment[]; // Synthesized leading comments + annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup. + flags?: EmitFlags; // Flags that customize emit + leadingComments?: SynthesizedComment[]; // Synthesized leading comments trailingComments?: SynthesizedComment[]; // Synthesized trailing comments - commentRange?: TextRange; // The text range to use when emitting leading or trailing comments - sourceMapRange?: TextRange; // The text range to use when emitting leading or trailing source mappings - tokenSourceMapRanges?: TextRange[]; // The text range to use when emitting source mappings for tokens - constantValue?: string | number; // The constant value of an expression - externalHelpersModuleName?: Identifier; // The local name for an imported helpers module - helpers?: EmitHelper[]; // Emit helpers for the node + commentRange?: TextRange; // The text range to use when emitting leading or trailing comments + sourceMapRange?: SourceMapRange; // The text range to use when emitting leading or trailing source mappings + tokenSourceMapRanges?: SourceMapRange[]; // The text range to use when emitting source mappings for tokens + constantValue?: string | number; // The constant value of an expression + externalHelpersModuleName?: Identifier; // The local name for an imported helpers module + helpers?: EmitHelper[]; // Emit helpers for the node } export const enum EmitFlags { @@ -4090,6 +4110,7 @@ namespace ts { AsyncGenerator = 1 << 12, // __asyncGenerator (used by ES2017 async generator transformation) AsyncDelegator = 1 << 13, // __asyncDelegator (used by ES2017 async generator yield* transformation) AsyncValues = 1 << 14, // __asyncValues (used by ES2017 for..await..of transformation) + ExportStar = 1 << 15, // __exportStar (used by CommonJS/AMD/UMD module transformation) // Helpers included by ES2015 for..of ForOfIncludes = Values, @@ -4107,7 +4128,7 @@ namespace ts { SpreadIncludes = Read | Spread, FirstEmitHelper = Extends, - LastEmitHelper = AsyncValues + LastEmitHelper = ExportStar } export const enum EmitHint { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e99fe9627aa..c8827801e5e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1459,7 +1459,7 @@ namespace ts { return node && firstOrUndefined(getJSDocTags(node, kind)); } - export function getJSDocs(node: Node): (JSDoc | JSDocTag)[] { + export function getJSDocs(node: Node): (JSDoc | JSDocTag)[] { if (isJSDocTypedefTag(node)) { return [node.parent]; } @@ -1557,6 +1557,12 @@ namespace ts { p.name.kind === SyntaxKind.Identifier && p.name.text === name); } + export function getTypeParameterFromJsDoc(node: TypeParameterDeclaration & { parent: JSDocTemplateTag }): TypeParameterDeclaration | undefined { + const name = node.name.text; + const { typeParameters } = (node.parent.parent.parent as ts.SignatureDeclaration | ts.InterfaceDeclaration | ts.ClassDeclaration); + return find(typeParameters, p => p.name.text === name); + } + export function getJSDocType(node: Node): JSDocType { let tag: JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag; if (!tag && node.kind === SyntaxKind.Parameter) { @@ -1573,10 +1579,19 @@ namespace ts { return getFirstJSDocTag(node, SyntaxKind.JSDocAugmentsTag) as JSDocAugmentsTag; } + export function getJSDocClassTag(node: Node): JSDocClassTag { + return getFirstJSDocTag(node, SyntaxKind.JSDocClassTag) as JSDocClassTag; + } + export function getJSDocReturnTag(node: Node): JSDocReturnTag { return getFirstJSDocTag(node, SyntaxKind.JSDocReturnTag) as JSDocReturnTag; } + export function getJSDocReturnType(node: Node): JSDocType { + const returnTag = getJSDocReturnTag(node); + return returnTag && returnTag.typeExpression && returnTag.typeExpression.type; + } + export function getJSDocTemplateTag(node: Node): JSDocTemplateTag { return getFirstJSDocTag(node, SyntaxKind.JSDocTemplateTag) as JSDocTemplateTag; } @@ -1623,7 +1638,7 @@ namespace ts { return unaryOperator === SyntaxKind.PlusPlusToken || unaryOperator === SyntaxKind.MinusMinusToken ? AssignmentKind.Compound : AssignmentKind.None; case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: - return (parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None; + return (parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None; case SyntaxKind.ParenthesizedExpression: case SyntaxKind.ArrayLiteralExpression: case SyntaxKind.SpreadElement: @@ -2485,7 +2500,7 @@ namespace ts { const path = outputDir ? getSourceFilePathInNewDir(sourceFile, host, outputDir) : sourceFile.fileName; - return removeFileExtension(path) + ".d.ts"; + return removeFileExtension(path) + Extension.Dts; } export interface EmitFileNames { @@ -2554,14 +2569,19 @@ namespace ts { }); } - /** Get the type annotaion for the value parameter. */ - export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode { + function getSetAccessorValueParameter(accessor: SetAccessorDeclaration): ParameterDeclaration | undefined { if (accessor && accessor.parameters.length > 0) { const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]); - return accessor.parameters[hasThis ? 1 : 0].type; + return accessor.parameters[hasThis ? 1 : 0]; } } + /** Get the type annotation for the value parameter. */ + export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode { + const parameter = getSetAccessorValueParameter(accessor); + return parameter && parameter.type; + } + export function getThisParameter(signature: SignatureDeclaration): ParameterDeclaration | undefined { if (signature.parameters.length) { const thisParameter = signature.parameters[0]; @@ -2640,6 +2660,55 @@ namespace ts { }; } + /** + * Gets the effective type annotation of a variable, parameter, or property. If the node was + * parsed in a JavaScript file, gets the type annotation from JSDoc. + */ + export function getEffectiveTypeAnnotationNode(node: VariableLikeDeclaration): TypeNode { + if (node.type) { + return node.type; + } + if (node.flags & NodeFlags.JavaScriptFile) { + return getJSDocType(node); + } + } + + /** + * Gets the effective return type annotation of a signature. If the node was parsed in a + * JavaScript file, gets the return type annotation from JSDoc. + */ + export function getEffectiveReturnTypeNode(node: SignatureDeclaration): TypeNode { + if (node.type) { + return node.type; + } + if (node.flags & NodeFlags.JavaScriptFile) { + return getJSDocReturnType(node); + } + } + + /** + * Gets the effective type parameters. If the node was parsed in a + * JavaScript file, gets the type parameters from the `@template` tag from JSDoc. + */ + export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): TypeParameterDeclaration[] { + if (node.typeParameters) { + return node.typeParameters; + } + if (node.flags & NodeFlags.JavaScriptFile) { + const templateTag = getJSDocTemplateTag(node); + return templateTag && templateTag.typeParameters; + } + } + + /** + * Gets the effective type annotation of the value parameter of a set accessor. If the node + * was parsed in a JavaScript file, gets the type annotation from JSDoc. + */ + export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration): TypeNode { + const parameter = getSetAccessorValueParameter(node); + return parameter && getEffectiveTypeAnnotationNode(parameter); + } + export function emitNewLineBeforeLeadingComments(lineMap: number[], writer: EmitTextWriter, node: TextRange, leadingComments: CommentRange[]) { emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments); } @@ -3986,7 +4055,7 @@ namespace ts { // Signature elements - export function isTypeParameter(node: Node): node is TypeParameterDeclaration { + export function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration { return node.kind === SyntaxKind.TypeParameter; } @@ -4619,6 +4688,16 @@ namespace ts { // All node tests in the following list should *not* reference parent pointers so that // they may be used with transformations. namespace ts { + /* @internal */ + export function isNode(node: Node) { + return isNodeKind(node.kind); + } + + /* @internal */ + export function isNodeKind(kind: SyntaxKind) { + return kind >= SyntaxKind.FirstNode; + } + /** * True if node is of some token syntax kind. * For example, this is true for an IfKeyword but not for an IfStatement. @@ -5040,6 +5119,11 @@ namespace ts { return false; } + /* @internal */ + export function isForInOrOfStatement(node: Node): node is ForInOrOfStatement { + return node.kind === SyntaxKind.ForInStatement || node.kind === SyntaxKind.ForOfStatement; + } + // Element /* @internal */ @@ -5168,6 +5252,10 @@ namespace ts { /* @internal */ export function isDeclaration(node: Node): node is NamedDeclaration { + if (node.kind === SyntaxKind.TypeParameter) { + return node.parent.kind !== SyntaxKind.JSDocTemplateTag || isInJavaScriptFile(node); + } + return isDeclarationKind(node.kind); } @@ -5257,6 +5345,11 @@ namespace ts { return node.kind >= SyntaxKind.FirstJSDocNode && node.kind <= SyntaxKind.LastJSDocNode; } + /** True if node is of a kind that may contain comment text. */ + export function isJSDocCommentContainingNode(node: Node): boolean { + return node.kind === SyntaxKind.JSDocComment || isJSDocTag(node); + } + // TODO: determine what this does before making it public. /* @internal */ export function isJSDocTag(node: Node): boolean { diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index fc3b9c784cc..391fa88c79d 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -275,7 +275,7 @@ namespace ts { case SyntaxKind.MethodSignature: return updateMethodSignature(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), visitNode((node).type, visitor, isTypeNode), visitNode((node).name, visitor, isPropertyName), @@ -288,7 +288,7 @@ namespace ts { visitNode((node).asteriskToken, tokenVisitor, isToken), visitNode((node).name, visitor, isPropertyName), visitNode((node).questionToken, tokenVisitor, isToken), - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); @@ -319,13 +319,13 @@ namespace ts { case SyntaxKind.CallSignature: return updateCallSignature(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.ConstructSignature: return updateConstructSignature(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), visitNode((node).type, visitor, isTypeNode)); @@ -350,13 +350,13 @@ namespace ts { case SyntaxKind.FunctionType: return updateFunctionTypeNode(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.ConstructorType: return updateConstructorTypeNode(node, - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), visitNode((node).type, visitor, isTypeNode)); @@ -400,7 +400,7 @@ namespace ts { case SyntaxKind.MappedType: return updateMappedTypeNode((node), visitNode((node).readonlyToken, tokenVisitor, isToken), - visitNode((node).typeParameter, visitor, isTypeParameter), + visitNode((node).typeParameter, visitor, isTypeParameterDeclaration), visitNode((node).questionToken, tokenVisitor, isToken), visitNode((node).type, visitor, isTypeNode)); @@ -476,7 +476,7 @@ namespace ts { nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).asteriskToken, tokenVisitor, isToken), visitNode((node).name, visitor, isIdentifier), - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); @@ -484,7 +484,7 @@ namespace ts { case SyntaxKind.ArrowFunction: return updateArrowFunction(node, nodesVisitor((node).modifiers, visitor, isModifier), - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); @@ -543,7 +543,7 @@ namespace ts { return updateClassExpression(node, nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).heritageClauses, visitor, isHeritageClause), nodesVisitor((node).members, visitor, isClassElement)); @@ -676,7 +676,7 @@ namespace ts { nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).asteriskToken, tokenVisitor, isToken), visitNode((node).name, visitor, isIdentifier), - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitParameterList((node).parameters, visitor, context, nodesVisitor), visitNode((node).type, visitor, isTypeNode), visitFunctionBody((node).body, visitor, context)); @@ -686,7 +686,7 @@ namespace ts { nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).heritageClauses, visitor, isHeritageClause), nodesVisitor((node).members, visitor, isClassElement)); @@ -695,7 +695,7 @@ namespace ts { nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).heritageClauses, visitor, isHeritageClause), nodesVisitor((node).members, visitor, isTypeElement)); @@ -704,7 +704,7 @@ namespace ts { nodesVisitor((node).decorators, visitor, isDecorator), nodesVisitor((node).modifiers, visitor, isModifier), visitNode((node).name, visitor, isIdentifier), - nodesVisitor((node).typeParameters, visitor, isTypeParameter), + nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), visitNode((node).type, visitor, isTypeNode)); case SyntaxKind.EnumDeclaration: @@ -1198,9 +1198,9 @@ namespace ts { case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: - result = reduceNode((node).initializer, cbNode, result); - result = reduceNode((node).expression, cbNode, result); - result = reduceNode((node).statement, cbNode, result); + result = reduceNode((node).initializer, cbNode, result); + result = reduceNode((node).expression, cbNode, result); + result = reduceNode((node).statement, cbNode, result); break; case SyntaxKind.ReturnStatement: @@ -1517,35 +1517,7 @@ namespace ts { } export namespace Debug { - if (isDebugging) { - // Add additional properties in debug mode to assist with debugging. - Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, { - "__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } } - }); - - Object.defineProperties(objectAllocator.getTypeConstructor().prototype, { - "__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } }, - "__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((this).objectFlags) : ""; } }, - "__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } }, - }); - - for (const ctor of [objectAllocator.getNodeConstructor(), objectAllocator.getIdentifierConstructor(), objectAllocator.getTokenConstructor(), objectAllocator.getSourceFileConstructor()]) { - if (!ctor.prototype.hasOwnProperty("__debugKind")) { - Object.defineProperties(ctor.prototype, { - "__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } }, - "__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } }, - "__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } }, - "__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } }, - "__debugGetText": { value(this: Node, includeTrivia?: boolean) { - if (nodeIsSynthesized(this)) return ""; - const parseNode = getParseTreeNode(this); - const sourceFile = parseNode && getSourceFileOfNode(parseNode); - return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; - } } - }); - } - } - } + let isDebugInfoEnabled = false; export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal) ? (node: Node, message?: string): void => fail( @@ -1592,5 +1564,51 @@ namespace ts { () => `Node ${formatSyntaxKind(node.kind)} was unexpected'.`, assertMissingNode) : noop; + + /** + * Injects debug information into frequently used types. + */ + export function enableDebugInfo() { + if (isDebugInfoEnabled) return; + + // Add additional properties in debug mode to assist with debugging. + Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, { + "__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } } + }); + + Object.defineProperties(objectAllocator.getTypeConstructor().prototype, { + "__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } }, + "__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((this).objectFlags) : ""; } }, + "__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } }, + }); + + const nodeConstructors = [ + objectAllocator.getNodeConstructor(), + objectAllocator.getIdentifierConstructor(), + objectAllocator.getTokenConstructor(), + objectAllocator.getSourceFileConstructor() + ]; + + for (const ctor of nodeConstructors) { + if (!ctor.prototype.hasOwnProperty("__debugKind")) { + Object.defineProperties(ctor.prototype, { + "__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } }, + "__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } }, + "__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } }, + "__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } }, + "__debugGetText": { + value(this: Node, includeTrivia?: boolean) { + if (nodeIsSynthesized(this)) return ""; + const parseNode = getParseTreeNode(this); + const sourceFile = parseNode && getSourceFileOfNode(parseNode); + return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; + } + } + }); + } + } + + isDebugInfoEnabled = true; + } } } diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 9d697f8ffe7..170a23e34f2 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -93,7 +93,7 @@ class CompilerBaselineRunner extends RunnerBase { } lastUnit = units[units.length - 1]; - hasNonDtsFiles = ts.forEach(units, unit => !ts.fileExtensionIs(unit.name, ".d.ts")); + hasNonDtsFiles = ts.forEach(units, unit => !ts.fileExtensionIs(unit.name, ts.Extension.Dts)); // We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test) // If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references, // otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another. diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 07aacf3c8a7..7fdbef74ad7 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -536,11 +536,16 @@ namespace FourSlash { Harness.IO.log("Unexpected error(s) found. Error list is:"); } - for (const { start, length, messageText } of errors) { - Harness.IO.log(" minChar: " + start + - ", limChar: " + (start + length) + + for (const { start, length, messageText, file } of errors) { + Harness.IO.log(" from: " + showPosition(file, start) + + ", to: " + showPosition(file, start + length) + ", message: " + ts.flattenDiagnosticMessageText(messageText, Harness.IO.newLine()) + "\n"); } + + function showPosition(file: ts.SourceFile, pos: number) { + const { line, character } = ts.getLineAndCharacterOfPosition(file, pos); + return `${line}:${character}`; + } } public verifyNoErrors() { @@ -809,8 +814,8 @@ namespace FourSlash { function filterByTextOrDocumentation(entry: ts.CompletionEntry) { const details = that.getCompletionEntryDetails(entry.name); - const documentation = ts.displayPartsToString(details.documentation); - const text = ts.displayPartsToString(details.displayParts); + const documentation = details && ts.displayPartsToString(details.documentation); + const text = details && ts.displayPartsToString(details.displayParts); // If any of the expected values are undefined, assume that users don't // care about them. @@ -847,6 +852,9 @@ namespace FourSlash { if (expectedKind) { error += "Expected kind: " + expectedKind + " to equal: " + filterCompletions[0].kind + "."; } + else { + error += "kind: " + filterCompletions[0].kind + "."; + } if (replacementSpan) { const spanText = filterCompletions[0].replacementSpan ? stringify(filterCompletions[0].replacementSpan) : undefined; error += "Expected replacement span: " + stringify(replacementSpan) + " to equal: " + spanText + "."; @@ -1036,21 +1044,27 @@ namespace FourSlash { fail(`Expected ${expected}, got ${actual}`); } - for (const key in actual) if (ts.hasProperty(actual as any, key)) { - const ak = actual[key], ek = expected[key]; - if (typeof ak === "object" && typeof ek === "object") { - recur(ak, ek, path ? path + "." + key : key); - } - else if (ak !== ek) { - fail(`Expected '${key}' to be '${ek}', got '${ak}'`); + for (const key in actual) { + if (ts.hasProperty(actual as any, key)) { + const ak = actual[key], ek = expected[key]; + if (typeof ak === "object" && typeof ek === "object") { + recur(ak, ek, path ? path + "." + key : key); + } + else if (ak !== ek) { + fail(`Expected '${key}' to be '${ek}', got '${ak}'`); + } } } - for (const key in expected) if (ts.hasProperty(expected as any, key)) { - if (!ts.hasProperty(actual as any, key)) { - fail(`${msgPrefix}Missing property '${key}'`); + + for (const key in expected) { + if (ts.hasProperty(expected as any, key)) { + if (!ts.hasProperty(actual as any, key)) { + fail(`${msgPrefix}Missing property '${key}'`); + } } } }; + if (fullActual === undefined || fullExpected === undefined) { if (fullActual === fullExpected) { return; @@ -1132,15 +1146,17 @@ namespace FourSlash { } public verifyQuickInfos(namesAndTexts: { [name: string]: string | [string, string] }) { - for (const name in namesAndTexts) if (ts.hasProperty(namesAndTexts, name)) { - const text = namesAndTexts[name]; - if (ts.isArray(text)) { - assert(text.length === 2); - const [expectedText, expectedDocumentation] = text; - this.verifyQuickInfoAt(name, expectedText, expectedDocumentation); - } - else { - this.verifyQuickInfoAt(name, text); + for (const name in namesAndTexts) { + if (ts.hasProperty(namesAndTexts, name)) { + const text = namesAndTexts[name]; + if (ts.isArray(text)) { + assert(text.length === 2); + const [expectedText, expectedDocumentation] = text; + this.verifyQuickInfoAt(name, expectedText, expectedDocumentation); + } + else { + this.verifyQuickInfoAt(name, text); + } } } } @@ -1149,7 +1165,6 @@ namespace FourSlash { if (expectedDocumentation === "") { throw new Error("Use 'undefined' instead"); } - const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); const actualQuickInfoText = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.displayParts) : ""; const actualQuickInfoDocumentation = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.documentation) : ""; @@ -1452,7 +1467,7 @@ namespace FourSlash { let baselineFile = this.testData.globalOptions[metadataOptionNames.baselineFile]; if (!baselineFile) { baselineFile = this.activeFile.fileName.replace(this.basePath + "/breakpointValidation", "bpSpan"); - baselineFile = baselineFile.replace(".ts", ".baseline"); + baselineFile = baselineFile.replace(ts.Extension.Ts, ".baseline"); } Harness.Baseline.runBaseline( @@ -1522,7 +1537,7 @@ namespace FourSlash { public baselineQuickInfo() { let baselineFile = this.testData.globalOptions[metadataOptionNames.baselineFile]; if (!baselineFile) { - baselineFile = ts.getBaseFileName(this.activeFile.fileName).replace(".ts", ".baseline"); + baselineFile = ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline"); } Harness.Baseline.runBaseline( @@ -1595,16 +1610,19 @@ namespace FourSlash { } private printMembersOrCompletions(info: ts.CompletionInfo) { + if (info === undefined) { return "No completion info."; } + const { entries } = info; + function pad(s: string, length: number) { return s + new Array(length - s.length + 1).join(" "); } function max(arr: T[], selector: (x: T) => number): number { return arr.reduce((prev, x) => Math.max(prev, selector(x)), 0); } - const longestNameLength = max(info.entries, m => m.name.length); - const longestKindLength = max(info.entries, m => m.kind.length); - info.entries.sort((m, n) => m.sortText > n.sortText ? 1 : m.sortText < n.sortText ? -1 : m.name > n.name ? 1 : m.name < n.name ? -1 : 0); - const membersString = info.entries.map(m => `${pad(m.name, longestNameLength)} ${pad(m.kind, longestKindLength)} ${m.kindModifiers}`).join("\n"); + const longestNameLength = max(entries, m => m.name.length); + const longestKindLength = max(entries, m => m.kind.length); + entries.sort((m, n) => m.sortText > n.sortText ? 1 : m.sortText < n.sortText ? -1 : m.name > n.name ? 1 : m.name < n.name ? -1 : 0); + const membersString = entries.map(m => `${pad(m.name, longestNameLength)} ${pad(m.kind, longestKindLength)} ${m.kindModifiers}`).join("\n"); Harness.IO.log(membersString); } @@ -2156,7 +2174,7 @@ namespace FourSlash { Harness.IO.log(this.spanInfoToString(this.getNameOrDottedNameSpan(pos), "**")); } - private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[]) { + private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[], sourceFileText: string) { if (actual.length !== expected.length) { this.raiseError("verifyClassifications failed - expected total classifications to be " + expected.length + ", but was " + actual.length + @@ -2196,9 +2214,11 @@ namespace FourSlash { }); function jsonMismatchString() { + const showActual = actual.map(({ classificationType, textSpan }) => + ({ classificationType, text: sourceFileText.slice(textSpan.start, textSpan.start + textSpan.length) })); return Harness.IO.newLine() + "expected: '" + Harness.IO.newLine() + stringify(expected) + "'" + Harness.IO.newLine() + - "actual: '" + Harness.IO.newLine() + stringify(actual) + "'"; + "actual: '" + Harness.IO.newLine() + stringify(showActual) + "'"; } } @@ -2221,14 +2241,14 @@ namespace FourSlash { const actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); - this.verifyClassifications(expected, actual); + this.verifyClassifications(expected, actual, this.activeFile.content); } public verifySyntacticClassifications(expected: { classificationType: string; text: string }[]) { const actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); - this.verifyClassifications(expected, actual); + this.verifyClassifications(expected, actual, this.activeFile.content); } public verifyOutliningSpans(spans: TextSpan[]) { @@ -2659,6 +2679,13 @@ namespace FourSlash { this.rangesByText().forEach(ranges => this.verifyRangesAreDocumentHighlights(ranges)); } + public verifyDocumentHighlightsOf(startRange: Range, ranges: Range[]) { + ts.Debug.assert(ts.contains(ranges, startRange)); + const fileNames = unique(ranges, range => range.fileName); + this.goToRangeStart(startRange); + this.verifyDocumentHighlights(ranges, fileNames); + } + public verifyRangesAreDocumentHighlights(ranges?: Range[]) { ranges = ranges || this.getRanges(); const fileNames = unique(ranges, range => range.fileName); @@ -2741,6 +2768,7 @@ namespace FourSlash { markerName: string, expectedContent: string, refactorNameToApply: string, + actionName: string, formattingOptions?: ts.FormatCodeSettings) { formattingOptions = formattingOptions || this.formatCodeSettings; @@ -2753,9 +2781,11 @@ namespace FourSlash { this.raiseError(`The expected refactor: ${refactorNameToApply} is not available at the marker location.`); } - const codeActions = this.languageService.getRefactorCodeActions(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply); + const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply, actionName); - this.applyCodeActions(codeActions); + for (const edit of editInfo.edits) { + this.applyEdits(edit.fileName, edit.textChanges); + } const actualContent = this.getFileContent(this.activeFile.fileName); if (this.normalizeNewlines(actualContent) !== this.normalizeNewlines(expectedContent)) { @@ -3798,8 +3828,8 @@ namespace FourSlashInterface { this.state.verifyRangeAfterCodeFix(expectedText, includeWhiteSpace, errorCode, index); } - public fileAfterApplyingRefactorAtMarker(markerName: string, expectedContent: string, refactorNameToApply: string, formattingOptions?: ts.FormatCodeSettings): void { - this.state.verifyFileAfterApplyingRefactorAtMarker(markerName, expectedContent, refactorNameToApply, formattingOptions); + public fileAfterApplyingRefactorAtMarker(markerName: string, expectedContent: string, refactorNameToApply: string, actionName: string, formattingOptions?: ts.FormatCodeSettings): void { + this.state.verifyFileAfterApplyingRefactorAtMarker(markerName, expectedContent, refactorNameToApply, actionName, formattingOptions); } public rangeIs(expectedText: string, includeWhiteSpace?: boolean): void { @@ -3870,6 +3900,10 @@ namespace FourSlashInterface { this.state.verifyRangesWithSameTextAreDocumentHighlights(); } + public documentHighlightsOf(startRange: FourSlash.Range, ranges: FourSlash.Range[]) { + this.state.verifyDocumentHighlightsOf(startRange, ranges); + } + public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) { this.state.verifyCompletionEntryDetails(entryName, text, documentation, kind, tags); } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 53731592a46..d73290f961f 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -259,8 +259,9 @@ namespace Utils { return true; } else if ((f & v) > 0) { - if (result.length) + if (result.length) { result += " | "; + } result += flags[v]; return false; } @@ -1052,7 +1053,7 @@ namespace Harness { ]; let optionsIndex: ts.Map; - function getCommandLineOption(name: string): ts.CommandLineOption { + function getCommandLineOption(name: string): ts.CommandLineOption | undefined { if (!optionsIndex) { optionsIndex = ts.createMap(); const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations); @@ -1248,7 +1249,7 @@ namespace Harness { sourceFileName = outFile; } - const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts"; + const dTsFileName = ts.removeFileExtension(sourceFileName) + ts.Extension.Dts; return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined); } @@ -1464,7 +1465,7 @@ namespace Harness { // When calling this function from rwc-runner, the baselinePath will have no extension. // As rwc test- file is stored in json which ".json" will get stripped off. // When calling this function from compiler-runner, the baselinePath will then has either ".ts" or ".tsx" extension - const outputFileName = ts.endsWith(baselinePath, ".ts") || ts.endsWith(baselinePath, ".tsx") ? + const outputFileName = ts.endsWith(baselinePath, ts.Extension.Ts) || ts.endsWith(baselinePath, ts.Extension.Tsx) ? baselinePath.replace(/\.tsx?/, fullExtension) : baselinePath.concat(fullExtension); Harness.Baseline.runBaseline(outputFileName, () => fullBaseLine, opts); } @@ -1562,7 +1563,7 @@ namespace Harness { } // check js output - Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js"), () => { + Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ts.Extension.Js), () => { let tsCode = ""; const tsSources = otherFiles.concat(toBeCompiled); if (tsSources.length > 1) { @@ -1650,22 +1651,22 @@ namespace Harness { } export function isTS(fileName: string) { - return ts.endsWith(fileName, ".ts"); + return ts.endsWith(fileName, ts.Extension.Ts); } export function isTSX(fileName: string) { - return ts.endsWith(fileName, ".tsx"); + return ts.endsWith(fileName, ts.Extension.Tsx); } export function isDTS(fileName: string) { - return ts.endsWith(fileName, ".d.ts"); + return ts.endsWith(fileName, ts.Extension.Dts); } export function isJS(fileName: string) { - return ts.endsWith(fileName, ".js"); + return ts.endsWith(fileName, ts.Extension.Js); } export function isJSX(fileName: string) { - return ts.endsWith(fileName, ".jsx"); + return ts.endsWith(fileName, ts.Extension.Jsx); } export function isJSMap(fileName: string) { @@ -1979,7 +1980,7 @@ namespace Harness { export function isDefaultLibraryFile(filePath: string): boolean { // We need to make sure that the filePath is prefixed with "lib." not just containing "lib." and end with ".d.ts" const fileName = ts.getBaseFileName(ts.normalizeSlashes(filePath)); - return ts.startsWith(fileName, "lib.") && ts.endsWith(fileName, ".d.ts"); + return ts.startsWith(fileName, "lib.") && ts.endsWith(fileName, ts.Extension.Dts); } export function isBuiltFile(filePath: string): boolean { diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 7aefb0f3a1f..774c43556ca 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -492,7 +492,7 @@ namespace Harness.LanguageService { getCodeFixDiagnostics(): ts.Diagnostic[] { throw new Error("Not supported on the shim."); } - getRefactorCodeActions(): ts.CodeAction[] { + getEditsForRefactor(): ts.RefactorEditInfo { throw new Error("Not supported on the shim."); } getApplicableRefactors(): ts.ApplicableRefactorInfo[] { @@ -731,7 +731,7 @@ namespace Harness.LanguageService { } createHash(s: string) { - return s; + return mockHash(s); } require(_initialDir: string, _moduleName: string): ts.server.RequireResult { @@ -856,4 +856,8 @@ namespace Harness.LanguageService { getClassifier(): ts.Classifier { throw new Error("getClassifier is not available using the server interface."); } getPreProcessedFileInfo(): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); } } + + export function mockHash(s: string): string { + return `hash-${s}`; + } } diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index dc4b9685dd5..b02164034fa 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -319,8 +319,8 @@ class ProjectRunner extends RunnerBase { // we need to instead create files that can live in the project reference folder // but make sure extension of these files matches with the fileName the compiler asked to write diskRelativeName = "diskFile" + nonSubfolderDiskFiles + - (Harness.Compiler.isDTS(fileName) ? ".d.ts" : - Harness.Compiler.isJS(fileName) ? ".js" : ".js.map"); + (Harness.Compiler.isDTS(fileName) ? ts.Extension.Dts : + Harness.Compiler.isJS(fileName) ? ts.Extension.Js : ".js.map"); nonSubfolderDiskFiles++; } @@ -380,14 +380,14 @@ class ProjectRunner extends RunnerBase { emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName); } - const outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts"; + const outputDtsFileName = emitOutputFilePathWithoutExtension + ts.Extension.Dts; const file = findOutputDtsFile(outputDtsFileName); if (file) { allInputFiles.unshift(file); } } else { - const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts"; + const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ts.Extension.Dts; const outputDtsFile = findOutputDtsFile(outputDtsFileName); if (!ts.contains(allInputFiles, outputDtsFile)) { allInputFiles.unshift(outputDtsFile); diff --git a/src/harness/runner.ts b/src/harness/runner.ts index 3ad6269e52f..4653e440f11 100644 --- a/src/harness/runner.ts +++ b/src/harness/runner.ts @@ -222,6 +222,10 @@ if (taskConfigsFolder) { } } else { + if (ts.Debug.isDebugging) { + ts.Debug.enableDebugInfo(); + } + runTests(runners); } if (!runUnitTests) { diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index f2c92d1260f..eee6473f77f 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -81,7 +81,7 @@ "../services/codefixes/fixConstructorForDerivedNeedSuperCall.ts", "../services/codefixes/helpers.ts", "../services/codefixes/importFixes.ts", - "../services/codefixes/unusedIdentifierFixes.ts", + "../services/codefixes/fixUnusedIdentifier.ts", "../services/codefixes/disableJsDiagnostics.ts", "harness.ts", diff --git a/src/harness/unittests/cachingInServerLSHost.ts b/src/harness/unittests/cachingInServerLSHost.ts index f5b54063df7..46d9aa462ce 100644 --- a/src/harness/unittests/cachingInServerLSHost.ts +++ b/src/harness/unittests/cachingInServerLSHost.ts @@ -47,7 +47,7 @@ namespace ts { clearTimeout, setImmediate: typeof setImmediate !== "undefined" ? setImmediate : action => setTimeout(action, 0), clearImmediate: typeof clearImmediate !== "undefined" ? clearImmediate : clearTimeout, - createHash: s => s + createHash: Harness.LanguageService.mockHash, }; } diff --git a/src/harness/unittests/compileOnSave.ts b/src/harness/unittests/compileOnSave.ts index eaab86b4ebc..7e262a1b257 100644 --- a/src/harness/unittests/compileOnSave.ts +++ b/src/harness/unittests/compileOnSave.ts @@ -513,7 +513,7 @@ namespace ts.projectSystem { const lines = ["var x = 1;", "var y = 2;"]; const path = "/a/app"; const f = { - path: path + ".ts", + path: path + ts.Extension.Ts, content: lines.join(newLine) }; const host = createServerHost([f], { newLine }); @@ -530,7 +530,7 @@ namespace ts.projectSystem { command: "compileOnSaveEmitFile", arguments: { file: f.path } }); - const emitOutput = host.readFile(path + ".js"); + const emitOutput = host.readFile(path + ts.Extension.Js); assert.equal(emitOutput, f.content + newLine, "content of emit output should be identical with the input + newline"); } }); diff --git a/src/harness/unittests/moduleResolution.ts b/src/harness/unittests/moduleResolution.ts index a4220f50321..87ec4ea8149 100644 --- a/src/harness/unittests/moduleResolution.ts +++ b/src/harness/unittests/moduleResolution.ts @@ -5,7 +5,7 @@ namespace ts { if (!expected === !actual) { if (expected) { assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`); - assert.isTrue(expected.extension === actual.extension, `'ext': expected '${Extension[expected.extension]}' to be equal to '${Extension[actual.extension]}'`); + assert.isTrue(expected.extension === actual.extension, `'ext': expected '${expected.extension}' to be equal to '${actual.extension}'`); assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`); } return true; diff --git a/src/harness/unittests/printer.ts b/src/harness/unittests/printer.ts index 4bdafe04ba1..23e301f3669 100644 --- a/src/harness/unittests/printer.ts +++ b/src/harness/unittests/printer.ts @@ -81,63 +81,136 @@ namespace ts { describe("printNode", () => { const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly"); - let sourceFile: SourceFile; - before(() => sourceFile = createSourceFile("source.ts", "", ScriptTarget.ES2015)); - // tslint:disable boolean-trivia - const syntheticNode = createClassDeclaration( - undefined, - undefined, - /*name*/ createIdentifier("C"), - undefined, - undefined, - createNodeArray([ - createProperty( - undefined, + printsCorrectly("class", {}, printer => printer.printNode( + EmitHint.Unspecified, + createClassDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*name*/ createIdentifier("C"), + /*typeParameters*/ undefined, + /*heritageClauses*/ undefined, + [createProperty( + /*decorators*/ undefined, createNodeArray([createToken(SyntaxKind.PublicKeyword)]), createIdentifier("prop"), - undefined, - undefined, - undefined - ) - ]) - ); + /*questionToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined + )] + ), + createSourceFile("source.ts", "", ScriptTarget.ES2015) + )); + + printsCorrectly("namespaceExportDeclaration", {}, printer => printer.printNode( + EmitHint.Unspecified, + createNamespaceExportDeclaration("B"), + createSourceFile("source.ts", "", ScriptTarget.ES2015) + )); // https://github.com/Microsoft/TypeScript/issues/15971 - const classWithOptionalMethodAndProperty = createClassDeclaration( - undefined, - /* modifiers */ createNodeArray([createToken(SyntaxKind.DeclareKeyword)]), - /* name */ createIdentifier("X"), - undefined, - undefined, - createNodeArray([ - createMethod( - undefined, - undefined, - undefined, - /* name */ createIdentifier("method"), - /* questionToken */ createToken(SyntaxKind.QuestionToken), - undefined, - undefined, - /* type */ createKeywordTypeNode(SyntaxKind.VoidKeyword), - undefined + printsCorrectly("classWithOptionalMethodAndProperty", {}, printer => printer.printNode( + EmitHint.Unspecified, + createClassDeclaration( + /*decorators*/ undefined, + /*modifiers*/ [createToken(SyntaxKind.DeclareKeyword)], + /*name*/ createIdentifier("X"), + /*typeParameters*/ undefined, + /*heritageClauses*/ undefined, + [ + createMethod( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*asteriskToken*/ undefined, + /*name*/ createIdentifier("method"), + /*questionToken*/ createToken(SyntaxKind.QuestionToken), + /*typeParameters*/ undefined, + [], + /*type*/ createKeywordTypeNode(SyntaxKind.VoidKeyword), + /*body*/ undefined + ), + createProperty( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*name*/ createIdentifier("property"), + /*questionToken*/ createToken(SyntaxKind.QuestionToken), + /*type*/ createKeywordTypeNode(SyntaxKind.StringKeyword), + /*initializer*/ undefined + ), + ] + ), + createSourceFile("source.ts", "", ScriptTarget.ES2015) + )); + + // https://github.com/Microsoft/TypeScript/issues/15651 + printsCorrectly("functionTypes", {}, printer => printer.printNode( + EmitHint.Unspecified, + createTupleTypeNode([ + createFunctionTypeNode( + /*typeArguments*/ undefined, + [createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + createIdentifier("args") + )], + createKeywordTypeNode(SyntaxKind.AnyKeyword) ), - createProperty( - undefined, - undefined, - /* name */ createIdentifier("property"), - /* questionToken */ createToken(SyntaxKind.QuestionToken), - /* type */ createKeywordTypeNode(SyntaxKind.StringKeyword), - undefined + createFunctionTypeNode( + [createTypeParameterDeclaration("T")], + [createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + createIdentifier("args") + )], + createKeywordTypeNode(SyntaxKind.AnyKeyword) ), - ]) - ); - - // tslint:enable boolean-trivia - printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile)); - - printsCorrectly("namespaceExportDeclaration", {}, printer => printer.printNode(EmitHint.Unspecified, createNamespaceExportDeclaration("B"), sourceFile)); - - printsCorrectly("classWithOptionalMethodAndProperty", {}, printer => printer.printNode(EmitHint.Unspecified, classWithOptionalMethodAndProperty, sourceFile)); + createFunctionTypeNode( + /*typeArguments*/ undefined, + [createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + createToken(SyntaxKind.DotDotDotToken), + createIdentifier("args") + )], + createKeywordTypeNode(SyntaxKind.AnyKeyword) + ), + createFunctionTypeNode( + /*typeArguments*/ undefined, + [createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + createIdentifier("args"), + createToken(SyntaxKind.QuestionToken) + )], + createKeywordTypeNode(SyntaxKind.AnyKeyword) + ), + createFunctionTypeNode( + /*typeArguments*/ undefined, + [createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + createIdentifier("args"), + /*questionToken*/ undefined, + createKeywordTypeNode(SyntaxKind.AnyKeyword) + )], + createKeywordTypeNode(SyntaxKind.AnyKeyword) + ), + createFunctionTypeNode( + /*typeArguments*/ undefined, + [createParameter( + /*decorators*/ undefined, + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + createObjectBindingPattern([]) + )], + createKeywordTypeNode(SyntaxKind.AnyKeyword) + ), + ]), + createSourceFile("source.ts", "", ScriptTarget.ES2015) + )); }); }); } diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index db33d87f087..067cd351ec7 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -25,7 +25,7 @@ namespace ts.server { clearTimeout: noop, setImmediate: () => 0, clearImmediate: noop, - createHash: s => s + createHash: Harness.LanguageService.mockHash, }; const mockLogger: Logger = { @@ -240,8 +240,8 @@ namespace ts.server { CommandNames.GetCodeFixesFull, CommandNames.GetSupportedCodeFixes, CommandNames.GetApplicableRefactors, - CommandNames.GetRefactorCodeActions, - CommandNames.GetRefactorCodeActionsFull, + CommandNames.GetEditsForRefactor, + CommandNames.GetEditsForRefactorFull, ]; it("should not throw when commands are executed with invalid arguments", () => { diff --git a/src/harness/unittests/telemetry.ts b/src/harness/unittests/telemetry.ts index cb7afa595bf..abc8dd24360 100644 --- a/src/harness/unittests/telemetry.ts +++ b/src/harness/unittests/telemetry.ts @@ -9,6 +9,7 @@ namespace ts.projectSystem { et.service.openClientFile(file.path); assert.equal(et.getEvents().length, 0); }); + it("only sends an event once", () => { const file = makeFile("/a.ts"); const tsconfig = makeFile("/tsconfig.json", {}); @@ -46,12 +47,13 @@ namespace ts.projectSystem { const et = new EventTracker([file1]); const compilerOptions: ts.server.protocol.CompilerOptions = { strict: true }; - const projectFileName = "foo.csproj"; + const projectFileName = "/hunter2/foo.csproj"; open(); // TODO: Apparently compilerOptions is mutated, so have to repeat it here! et.assertProjectInfoTelemetryEvent({ + projectId: Harness.LanguageService.mockHash("/hunter2/foo.csproj"), compilerOptions: { strict: true }, compileOnSave: true, // These properties can't be present for an external project, so they are undefined instead of false. @@ -193,6 +195,7 @@ namespace ts.projectSystem { const et = new EventTracker([jsconfig, file]); et.service.openClientFile(file.path); et.assertProjectInfoTelemetryEvent({ + projectId: Harness.LanguageService.mockHash("/jsconfig.json"), fileStats: fileStats({ js: 1 }), compilerOptions: autoJsCompilerOptions, typeAcquisition: { @@ -212,6 +215,7 @@ namespace ts.projectSystem { et.service.openClientFile(file.path); et.getEvent(server.ProjectLanguageServiceStateEvent, /*mayBeMore*/ true); et.assertProjectInfoTelemetryEvent({ + projectId: Harness.LanguageService.mockHash("/jsconfig.json"), fileStats: fileStats({ js: 1 }), compilerOptions: autoJsCompilerOptions, configFileName: "jsconfig.json", @@ -246,7 +250,26 @@ namespace ts.projectSystem { } assertProjectInfoTelemetryEvent(partial: Partial): void { - assert.deepEqual(this.getEvent(ts.server.ProjectInfoTelemetryEvent), makePayload(partial)); + assert.deepEqual(this.getEvent(ts.server.ProjectInfoTelemetryEvent), { + projectId: Harness.LanguageService.mockHash("/tsconfig.json"), + fileStats: fileStats({ ts: 1 }), + compilerOptions: {}, + extends: false, + files: false, + include: false, + exclude: false, + compileOnSave: false, + typeAcquisition: { + enable: false, + exclude: false, + include: false, + }, + configFileName: "tsconfig.json", + projectType: "configured", + languageServiceEnabled: true, + version: ts.version, + ...partial, + }); } getEvent(eventName: T["eventName"], mayBeMore = false): T["data"] { @@ -258,28 +281,6 @@ namespace ts.projectSystem { } } - function makePayload(partial: Partial): server.ProjectInfoTelemetryEventData { - return { - fileStats: fileStats({ ts: 1 }), - compilerOptions: {}, - extends: false, - files: false, - include: false, - exclude: false, - compileOnSave: false, - typeAcquisition: { - enable: false, - exclude: false, - include: false, - }, - configFileName: "tsconfig.json", - projectType: "configured", - languageServiceEnabled: true, - version: ts.version, - ...partial - }; - } - function makeFile(path: string, content: {} = ""): projectSystem.FileOrFolder { return { path, content: typeof content === "string" ? "" : JSON.stringify(content) }; } diff --git a/src/harness/unittests/transpile.ts b/src/harness/unittests/transpile.ts index 20552ab9c2e..e0c96797827 100644 --- a/src/harness/unittests/transpile.ts +++ b/src/harness/unittests/transpile.ts @@ -36,7 +36,7 @@ namespace ts { transpileOptions.reportDiagnostics = true; - justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? ".tsx" : ".ts"); + justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? Extension.Tsx : Extension.Ts); toBeCompiled = [{ unitName: transpileOptions.fileName, content: input @@ -88,7 +88,7 @@ namespace ts { } it("Correct output for " + justName, () => { - Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".js"), () => { + Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ts.Extension.Js), () => { if (transpileResult.outputText) { return transpileResult.outputText; } diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 8108d11888a..3284c131bae 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -472,7 +472,7 @@ namespace ts.projectSystem { } createHash(s: string): string { - return s; + return Harness.LanguageService.mockHash(s); } triggerDirectoryWatcherCallback(directoryName: string, fileName: string): void { @@ -2204,7 +2204,8 @@ namespace ts.projectSystem { projectService.closeClientFile(f1.path); projectService.checkNumberOfProjects({}); - for (const f of [f2, f3]) { + for (const f of [f1, f2, f3]) { + // There shouldnt be any script info as we closed the file that resulted in creation of it const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path)); assert.equal(scriptInfo.containingProjects.length, 0, `expect 0 containing projects for '${f.path}'`); } diff --git a/src/lib/dom.generated.d.ts b/src/lib/dom.generated.d.ts index 3aa813c0a8a..da81bba5d78 100644 --- a/src/lib/dom.generated.d.ts +++ b/src/lib/dom.generated.d.ts @@ -3483,7 +3483,7 @@ interface DragEvent extends MouseEvent { declare var DragEvent: { prototype: DragEvent; - new(): DragEvent; + new(type: "drag" | "dragend" | "dragenter" | "dragexit" | "dragleave" | "dragover" | "dragstart" | "drop", dragEventInit?: { dataTransfer?: DataTransfer }): DragEvent; }; interface DynamicsCompressorNode extends AudioNode { @@ -8224,6 +8224,7 @@ interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorConte readonly serviceWorker: ServiceWorkerContainer; readonly webdriver: boolean; readonly hardwareConcurrency: number; + readonly languages: string[]; getGamepads(): Gamepad[]; javaEnabled(): boolean; msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void; diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 6decc78558a..48a97fa6658 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1635,7 +1635,7 @@ interface Int8Array { * @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. */ - map(callbackfn: (this: void, value: number, index: number, array: Int8Array) => number, thisArg: any): Int8Array; + map(callbackfn: (this: void, value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -1902,7 +1902,7 @@ interface Uint8Array { * @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. */ - map(callbackfn: (this: void, value: number, index: number, array: Uint8Array) => number, thisArg: any): Uint8Array; + map(callbackfn: (this: void, value: number, index: number, array: Uint8Array) => number, thisArg?: any): Uint8Array; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -2169,7 +2169,7 @@ interface Uint8ClampedArray { * @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. */ - map(callbackfn: (this: void, value: number, index: number, array: Uint8ClampedArray) => number, thisArg: any): Uint8ClampedArray; + map(callbackfn: (this: void, value: number, index: number, array: Uint8ClampedArray) => number, thisArg?: any): Uint8ClampedArray; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -2434,7 +2434,7 @@ interface Int16Array { * @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. */ - map(callbackfn: (this: void, value: number, index: number, array: Int16Array) => number, thisArg: any): Int16Array; + map(callbackfn: (this: void, value: number, index: number, array: Int16Array) => number, thisArg?: any): Int16Array; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -2702,7 +2702,7 @@ interface Uint16Array { * @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. */ - map(callbackfn: (this: void, value: number, index: number, array: Uint16Array) => number, thisArg: any): Uint16Array; + map(callbackfn: (this: void, value: number, index: number, array: Uint16Array) => number, thisArg?: any): Uint16Array; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -3235,7 +3235,7 @@ interface Uint32Array { * @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. */ - map(callbackfn: (this: void, value: number, index: number, array: Uint32Array) => number, thisArg: any): Uint32Array; + map(callbackfn: (this: void, value: number, index: number, array: Uint32Array) => number, thisArg?: any): Uint32Array; /** * Calls the specified callback function for all the elements in an array. The return value of @@ -3502,7 +3502,7 @@ interface Float32Array { * @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. */ - map(callbackfn: (this: void, value: number, index: number, array: Float32Array) => number, thisArg: any): Float32Array; + map(callbackfn: (this: void, value: number, index: number, array: Float32Array) => number, thisArg?: any): Float32Array; /** * Calls the specified callback function for all the elements in an array. The return value of diff --git a/src/server/client.ts b/src/server/client.ts index aca52422e44..2cfe32f521a 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -719,20 +719,49 @@ namespace ts.server { return response.body; } - getRefactorCodeActions( + getEditsForRefactor( fileName: string, _formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, - refactorName: string) { + refactorName: string, + actionName: string): RefactorEditInfo { - const args = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName) as protocol.GetRefactorCodeActionsRequestArgs; - args.refactorName = refactorName; + const args = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName) as protocol.GetEditsForRefactorRequestArgs; + args.refactor = refactorName; + args.action = actionName; - const request = this.processRequest(CommandNames.GetRefactorCodeActions, args); - const response = this.processResponse(request); - const codeActions = response.body.actions; + const request = this.processRequest(CommandNames.GetEditsForRefactor, args); + const response = this.processResponse(request); - return map(codeActions, codeAction => this.convertCodeActions(codeAction, fileName)); + if (!response.body) { + return { + edits: [] + }; + } + + const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits); + + const renameFilename: string | undefined = response.body.renameFilename; + let renameLocation: number | undefined = undefined; + if (renameFilename !== undefined) { + renameLocation = this.lineOffsetToPosition(renameFilename, response.body.renameLocation); + } + + return { + edits, + renameFilename, + renameLocation + }; + } + + private convertCodeEditsToTextChanges(edits: ts.server.protocol.FileCodeEdits[]): FileTextChanges[] { + return edits.map(edit => { + const fileName = edit.fileName; + return { + fileName, + textChanges: edit.textChanges.map(t => this.convertTextChangeToCodeEdit(t, fileName)) + }; + }); } convertCodeActions(entry: protocol.CodeAction, fileName: string): CodeAction { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 8d6afe9b5a7..649b5fd5a77 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -37,6 +37,8 @@ namespace ts.server { } export interface ProjectInfoTelemetryEventData { + /** Cryptographically secure hash of project file location. */ + readonly projectId: string; /** Count of file extensions seen in the project. */ readonly fileStats: FileStats; /** @@ -563,10 +565,17 @@ namespace ts.server { } else { if (info && (!info.isScriptOpen())) { - // file has been changed which might affect the set of referenced files in projects that include - // this file and set of inferred projects - info.reloadFromFile(); - this.updateProjectGraphs(info.containingProjects); + if (info.containingProjects.length === 0) { + // Orphan script info, remove it as we can always reload it on next open + info.stopWatcher(); + this.filenameToScriptInfo.remove(info.path); + } + else { + // file has been changed which might affect the set of referenced files in projects that include + // this file and set of inferred projects + info.reloadFromFile(); + this.updateProjectGraphs(info.containingProjects); + } } } } @@ -827,10 +836,29 @@ namespace ts.server { this.assignScriptInfoToInferredProjectIfNecessary(f, /*addToListOfOpenFiles*/ false); } } + + // Cleanup script infos that arent part of any project is postponed to + // next file open so that if file from same project is opened we wont end up creating same script infos } - if (info.containingProjects.length === 0) { - // if there are not projects that include this script info - delete it - this.filenameToScriptInfo.remove(info.path); + + // If the current info is being just closed - add the watcher file to track changes + // But if file was deleted, handle that part + if (this.host.fileExists(info.fileName)) { + this.watchClosedScriptInfo(info); + } + else { + this.handleDeletedFile(info); + } + } + + private deleteOrphanScriptInfoNotInAnyProject() { + for (const path of this.filenameToScriptInfo.getKeys()) { + const info = this.filenameToScriptInfo.get(path); + if (!info.isScriptOpen() && info.containingProjects.length === 0) { + // if there are not projects that include this script info - delete it + info.stopWatcher(); + this.filenameToScriptInfo.remove(info.path); + } } } @@ -1043,6 +1071,7 @@ namespace ts.server { if (!this.eventHandler) return; const data: ProjectInfoTelemetryEventData = { + projectId: this.host.createHash(projectKey), fileStats: countEachFileTypes(project.getScriptInfos()), compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilerOptions()), typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()), @@ -1294,6 +1323,14 @@ namespace ts.server { return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName)); } + watchClosedScriptInfo(info: ScriptInfo) { + // do not watch files with mixed content - server doesn't know how to interpret it + if (!info.hasMixedContent) { + const { fileName } = info; + info.setWatcher(this.host.watchFile(fileName, _ => this.onSourceFileChanged(fileName))); + } + } + getOrCreateScriptInfoForNormalizedPath(fileName: NormalizedPath, openedByClient: boolean, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean) { let info = this.getScriptInfoForNormalizedPath(fileName); if (!info) { @@ -1309,15 +1346,13 @@ namespace ts.server { } } else { - // do not watch files with mixed content - server doesn't know how to interpret it - if (!hasMixedContent) { - info.setWatcher(this.host.watchFile(fileName, _ => this.onSourceFileChanged(fileName))); - } + this.watchClosedScriptInfo(info); } } } if (info) { if (openedByClient && !info.isScriptOpen()) { + info.stopWatcher(); info.open(fileContent); if (hasMixedContent) { info.registerFileUpdate(); @@ -1412,6 +1447,7 @@ namespace ts.server { for (const p of this.inferredProjects) { p.updateGraph(); } + this.printProjects(); } @@ -1445,6 +1481,11 @@ namespace ts.server { // at this point if file is the part of some configured/external project then this project should be created const info = this.getOrCreateScriptInfoForNormalizedPath(fileName, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent); this.assignScriptInfoToInferredProjectIfNecessary(info, /*addToListOfOpenFiles*/ true); + // Delete the orphan files here because there might be orphan script infos (which are not part of project) + // when some file/s were closed which resulted in project removal. + // It was then postponed to cleanup these script infos so that they can be reused if + // the file from that old project is reopened because of opening file from here. + this.deleteOrphanScriptInfoNotInAnyProject(); this.printProjects(); return { configFileName, configFileErrors }; } diff --git a/src/server/lsHost.ts b/src/server/lsHost.ts index ec655c545ea..79429737240 100644 --- a/src/server/lsHost.ts +++ b/src/server/lsHost.ts @@ -11,11 +11,11 @@ namespace ts.server { private filesWithChangedSetOfUnresolvedImports: Path[]; - private readonly resolveModuleName: typeof resolveModuleName; + private resolveModuleName: typeof resolveModuleName; readonly trace: (s: string) => void; readonly realpath?: (path: string) => string; - constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) { + constructor(private readonly host: ServerHost, private project: Project, private readonly cancellationToken: HostCancellationToken) { this.cancellationToken = new ThrottledCancellationToken(cancellationToken, project.projectService.throttleWaitMilliseconds); this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); @@ -47,6 +47,11 @@ namespace ts.server { } } + dispose() { + this.project = undefined; + this.resolveModuleName = undefined; + } + public startRecordingFilesWithChangedResolutions() { this.filesWithChangedSetOfUnresolvedImports = []; } @@ -238,4 +243,4 @@ namespace ts.server { this.compilationSettings = opt; } } -} \ No newline at end of file +} diff --git a/src/server/project.ts b/src/server/project.ts index 943517aa67f..ac040a77ace 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -25,7 +25,7 @@ namespace ts.server { result.jsx += 1; break; case ScriptKind.TS: - fileExtensionIs(info.fileName, ".d.ts") + fileExtensionIs(info.fileName, Extension.Dts) ? result.dts += 1 : result.ts += 1; break; @@ -116,7 +116,7 @@ namespace ts.server { public languageServiceEnabled = true; - protected readonly lsHost: LSHost; + protected lsHost: LSHost; builder: Builder; /** @@ -304,9 +304,15 @@ namespace ts.server { this.rootFiles = undefined; this.rootFilesMap = undefined; this.program = undefined; + this.builder = undefined; + this.cachedUnresolvedImportsPerFile = undefined; + this.projectErrors = undefined; + this.lsHost.dispose(); + this.lsHost = undefined; // signal language service to release source files acquired from document registry this.languageService.dispose(); + this.languageService = undefined; } getCompilerOptions() { @@ -1080,6 +1086,7 @@ namespace ts.server { if (this.projectFileWatcher) { this.projectFileWatcher.close(); + this.projectFileWatcher = undefined; } if (this.typeRootsWatchers) { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index c7d9e2c3a09..916d9c51a14 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -98,8 +98,11 @@ namespace ts.server.protocol { GetSupportedCodeFixes = "getSupportedCodeFixes", GetApplicableRefactors = "getApplicableRefactors", - GetRefactorCodeActions = "getRefactorCodeActions", - GetRefactorCodeActionsFull = "getRefactorCodeActions-full", + GetEditsForRefactor = "getEditsForRefactor", + /* @internal */ + GetEditsForRefactorFull = "getEditsForRefactor-full", + + // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`. } /** @@ -401,52 +404,98 @@ namespace ts.server.protocol { export type FileLocationOrRangeRequestArgs = FileLocationRequestArgs | FileRangeRequestArgs; + /** + * Request refactorings at a given position or selection area. + */ export interface GetApplicableRefactorsRequest extends Request { command: CommandTypes.GetApplicableRefactors; arguments: GetApplicableRefactorsRequestArgs; } - export type GetApplicableRefactorsRequestArgs = FileLocationOrRangeRequestArgs; - export interface ApplicableRefactorInfo { - name: string; - description: string; - } - + /** + * Response is a list of available refactorings. + * Each refactoring exposes one or more "Actions"; a user selects one action to invoke a refactoring + */ export interface GetApplicableRefactorsResponse extends Response { body?: ApplicableRefactorInfo[]; } - export interface GetRefactorCodeActionsRequest extends Request { - command: CommandTypes.GetRefactorCodeActions; - arguments: GetRefactorCodeActionsRequestArgs; + /** + * A set of one or more available refactoring actions, grouped under a parent refactoring. + */ + export interface ApplicableRefactorInfo { + /** + * The programmatic name of the refactoring + */ + name: string; + /** + * A description of this refactoring category to show to the user. + * If the refactoring gets inlined (see below), this text will not be visible. + */ + description: string; + /** + * Inlineable refactorings can have their actions hoisted out to the top level + * of a context menu. Non-inlineanable refactorings should always be shown inside + * their parent grouping. + * + * If not specified, this value is assumed to be 'true' + */ + inlineable?: boolean; + + actions: RefactorActionInfo[]; } - export type GetRefactorCodeActionsRequestArgs = FileLocationOrRangeRequestArgs & { - /* The kind of the applicable refactor */ - refactorName: string; + /** + * Represents a single refactoring action - for example, the "Extract Method..." refactor might + * offer several actions, each corresponding to a surround class or closure to extract into. + */ + export type RefactorActionInfo = { + /** + * The programmatic name of the refactoring action + */ + name: string; + + /** + * A description of this refactoring action to show to the user. + * If the parent refactoring is inlined away, this will be the only text shown, + * so this description should make sense by itself if the parent is inlineable=true + */ + description: string; }; - export type RefactorCodeActions = { - actions: protocol.CodeAction[]; - renameLocation?: number - }; - - /* @internal */ - export type RefactorCodeActionsFull = { - actions: ts.CodeAction[]; - renameLocation?: number - }; - - export interface GetRefactorCodeActionsResponse extends Response { - body: RefactorCodeActions; + export interface GetEditsForRefactorRequest extends Request { + command: CommandTypes.GetEditsForRefactor; + arguments: GetEditsForRefactorRequestArgs; } - /* @internal */ - export interface GetRefactorCodeActionsFullResponse extends Response { - body: RefactorCodeActionsFull; + /** + * Request the edits that a particular refactoring action produces. + * Callers must specify the name of the refactor and the name of the action. + */ + export type GetEditsForRefactorRequestArgs = FileLocationOrRangeRequestArgs & { + /* The 'name' property from the refactoring that offered this action */ + refactor: string; + /* The 'name' property from the refactoring action */ + action: string; + }; + + + export interface GetEditsForRefactorResponse extends Response { + body?: RefactorEditInfo; } + export type RefactorEditInfo = { + edits: FileCodeEdits[]; + + /** + * An optional location where the editor should start a rename operation once + * the refactoring edits have been applied + */ + renameLocation?: Location; + renameFilename?: string; + }; + /** * Request for the available codefixes at a specific position. */ diff --git a/src/server/server.ts b/src/server/server.ts index 7e1ee683c8c..5f2b7054755 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -35,6 +35,7 @@ namespace ts.server { } = require("os"); function getGlobalTypingsCacheLocation() { + const versionMajorMinor = ts.version.match(/\d+\.\d+/)[0]; switch (process.platform) { case "win32": { const basePath = process.env.LOCALAPPDATA || @@ -43,7 +44,7 @@ namespace ts.server { process.env.USERPROFILE || (process.env.HOMEDRIVE && process.env.HOMEPATH && normalizeSlashes(process.env.HOMEDRIVE + process.env.HOMEPATH)) || os.tmpdir(); - return combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript"); + return combinePaths(combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript"), versionMajorMinor); } case "openbsd": case "freebsd": @@ -51,7 +52,7 @@ namespace ts.server { case "linux": case "android": { const cacheLocation = getNonWindowsCacheLocation(process.platform === "darwin"); - return combinePaths(cacheLocation, "typescript"); + return combinePaths(combinePaths(cacheLocation, "typescript"), versionMajorMinor); } default: Debug.fail(`unsupported platform '${process.platform}'`); @@ -526,7 +527,7 @@ namespace ts.server { watchedFile.callback(watchedFile.fileName); } else if (watchedFile.mtime.getTime() !== stats.mtime.getTime()) { - watchedFile.mtime = getModifiedTime(watchedFile.fileName); + watchedFile.mtime = stats.mtime; watchedFile.callback(watchedFile.fileName, watchedFile.mtime.getTime() === 0); } }); diff --git a/src/server/session.ts b/src/server/session.ts index 1e66b1eadd1..3f4450e4f4d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -118,7 +118,13 @@ namespace ts.server { return true; } - export import CommandNames = protocol.CommandTypes; + // CommandNames used to be exposed before TS 2.4 as a namespace + // In TS 2.4 we switched to an enum, keep this for backward compatibility + // The var assignment ensures that even though CommandTypes are a const enum + // we want to ensure the value is maintained in the out since the file is + // built using --preseveConstEnum. + export type CommandNames = protocol.CommandTypes; + export const CommandNames = (protocol).CommandTypes; export function formatMessage(msg: T, logger: server.Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string { const verboseLogging = logger.hasLevel(LogLevel.verbose); @@ -1487,29 +1493,40 @@ namespace ts.server { return project.getLanguageService().getApplicableRefactors(file, position || textRange); } - private getRefactorCodeActions(args: protocol.GetRefactorCodeActionsRequestArgs, simplifiedResult: boolean): protocol.RefactorCodeActions | protocol.RefactorCodeActionsFull { + private getEditsForRefactor(args: protocol.GetEditsForRefactorRequestArgs, simplifiedResult: boolean): ts.RefactorEditInfo | protocol.RefactorEditInfo { const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args); const scriptInfo = project.getScriptInfoForNormalizedPath(file); const { position, textRange } = this.extractPositionAndRange(args, scriptInfo); - const result: ts.CodeAction[] = project.getLanguageService().getRefactorCodeActions( + const result = project.getLanguageService().getEditsForRefactor( file, this.projectService.getFormatCodeOptions(), position || textRange, - args.refactorName + args.refactor, + args.action ); - if (simplifiedResult) { - // Not full + if (result === undefined) { return { - actions: result.map(action => this.mapCodeAction(action, scriptInfo)) + edits: [] + }; + } + + if (simplifiedResult) { + const file = result.renameFilename; + let location: ILineInfo | undefined = undefined; + if (file !== undefined && result.renameLocation !== undefined) { + const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(file)); + location = renameScriptInfo.positionToLineOffset(result.renameLocation); + } + return { + renameLocation: location, + renameFilename: file, + edits: result.edits.map(change => this.mapTextChangesToCodeEdits(project, change)) }; } else { - // Full - return { - actions: result - }; + return result; } } @@ -1567,6 +1584,14 @@ namespace ts.server { }; } + private mapTextChangesToCodeEdits(project: Project, textChanges: FileTextChanges): protocol.FileCodeEdits { + const scriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(textChanges.fileName)); + return { + fileName: textChanges.fileName, + textChanges: textChanges.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo)) + }; + } + private convertTextChangeToCodeEdit(change: ts.TextChange, scriptInfo: ScriptInfo): protocol.CodeEdit { return { start: scriptInfo.positionToLineOffset(change.span.start), @@ -1606,18 +1631,22 @@ namespace ts.server { const normalizedFileName = toNormalizedPath(fileName); const project = this.projectService.getDefaultProjectForFile(normalizedFileName, /*refreshInferredProjects*/ true); for (const fileNameInProject of fileNamesInProject) { - if (this.getCanonicalFileName(fileNameInProject) === this.getCanonicalFileName(fileName)) + if (this.getCanonicalFileName(fileNameInProject) === this.getCanonicalFileName(fileName)) { highPriorityFiles.push(fileNameInProject); + } else { const info = this.projectService.getScriptInfo(fileNameInProject); if (!info.isScriptOpen()) { - if (fileNameInProject.indexOf(".d.ts") > 0) + if (fileNameInProject.indexOf(Extension.Dts) > 0) { veryLowPriorityFiles.push(fileNameInProject); - else + } + else { lowPriorityFiles.push(fileNameInProject); + } } - else + else { mediumPriorityFiles.push(fileNameInProject); + } } } @@ -1895,11 +1924,11 @@ namespace ts.server { [CommandNames.GetApplicableRefactors]: (request: protocol.GetApplicableRefactorsRequest) => { return this.requiredResponse(this.getApplicableRefactors(request.arguments)); }, - [CommandNames.GetRefactorCodeActions]: (request: protocol.GetRefactorCodeActionsRequest) => { - return this.requiredResponse(this.getRefactorCodeActions(request.arguments, /*simplifiedResult*/ true)); + [CommandNames.GetEditsForRefactor]: (request: protocol.GetEditsForRefactorRequest) => { + return this.requiredResponse(this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ true)); }, - [CommandNames.GetRefactorCodeActionsFull]: (request: protocol.GetRefactorCodeActionsRequest) => { - return this.requiredResponse(this.getRefactorCodeActions(request.arguments, /*simplifiedResult*/ false)); + [CommandNames.GetEditsForRefactorFull]: (request: protocol.GetEditsForRefactorRequest) => { + return this.requiredResponse(this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ false)); } }); diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 38da43bdee8..37aa8df0ca1 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -146,7 +146,7 @@ namespace ts.BreakpointResolver { case SyntaxKind.ForOfStatement: // span in initializer - return spanInInitializerOfForLike(node); + return spanInInitializerOfForLike(node); case SyntaxKind.SwitchStatement: // span on switch(...) diff --git a/src/services/classifier.ts b/src/services/classifier.ts index beeddda434e..ff33059630d 100644 --- a/src/services/classifier.ts +++ b/src/services/classifier.ts @@ -724,8 +724,8 @@ namespace ts { pushCommentRange(pos, tag.pos - pos); } - pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); - pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); + pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); // "@" + pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); // e.g. "param" pos = tag.tagName.end; @@ -814,7 +814,7 @@ namespace ts { * False will mean that node is not classified and traverse routine should recurse into node contents. */ function tryClassifyNode(node: Node): boolean { - if (isJSDocTag(node)) { + if (isJSDoc(node)) { return true; } diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/fixUnusedIdentifier.ts similarity index 63% rename from src/services/codefixes/unusedIdentifierFixes.ts rename to src/services/codefixes/fixUnusedIdentifier.ts index 5d85979fcf9..cbe2ba5b1c5 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -18,14 +18,14 @@ namespace ts.codefix { switch (token.kind) { case ts.SyntaxKind.Identifier: - return deleteIdentifier(); + return deleteIdentifierOrPrefixWithUnderscore(token); case SyntaxKind.PropertyDeclaration: case SyntaxKind.NamespaceImport: - return deleteNode(token.parent); + return [deleteNode(token.parent)]; default: - return deleteDefault(); + return [deleteDefault()]; } function deleteDefault() { @@ -40,61 +40,69 @@ namespace ts.codefix { } } - function deleteIdentifier(): CodeAction[] | undefined { - switch (token.parent.kind) { + function prefixIdentifierWithUnderscore(identifier: Identifier): CodeAction { + const startPosition = identifier.getStart(sourceFile, /*includeJsDocComment*/ false); + return { + description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Prefix_0_with_an_underscore), { 0: token.getText() }), + changes: [{ + fileName: sourceFile.path, + textChanges: [{ + span: { start: startPosition, length: 0 }, + newText: "_" + }] + }] + }; + } + + function deleteIdentifierOrPrefixWithUnderscore(identifier: Identifier): CodeAction[] | undefined { + const parent = identifier.parent; + switch (parent.kind) { case ts.SyntaxKind.VariableDeclaration: - return deleteVariableDeclaration(token.parent); + return deleteVariableDeclarationOrPrefixWithUnderscore(identifier, parent); case SyntaxKind.TypeParameter: - const typeParameters = (token.parent.parent).typeParameters; + const typeParameters = (parent.parent).typeParameters; if (typeParameters.length === 1) { const previousToken = getTokenAtPosition(sourceFile, typeParameters.pos - 1, /*includeJsDocComment*/ false); - if (!previousToken || previousToken.kind !== SyntaxKind.LessThanToken) { - return deleteRange(typeParameters); - } const nextToken = getTokenAtPosition(sourceFile, typeParameters.end, /*includeJsDocComment*/ false); - if (!nextToken || nextToken.kind !== SyntaxKind.GreaterThanToken) { - return deleteRange(typeParameters); - } - return deleteNodeRange(previousToken, nextToken); + Debug.assert(previousToken.kind === SyntaxKind.LessThanToken); + Debug.assert(nextToken.kind === SyntaxKind.GreaterThanToken); + + return [deleteNodeRange(previousToken, nextToken)]; } else { - return deleteNodeInList(token.parent); + return [deleteNodeInList(parent)]; } case ts.SyntaxKind.Parameter: - const functionDeclaration = token.parent.parent; - if (functionDeclaration.parameters.length === 1) { - return deleteNode(token.parent); - } - else { - return deleteNodeInList(token.parent); - } + const functionDeclaration = parent.parent; + return [functionDeclaration.parameters.length === 1 ? deleteNode(parent) : deleteNodeInList(parent), + prefixIdentifierWithUnderscore(identifier)]; // handle case where 'import a = A;' case SyntaxKind.ImportEqualsDeclaration: - const importEquals = getAncestor(token, SyntaxKind.ImportEqualsDeclaration); - return deleteNode(importEquals); + const importEquals = getAncestor(identifier, SyntaxKind.ImportEqualsDeclaration); + return [deleteNode(importEquals)]; case SyntaxKind.ImportSpecifier: - const namedImports = token.parent.parent; + const namedImports = parent.parent; if (namedImports.elements.length === 1) { // Only 1 import and it is unused. So the entire declaration should be removed. - const importSpec = getAncestor(token, SyntaxKind.ImportDeclaration); - return deleteNode(importSpec); + const importSpec = getAncestor(identifier, SyntaxKind.ImportDeclaration); + return [deleteNode(importSpec)]; } else { // delete import specifier - return deleteNodeInList(token.parent); + return [deleteNodeInList(parent)]; } // handle case where "import d, * as ns from './file'" // or "'import {a, b as ns} from './file'" case SyntaxKind.ImportClause: // this covers both 'import |d|' and 'import |d,| *' - const importClause = token.parent; + const importClause = parent; if (!importClause.namedBindings) { // |import d from './file'| or |import * as ns from './file'| const importDecl = getAncestor(importClause, SyntaxKind.ImportDeclaration); - return deleteNode(importDecl); + return [deleteNode(importDecl)]; } else { // import |d,| * as ns from './file' @@ -102,64 +110,62 @@ namespace ts.codefix { const nextToken = getTokenAtPosition(sourceFile, importClause.name.end, /*includeJsDocComment*/ false); if (nextToken && nextToken.kind === SyntaxKind.CommaToken) { // shift first non-whitespace position after comma to the start position of the node - return deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) }); + return [deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) })]; } else { - return deleteNode(importClause.name); + return [deleteNode(importClause.name)]; } } case SyntaxKind.NamespaceImport: - const namespaceImport = token.parent; - if (namespaceImport.name === token && !(namespaceImport.parent).name) { + const namespaceImport = parent; + if (namespaceImport.name === identifier && !(namespaceImport.parent).name) { const importDecl = getAncestor(namespaceImport, SyntaxKind.ImportDeclaration); - return deleteNode(importDecl); + return [deleteNode(importDecl)]; } else { const previousToken = getTokenAtPosition(sourceFile, namespaceImport.pos - 1, /*includeJsDocComment*/ false); if (previousToken && previousToken.kind === SyntaxKind.CommaToken) { const startPosition = textChanges.getAdjustedStartPosition(sourceFile, previousToken, {}, textChanges.Position.FullStart); - return deleteRange({ pos: startPosition, end: namespaceImport.end }); + return [deleteRange({ pos: startPosition, end: namespaceImport.end })]; } - return deleteRange(namespaceImport); + return [deleteRange(namespaceImport)]; } default: - return deleteDefault(); + return [deleteDefault()]; } } // token.parent is a variableDeclaration - function deleteVariableDeclaration(varDecl: ts.VariableDeclaration): CodeAction[] | undefined { + function deleteVariableDeclarationOrPrefixWithUnderscore(identifier: Identifier, varDecl: ts.VariableDeclaration): CodeAction[] | undefined { switch (varDecl.parent.parent.kind) { case SyntaxKind.ForStatement: const forStatement = varDecl.parent.parent; const forInitializer = forStatement.initializer; - if (forInitializer.declarations.length === 1) { - return deleteNode(forInitializer); - } - else { - return deleteNodeInList(varDecl); - } + return [forInitializer.declarations.length === 1 ? deleteNode(forInitializer) : deleteNodeInList(varDecl)]; case SyntaxKind.ForOfStatement: const forOfStatement = varDecl.parent.parent; Debug.assert(forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList); const forOfInitializer = forOfStatement.initializer; - return replaceNode(forOfInitializer.declarations[0], createObjectLiteral()); + return [ + replaceNode(forOfInitializer.declarations[0], createObjectLiteral()), + prefixIdentifierWithUnderscore(identifier) + ]; case SyntaxKind.ForInStatement: // There is no valid fix in the case of: // for .. in - return undefined; + return [prefixIdentifierWithUnderscore(identifier)]; default: const variableStatement = varDecl.parent.parent; if (variableStatement.declarationList.declarations.length === 1) { - return deleteNode(variableStatement); + return [deleteNode(variableStatement)]; } else { - return deleteNodeInList(varDecl); + return [deleteNodeInList(varDecl)]; } } } @@ -184,11 +190,11 @@ namespace ts.codefix { return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).replaceNode(sourceFile, n, newNode)); } - function makeChange(changeTracker: textChanges.ChangeTracker) { - return [{ + function makeChange(changeTracker: textChanges.ChangeTracker): CodeAction { + return { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }), changes: changeTracker.getChanges() - }]; + }; } } }); diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index c2e2509a28e..c38820231b0 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -6,7 +6,7 @@ /// /// /// -/// +/// /// /// /// diff --git a/src/services/completions.ts b/src/services/completions.ts index 71fe4ce1c78..6f1f3fae1ea 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -18,7 +18,7 @@ namespace ts.Completions { return undefined; } - const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords } = completionData; + const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, request, hasFilteredClassMemberKeywords } = completionData; if (sourceFile.languageVariant === LanguageVariant.JSX && location && location.parent && location.parent.kind === SyntaxKind.JsxClosingElement) { @@ -36,14 +36,15 @@ namespace ts.Completions { }]}; } - if (requestJsDocTagName) { - // If the current position is a jsDoc tag name, only tag names should be provided for completion - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagNameCompletions() }; - } - - if (requestJsDocTag) { - // If the current position is a jsDoc tag, only tags should be provided for completion - return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagCompletions() }; + if (request) { + const entries = request.kind === "JsDocTagName" + // If the current position is a jsDoc tag name, only tag names should be provided for completion + ? JsDoc.getJSDocTagNameCompletions() + : request.kind === "JsDocTag" + // If the current position is a jsDoc tag, only tags should be provided for completion + ? JsDoc.getJSDocTagCompletions() + : JsDoc.getJSDocParameterNameCompletions(request.tag); + return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries }; } const entries: CompletionEntry[] = []; @@ -66,7 +67,7 @@ namespace ts.Completions { addRange(entries, classMemberKeywordCompletions); } // Add keywords if this is not a member completion list - else if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) { + else if (!isMemberCompletion) { addRange(entries, keywordCompletions); } @@ -347,16 +348,27 @@ namespace ts.Completions { return undefined; } - function getCompletionData(typeChecker: TypeChecker, log: (message: string) => void, sourceFile: SourceFile, position: number) { + interface CompletionData { + symbols: Symbol[]; + isGlobalCompletion: boolean; + isMemberCompletion: boolean; + isNewIdentifierLocation: boolean; + location: Node; + isRightOfDot: boolean; + request?: Request; + hasFilteredClassMemberKeywords: boolean; + } + type Request = { kind: "JsDocTagName" } | { kind: "JsDocTag" } | { kind: "JsDocParameterName", tag: JSDocParameterTag }; + + function getCompletionData(typeChecker: TypeChecker, log: (message: string) => void, sourceFile: SourceFile, position: number): CompletionData { const isJavaScriptFile = isSourceFileJavaScript(sourceFile); - // JsDoc tag-name is just the name of the JSDoc tagname (exclude "@") - let requestJsDocTagName = false; - // JsDoc tag includes both "@" and tag-name - let requestJsDocTag = false; + let request: Request | undefined; let start = timestamp(); - const currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853 + let currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853 + // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.) + log("getCompletionData: Get current token: " + (timestamp() - start)); start = timestamp(); @@ -364,12 +376,13 @@ namespace ts.Completions { const insideComment = isInComment(sourceFile, position, currentToken); log("getCompletionData: Is inside comment: " + (timestamp() - start)); + let insideJsDocTagTypeExpression = false; if (insideComment) { if (hasDocComment(sourceFile, position)) { - // The current position is next to the '@' sign, when no tag name being provided yet. - // Provide a full list of tag names if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) { - requestJsDocTagName = true; + // The current position is next to the '@' sign, when no tag name being provided yet. + // Provide a full list of tag names + request = { kind: "JsDocTagName" }; } else { // When completion is requested without "@", we will have check to make sure that @@ -389,37 +402,40 @@ namespace ts.Completions { // * |c| // */ const lineStart = getLineStartPositionForPosition(position, sourceFile); - requestJsDocTag = !(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/)); + if (!(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/))) { + request = { kind: "JsDocTag" }; + } } } // Completion should work inside certain JsDoc tags. For example: // /** @type {number | string} */ // Completion should work in the brackets - let insideJsDocTagExpression = false; - const tag = getJsDocTagAtPosition(sourceFile, position); + const tag = getJsDocTagAtPosition(currentToken, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { - requestJsDocTagName = true; + request = { kind: "JsDocTagName" }; } - - switch (tag.kind) { - case SyntaxKind.JSDocTypeTag: - case SyntaxKind.JSDocParameterTag: - case SyntaxKind.JSDocReturnTag: - const tagWithExpression = tag; - if (tagWithExpression.typeExpression) { - insideJsDocTagExpression = tagWithExpression.typeExpression.pos < position && position < tagWithExpression.typeExpression.end; - } - break; + if (isTagWithTypeExpression(tag) && tag.typeExpression) { + currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ true); + if (!currentToken || + (!isDeclarationName(currentToken) && + (currentToken.parent.kind !== SyntaxKind.JSDocPropertyTag || + (currentToken.parent).name !== currentToken))) { + // Use as type location if inside tag's type expression + insideJsDocTagTypeExpression = isCurrentlyEditingNode(tag.typeExpression); + } + } + if (isJSDocParameterTag(tag) && (nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) { + request = { kind: "JsDocParameterName", tag }; } } - if (requestJsDocTagName || requestJsDocTag) { - return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords: false }; + if (request) { + return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, request, hasFilteredClassMemberKeywords: false }; } - if (!insideJsDocTagExpression) { + if (!insideJsDocTagTypeExpression) { // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal // comment or the plain text part of a jsDoc comment, so no completion should be available log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment."); @@ -428,7 +444,7 @@ namespace ts.Completions { } start = timestamp(); - const previousToken = findPrecedingToken(position, sourceFile); + const previousToken = findPrecedingToken(position, sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression); log("getCompletionData: Get previous token 1: " + (timestamp() - start)); // The decision to provide completion depends on the contextToken, which is determined through the previousToken. @@ -439,7 +455,7 @@ namespace ts.Completions { // Skip this partial identifier and adjust the contextToken to the token that precedes it. if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) { const start = timestamp(); - contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile); + contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression); log("getCompletionData: Get previous token 2: " + (timestamp() - start)); } @@ -451,7 +467,7 @@ namespace ts.Completions { let isRightOfOpenTag = false; let isStartingCloseTag = false; - let location = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853 + let location = getTouchingPropertyName(sourceFile, position, insideJsDocTagTypeExpression); // TODO: GH#15853 if (contextToken) { // Bail out if this is a known invalid completion location if (isCompletionListBlocker(contextToken)) { @@ -553,7 +569,21 @@ namespace ts.Completions { log("getCompletionData: Semantic work: " + (timestamp() - semanticStart)); - return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag, hasFilteredClassMemberKeywords }; + return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, hasFilteredClassMemberKeywords }; + + type JSDocTagWithTypeExpression = JSDocAugmentsTag | JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag; + + function isTagWithTypeExpression(tag: JSDocTag): tag is JSDocTagWithTypeExpression { + switch (tag.kind) { + case SyntaxKind.JSDocAugmentsTag: + case SyntaxKind.JSDocParameterTag: + case SyntaxKind.JSDocPropertyTag: + case SyntaxKind.JSDocReturnTag: + case SyntaxKind.JSDocTypeTag: + case SyntaxKind.JSDocTypedefTag: + return true; + } + } function getTypeScriptMemberSymbols(): void { // Right of dot member completion list @@ -561,6 +591,9 @@ namespace ts.Completions { isMemberCompletion = true; isNewIdentifierLocation = false; + // Since this is qualified name check its a type node location + const isTypeLocation = isPartOfTypeNode(node.parent) || insideJsDocTagTypeExpression; + const isRhsOfImportDeclaration = isInRightSideOfInternalImportEqualsDeclaration(node); if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.PropertyAccessExpression) { let symbol = typeChecker.getSymbolAtLocation(node); @@ -572,16 +605,24 @@ namespace ts.Completions { if (symbol && symbol.flags & SymbolFlags.HasExports) { // Extract module or enum members const exportedSymbols = typeChecker.getExportsOfModule(symbol); + const isValidValueAccess = (symbol: Symbol) => typeChecker.isValidPropertyAccess((node.parent), symbol.name); + const isValidTypeAccess = (symbol: Symbol) => symbolCanbeReferencedAtTypeLocation(symbol); + const isValidAccess = isRhsOfImportDeclaration ? + // Any kind is allowed when dotting off namespace in internal import equals declaration + (symbol: Symbol) => isValidTypeAccess(symbol) || isValidValueAccess(symbol) : + isTypeLocation ? isValidTypeAccess : isValidValueAccess; forEach(exportedSymbols, symbol => { - if (typeChecker.isValidPropertyAccess((node.parent), symbol.name)) { + if (isValidAccess(symbol)) { symbols.push(symbol); } }); } } - const type = typeChecker.getTypeAtLocation(node); - addTypeProperties(type); + if (!isTypeLocation) { + const type = typeChecker.getTypeAtLocation(node); + addTypeProperties(type); + } } function addTypeProperties(type: Type) { @@ -689,13 +730,87 @@ namespace ts.Completions { isStatement(scopeNode); } - /// TODO filter meaning based on the current context const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; - symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); + symbols = filterGlobalCompletion(typeChecker.getSymbolsInScope(scopeNode, symbolMeanings)); return true; } + function filterGlobalCompletion(symbols: Symbol[]) { + return filter(symbols, symbol => { + if (!isSourceFile(location)) { + // export = /**/ here we want to get all meanings, so any symbol is ok + if (isExportAssignment(location.parent)) { + return true; + } + + // This is an alias, follow what it aliases + if (symbol && symbol.flags & SymbolFlags.Alias) { + symbol = typeChecker.getAliasedSymbol(symbol); + } + + // import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace) + if (isInRightSideOfInternalImportEqualsDeclaration(location)) { + return !!(symbol.flags & SymbolFlags.Namespace); + } + + if (insideJsDocTagTypeExpression || + (!isContextTokenValueLocation(contextToken) && + (isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken)))) { + // Its a type, but you can reach it by namespace.type as well + return symbolCanbeReferencedAtTypeLocation(symbol); + } + } + + // expressions are value space (which includes the value namespaces) + return !!(symbol.flags & SymbolFlags.Value); + }); + } + + function isContextTokenValueLocation(contextToken: Node) { + return contextToken && + contextToken.kind === SyntaxKind.TypeOfKeyword && + contextToken.parent.kind === SyntaxKind.TypeQuery; + } + + function isContextTokenTypeLocation(contextToken: Node) { + if (contextToken) { + const parentKind = contextToken.parent.kind; + switch (contextToken.kind) { + case SyntaxKind.ColonToken: + return parentKind === SyntaxKind.PropertyDeclaration || + parentKind === SyntaxKind.PropertySignature || + parentKind === SyntaxKind.Parameter || + parentKind === SyntaxKind.VariableDeclaration || + isFunctionLikeKind(parentKind); + + case SyntaxKind.EqualsToken: + return parentKind === SyntaxKind.TypeAliasDeclaration; + + case SyntaxKind.AsKeyword: + return parentKind === SyntaxKind.AsExpression; + } + } + } + + function symbolCanbeReferencedAtTypeLocation(symbol: Symbol): boolean { + // This is an alias, follow what it aliases + if (symbol && symbol.flags & SymbolFlags.Alias) { + symbol = typeChecker.getAliasedSymbol(symbol); + } + + if (symbol.flags & SymbolFlags.Type) { + return true; + } + + if (symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule)) { + const exportedSymbols = typeChecker.getExportsOfModule(symbol); + // If the exported symbols contains type, + // symbol can be referenced at locations where type is allowed + return forEach(exportedSymbols, symbolCanbeReferencedAtTypeLocation); + } + } + /** * Finds the first node that "embraces" the position, so that one may * accurately aggregate locals from the closest containing scope. @@ -827,7 +942,7 @@ namespace ts.Completions { * * @returns true if 'symbols' was successfully populated; false otherwise. */ - function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | BindingPattern): boolean { + function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | ObjectBindingPattern): boolean { // We're looking up possible property names from contextual/inferred/declared type. isMemberCompletion = true; @@ -843,41 +958,36 @@ namespace ts.Completions { typeMembers = typeChecker.getAllPossiblePropertiesOfType(typeForObject); existingMembers = (objectLikeContainer).properties; } - else if (objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern) { + else { + Debug.assert(objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern); // We are *only* completing on properties from the type being destructured. isNewIdentifierLocation = false; const rootDeclaration = getRootDeclaration(objectLikeContainer.parent); - if (isVariableLike(rootDeclaration)) { - // We don't want to complete using the type acquired by the shape - // of the binding pattern; we are only interested in types acquired - // through type declaration or inference. - // Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed - - // type of parameter will flow in from the contextual type of the function - let canGetType = !!(rootDeclaration.initializer || rootDeclaration.type); - if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) { - if (isExpression(rootDeclaration.parent)) { - canGetType = !!typeChecker.getContextualType(rootDeclaration.parent); - } - else if (rootDeclaration.parent.kind === SyntaxKind.MethodDeclaration || rootDeclaration.parent.kind === SyntaxKind.SetAccessor) { - canGetType = isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent); - } + if (!isVariableLike(rootDeclaration)) throw Debug.fail("Root declaration is not variable-like."); + + // We don't want to complete using the type acquired by the shape + // of the binding pattern; we are only interested in types acquired + // through type declaration or inference. + // Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed - + // type of parameter will flow in from the contextual type of the function + let canGetType = rootDeclaration.initializer || rootDeclaration.type || rootDeclaration.parent.parent.kind === SyntaxKind.ForOfStatement; + if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) { + if (isExpression(rootDeclaration.parent)) { + canGetType = !!typeChecker.getContextualType(rootDeclaration.parent); } - if (canGetType) { - const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); - if (!typeForObject) return false; - // In a binding pattern, get only known properties. Everywhere else we will get all possible properties. - typeMembers = typeChecker.getPropertiesOfType(typeForObject); - existingMembers = (objectLikeContainer).elements; + else if (rootDeclaration.parent.kind === SyntaxKind.MethodDeclaration || rootDeclaration.parent.kind === SyntaxKind.SetAccessor) { + canGetType = isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent); } } - else { - Debug.fail("Root declaration is not variable-like."); + if (canGetType) { + const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); + if (!typeForObject) return false; + // In a binding pattern, get only known properties. Everywhere else we will get all possible properties. + typeMembers = typeChecker.getPropertiesOfType(typeForObject); + existingMembers = (objectLikeContainer).elements; } } - else { - Debug.fail("Expected object literal or binding pattern, got " + objectLikeContainer.kind); - } if (typeMembers && typeMembers.length > 0) { // Add filtered items to the completion list @@ -986,14 +1096,14 @@ namespace ts.Completions { * Returns the immediate owning object literal or binding pattern of a context token, * on the condition that one exists and that the context implies completion should be given. */ - function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | BindingPattern { + function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | ObjectBindingPattern { if (contextToken) { switch (contextToken.kind) { case SyntaxKind.OpenBraceToken: // const x = { | case SyntaxKind.CommaToken: // const x = { a: 0, | const parent = contextToken.parent; - if (parent && (parent.kind === SyntaxKind.ObjectLiteralExpression || parent.kind === SyntaxKind.ObjectBindingPattern)) { - return parent; + if (isObjectLiteralExpression(parent) || isObjectBindingPattern(parent)) { + return parent; } break; } @@ -1128,21 +1238,6 @@ namespace ts.Completions { return undefined; } - function isFunction(kind: SyntaxKind): boolean { - if (!isFunctionLikeKind(kind)) { - return false; - } - - switch (kind) { - case SyntaxKind.Constructor: - case SyntaxKind.ConstructorType: - case SyntaxKind.FunctionType: - return false; - default: - return true; - } - } - /** * @returns true if we are certain that the currently edited location must define a new location; false otherwise. */ @@ -1154,7 +1249,7 @@ namespace ts.Completions { containingNodeKind === SyntaxKind.VariableDeclarationList || containingNodeKind === SyntaxKind.VariableStatement || containingNodeKind === SyntaxKind.EnumDeclaration || // enum a { foo, | - isFunction(containingNodeKind) || + isFunctionLikeButNotConstructor(containingNodeKind) || containingNodeKind === SyntaxKind.ClassDeclaration || // class A end) continue; + for (let i = tags.length - 1; i >= 0; i--) { + const tag = tags[i]; + if (position >= tag.pos) { + return tag; + } + } + } + } + + function getJsDocHavingNode(node: Node): Node { + if (!isToken(node)) return node; + + switch (node.kind) { + case SyntaxKind.VarKeyword: + case SyntaxKind.LetKeyword: + case SyntaxKind.ConstKeyword: + // if the current token is var, let or const, skip the VariableDeclarationList + return node.parent.parent; + default: + return node.parent; + } + } } diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 36b72ecfa78..7ea8c519646 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -1,17 +1,23 @@ /* @internal */ namespace ts.DocumentHighlights { - export function getDocumentHighlights(program: Program, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] { + export function getDocumentHighlights(program: Program, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] | undefined { const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true); - return node && (getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile)); + if (!node) return undefined; + + if (isJsxOpeningElement(node.parent) && node.parent.tagName === node || isJsxClosingElement(node.parent)) { + // For a JSX element, just highlight the matching tag, not all references. + const { openingElement, closingElement } = node.parent.parent; + const highlightSpans = [openingElement, closingElement].map(({ tagName }) => getHighlightSpanForNode(tagName, sourceFile)); + return [{ fileName: sourceFile.fileName, highlightSpans }]; + } + + return getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); } function getHighlightSpanForNode(node: Node, sourceFile: SourceFile): HighlightSpan { - const start = node.getStart(sourceFile); - const end = node.getEnd(); - return { fileName: sourceFile.fileName, - textSpan: createTextSpanFromBounds(start, end), + textSpan: createTextSpanFromNode(node, sourceFile), kind: HighlightSpanKind.none }; } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index c1a7408fae7..192895cde59 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -307,7 +307,7 @@ namespace ts.FindAllReferences.Core { case SyntaxKind.ExportDeclaration: return true; case SyntaxKind.CallExpression: - return isRequireCall(node.parent as CallExpression, /*checkArgumentIsStringLiteral*/ false); + return isRequireCall(node.parent as CallExpression, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent as CallExpression); default: return false; } @@ -496,11 +496,10 @@ namespace ts.FindAllReferences.Core { const { text = stripQuotes(getDeclaredName(this.checker, symbol, location)), allSearchSymbols = undefined } = searchOptions; const escapedText = escapeIdentifier(text); const parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker); - return { location, symbol, comingFrom, text, escapedText, parents, includes }; - - function includes(referenceSymbol: Symbol): boolean { - return allSearchSymbols ? contains(allSearchSymbols, referenceSymbol) : referenceSymbol === symbol; - } + return { + location, symbol, comingFrom, text, escapedText, parents, + includes: referenceSymbol => allSearchSymbols ? contains(allSearchSymbols, referenceSymbol) : referenceSymbol === symbol, + }; } private readonly symbolIdToReferences: Entry[][] = []; @@ -679,9 +678,7 @@ namespace ts.FindAllReferences.Core { return parent ? scope.getSourceFile() : scope; } - function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile, fullStart = false): number[] { - const start = fullStart ? container.getFullStart() : container.getStart(sourceFile); - const end = container.getEnd(); + function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile): number[] { const positions: number[] = []; /// TODO: Cache symbol existence for files to save text search @@ -696,10 +693,10 @@ namespace ts.FindAllReferences.Core { const sourceLength = text.length; const symbolNameLength = symbolName.length; - let position = text.indexOf(symbolName, start); + let position = text.indexOf(symbolName, container.pos); while (position >= 0) { // If we are past the end, stop looking - if (position > end) break; + if (position > container.end) break; // We found a match. Make sure it's not part of a larger word (i.e. the char // before and after it have to be a non-identifier char). @@ -760,8 +757,7 @@ namespace ts.FindAllReferences.Core { } function addReferencesForKeywordInFile(sourceFile: SourceFile, kind: SyntaxKind, searchText: string, references: Push): void { - // Want fullStart so we can find the symbol in JSDoc comments - const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile, /*fullStart*/ true); + const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile); for (const position of possiblePositions) { const referenceLocation = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); if (referenceLocation.kind === kind) { @@ -785,8 +781,7 @@ namespace ts.FindAllReferences.Core { return; } - const fullStart = state.options.findInComments || container.jsDoc !== undefined || forEach(search.symbol.declarations, d => d.kind === ts.SyntaxKind.JSDocTypedefTag); - for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container, fullStart)) { + for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container)) { getReferencesAtLocation(sourceFile, position, search, state); } } diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 585af7ebd31..5e8e7b8b3a7 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -73,54 +73,56 @@ namespace ts.FindAllReferences { function handleDirectImports(exportingModuleSymbol: Symbol): void { const theseDirectImports = getDirectImports(exportingModuleSymbol); - if (theseDirectImports) for (const direct of theseDirectImports) { - if (!markSeenDirectImport(direct)) { - continue; - } + if (theseDirectImports) { + for (const direct of theseDirectImports) { + if (!markSeenDirectImport(direct)) { + continue; + } - cancellationToken.throwIfCancellationRequested(); + cancellationToken.throwIfCancellationRequested(); - switch (direct.kind) { - case SyntaxKind.CallExpression: - if (!isAvailableThroughGlobal) { - const parent = direct.parent!; - if (exportKind === ExportKind.ExportEquals && parent.kind === SyntaxKind.VariableDeclaration) { - const { name } = parent as ts.VariableDeclaration; - if (name.kind === SyntaxKind.Identifier) { - directImports.push(name); - break; + switch (direct.kind) { + case SyntaxKind.CallExpression: + if (!isAvailableThroughGlobal) { + const parent = direct.parent!; + if (exportKind === ExportKind.ExportEquals && parent.kind === SyntaxKind.VariableDeclaration) { + const { name } = parent as ts.VariableDeclaration; + if (name.kind === SyntaxKind.Identifier) { + directImports.push(name); + break; + } } + + // Don't support re-exporting 'require()' calls, so just add a single indirect user. + addIndirectUser(direct.getSourceFile()); } + break; - // Don't support re-exporting 'require()' calls, so just add a single indirect user. - addIndirectUser(direct.getSourceFile()); - } - break; + case SyntaxKind.ImportEqualsDeclaration: + handleNamespaceImport(direct, direct.name, hasModifier(direct, ModifierFlags.Export)); + break; - case SyntaxKind.ImportEqualsDeclaration: - handleNamespaceImport(direct, direct.name, hasModifier(direct, ModifierFlags.Export)); - break; + case SyntaxKind.ImportDeclaration: + const namedBindings = direct.importClause && direct.importClause.namedBindings; + if (namedBindings && namedBindings.kind === SyntaxKind.NamespaceImport) { + handleNamespaceImport(direct, namedBindings.name); + } + else { + directImports.push(direct); + } + break; - case SyntaxKind.ImportDeclaration: - const namedBindings = direct.importClause && direct.importClause.namedBindings; - if (namedBindings && namedBindings.kind === SyntaxKind.NamespaceImport) { - handleNamespaceImport(direct, namedBindings.name); - } - else { - directImports.push(direct); - } - break; - - case SyntaxKind.ExportDeclaration: - if (!direct.exportClause) { - // This is `export * from "foo"`, so imports of this module may import the export too. - handleDirectImports(getContainingModuleSymbol(direct, checker)); - } - else { - // This is `export { foo } from "foo"` and creates an alias symbol, so recursive search will get handle re-exports. - directImports.push(direct); - } - break; + case SyntaxKind.ExportDeclaration: + if (!direct.exportClause) { + // This is `export * from "foo"`, so imports of this module may import the export too. + handleDirectImports(getContainingModuleSymbol(direct, checker)); + } + else { + // This is `export { foo } from "foo"` and creates an alias symbol, so recursive search will get handle re-exports. + directImports.push(direct); + } + break; + } } } } @@ -160,8 +162,10 @@ namespace ts.FindAllReferences { const moduleSymbol = checker.getMergedSymbol(sourceFileLike.symbol); Debug.assert(!!(moduleSymbol.flags & SymbolFlags.Module)); const directImports = getDirectImports(moduleSymbol); - if (directImports) for (const directImport of directImports) { - addIndirectUsers(getSourceFileLikeForImportDeclaration(directImport)); + if (directImports) { + for (const directImport of directImports) { + addIndirectUsers(getSourceFileLikeForImportDeclaration(directImport)); + } } } @@ -183,8 +187,10 @@ namespace ts.FindAllReferences { importSearches.push([location, symbol]); } - if (directImports) for (const decl of directImports) { - handleImport(decl); + if (directImports) { + for (const decl of directImports) { + handleImport(decl); + } } return { importSearches, singleReferences }; @@ -258,25 +264,27 @@ namespace ts.FindAllReferences { } function searchForNamedImport(namedBindings: NamedImportsOrExports | undefined): void { - if (namedBindings) for (const element of namedBindings.elements) { - const { name, propertyName } = element; - if ((propertyName || name).text !== exportName) { - continue; - } - - if (propertyName) { - // This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference. - singleReferences.push(propertyName); - if (!isForRename) { // If renaming `foo`, don't touch `bar`, just `foo`. - // Search locally for `bar`. - addSearch(name, checker.getSymbolAtLocation(name)); + if (namedBindings) { + for (const element of namedBindings.elements) { + const { name, propertyName } = element; + if ((propertyName || name).text !== exportName) { + continue; + } + + if (propertyName) { + // This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference. + singleReferences.push(propertyName); + if (!isForRename) { // If renaming `foo`, don't touch `bar`, just `foo`. + // Search locally for `bar`. + addSearch(name, checker.getSymbolAtLocation(name)); + } + } + else { + const localSymbol = element.kind === SyntaxKind.ExportSpecifier && element.propertyName + ? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol. + : checker.getSymbolAtLocation(name); + addSearch(name, localSymbol); } - } - else { - const localSymbol = element.kind === SyntaxKind.ExportSpecifier && element.propertyName - ? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol. - : checker.getSymbolAtLocation(name); - addSearch(name, localSymbol); } } } @@ -436,8 +444,8 @@ namespace ts.FindAllReferences { if (parent.kind === SyntaxKind.PropertyAccessExpression) { // When accessing an export of a JS module, there's no alias. The symbol will still be flagged as an export even though we're at the use. // So check that we are at the declaration. - return symbol.declarations.some(d => d === parent) && parent.parent.kind === ts.SyntaxKind.BinaryExpression - ? getSpecialPropertyExport(parent.parent as ts.BinaryExpression, /*useLhsSymbol*/ false) + return symbol.declarations.some(d => d === parent) && isBinaryExpression(parent.parent) + ? getSpecialPropertyExport(parent.parent, /*useLhsSymbol*/ false) : undefined; } else { @@ -449,31 +457,41 @@ namespace ts.FindAllReferences { else { const exportNode = getExportNode(parent); if (exportNode && hasModifier(exportNode, ModifierFlags.Export)) { - if (exportNode.kind === SyntaxKind.ImportEqualsDeclaration && (exportNode as ImportEqualsDeclaration).moduleReference === node) { + if (isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) { // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement. if (comingFromExport) { return undefined; } - const lhsSymbol = checker.getSymbolAtLocation((exportNode as ImportEqualsDeclaration).name); + const lhsSymbol = checker.getSymbolAtLocation(exportNode.name); return { kind: ImportExport.Import, symbol: lhsSymbol, isNamedImport: false }; } else { return exportInfo(symbol, getExportKindForDeclaration(exportNode)); } } - else if (parent.kind === SyntaxKind.ExportAssignment) { - // Get the symbol for the `export =` node; its parent is the module it's the export of. - const exportingModuleSymbol = parent.symbol.parent; - Debug.assert(!!exportingModuleSymbol); - return { kind: ImportExport.Export, symbol, exportInfo: { exportingModuleSymbol, exportKind: ExportKind.ExportEquals } }; + // If we are in `export = a;`, `parent` is the export assignment. + else if (isExportAssignment(parent)) { + return getExportAssignmentExport(parent); } - else if (parent.kind === ts.SyntaxKind.BinaryExpression) { - return getSpecialPropertyExport(parent as ts.BinaryExpression, /*useLhsSymbol*/ true); + // If we are in `export = class A {};` at `A`, `parent.parent` is the export assignment. + else if (isExportAssignment(parent.parent)) { + return getExportAssignmentExport(parent.parent); } - else if (parent.parent.kind === SyntaxKind.BinaryExpression) { - return getSpecialPropertyExport(parent.parent as ts.BinaryExpression, /*useLhsSymbol*/ true); + // Similar for `module.exports =` and `exports.A =`. + else if (isBinaryExpression(parent)) { + return getSpecialPropertyExport(parent, /*useLhsSymbol*/ true); } + else if (isBinaryExpression(parent.parent)) { + return getSpecialPropertyExport(parent.parent, /*useLhsSymbol*/ true); + } + } + + function getExportAssignmentExport(ex: ExportAssignment): ExportedSymbol { + // Get the symbol for the `export =` node; its parent is the module it's the export of. + const exportingModuleSymbol = ex.symbol.parent; + Debug.assert(!!exportingModuleSymbol); + return { kind: ImportExport.Export, symbol, exportInfo: { exportingModuleSymbol, exportKind: ExportKind.ExportEquals } }; } function getSpecialPropertyExport(node: ts.BinaryExpression, useLhsSymbol: boolean): ExportedSymbol | undefined { @@ -496,21 +514,21 @@ namespace ts.FindAllReferences { function getImport(): ImportedSymbol | undefined { const isImport = isNodeImport(node); - if (!isImport) return; + if (!isImport) return undefined; // A symbol being imported is always an alias. So get what that aliases to find the local symbol. let importedSymbol = checker.getImmediateAliasedSymbol(symbol); - if (importedSymbol) { - // Search on the local symbol in the exporting module, not the exported symbol. - importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker); - // Similarly, skip past the symbol for 'export =' - if (importedSymbol.name === "export=") { - importedSymbol = checker.getImmediateAliasedSymbol(importedSymbol); - } + if (!importedSymbol) return undefined; - if (symbolName(importedSymbol) === symbol.name) { // If this is a rename import, do not continue searching. - return { kind: ImportExport.Import, symbol: importedSymbol, ...isImport }; - } + // Search on the local symbol in the exporting module, not the exported symbol. + importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker); + // Similarly, skip past the symbol for 'export =' + if (importedSymbol.name === "export=") { + importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker); + } + + if (symbolName(importedSymbol) === symbol.name) { // If this is a rename import, do not continue searching. + return { kind: ImportExport.Import, symbol: importedSymbol, ...isImport }; } } @@ -525,6 +543,22 @@ namespace ts.FindAllReferences { } } + function getExportEqualsLocalSymbol(importedSymbol: Symbol, checker: TypeChecker): Symbol { + if (importedSymbol.flags & SymbolFlags.Alias) { + return checker.getImmediateAliasedSymbol(importedSymbol); + } + + const decl = importedSymbol.valueDeclaration; + if (isExportAssignment(decl)) { // `export = class {}` + return decl.expression.symbol; + } + else if (isBinaryExpression(decl)) { // `module.exports = class {}` + return decl.right.symbol; + } + Debug.fail(); + } + + // If a reference is a class expression, the exported node would be its parent. // If a reference is a variable declaration, the exported node would be the variable statement. function getExportNode(parent: Node): Node | undefined { if (parent.kind === SyntaxKind.VariableDeclaration) { @@ -578,12 +612,13 @@ namespace ts.FindAllReferences { /** If at an export specifier, go to the symbol it refers to. */ function skipExportSpecifierSymbol(symbol: Symbol, checker: TypeChecker): Symbol { // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does. - if (symbol.declarations) for (const declaration of symbol.declarations) { - if (isExportSpecifier(declaration) && !(declaration as ExportSpecifier).propertyName && !(declaration as ExportSpecifier).parent.parent.moduleSpecifier) { - return checker.getExportSpecifierLocalTargetSymbol(declaration); + if (symbol.declarations) { + for (const declaration of symbol.declarations) { + if (isExportSpecifier(declaration) && !(declaration as ExportSpecifier).propertyName && !(declaration as ExportSpecifier).parent.parent.moduleSpecifier) { + return checker.getExportSpecifierLocalTargetSymbol(declaration); + } } } - return symbol; } diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index 8ca55029603..5d03ad03b0c 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -132,6 +132,25 @@ namespace ts.JsDoc { })); } + export function getJSDocParameterNameCompletions(tag: JSDocParameterTag): CompletionEntry[] { + const nameThusFar = tag.name.text; + const jsdoc = tag.parent; + const fn = jsdoc.parent; + if (!ts.isFunctionLike(fn)) return []; + + return mapDefined(fn.parameters, param => { + if (!isIdentifier(param.name)) return undefined; + + const name = param.name.text; + if (jsdoc.tags.some(t => t !== tag && isJSDocParameterTag(t) && t.name.text === name) + || nameThusFar !== undefined && !startsWith(name, nameThusFar)) { + return undefined; + } + + return { name, kind: ScriptElementKind.parameterElement, kindModifiers: "", sortText: "0" }; + }); + } + /** * Checks if position points to a valid position to add JSDoc comments, and if so, * returns the appropriate template. Otherwise returns an empty string. diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index d4adeaea974..304f64f3cdb 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -10,7 +10,7 @@ namespace ts.NavigateTo { for (const sourceFile of sourceFiles) { cancellationToken.throwIfCancellationRequested(); - if (excludeDtsFiles && fileExtensionIs(sourceFile.fileName, ".d.ts")) { + if (excludeDtsFiles && fileExtensionIs(sourceFile.fileName, Extension.Dts)) { continue; } diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 0f0702066e1..7efc174c423 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -95,9 +95,16 @@ namespace ts { function tryConsumeImport(): boolean { let token = scanner.getToken(); if (token === SyntaxKind.ImportKeyword) { - token = nextToken(); - if (token === SyntaxKind.StringLiteral) { + if (token === SyntaxKind.OpenParenToken) { + token = nextToken(); + if (token === SyntaxKind.StringLiteral) { + // import("mod"); + recordModuleName(); + return true; + } + } + else if (token === SyntaxKind.StringLiteral) { // import "mod"; recordModuleName(); return true; @@ -297,7 +304,8 @@ namespace ts { // import * as NS from "mod" // import d, {a, b as B} from "mod" // import i = require("mod"); - // + // import("mod"); + // export * from "mod" // export {a as b} from "mod" // export import i = require("mod") diff --git a/src/services/refactorProvider.ts b/src/services/refactorProvider.ts index 1058f9c2ca6..3c02ddf671c 100644 --- a/src/services/refactorProvider.ts +++ b/src/services/refactorProvider.ts @@ -8,10 +8,10 @@ namespace ts { description: string; /** Compute the associated code actions */ - getCodeActions(context: RefactorContext): CodeAction[]; + getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined; - /** A fast syntactic check to see if the refactor is applicable at given position. */ - isApplicable(context: RefactorContext): boolean; + /** Compute (quickly) which actions are available here */ + getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined; } export interface RefactorContext { @@ -34,7 +34,6 @@ namespace ts { } export function getApplicableRefactors(context: RefactorContext): ApplicableRefactorInfo[] | undefined { - let results: ApplicableRefactorInfo[]; const refactorList: Refactor[] = []; refactors.forEach(refactor => { @@ -44,16 +43,17 @@ namespace ts { if (context.cancellationToken && context.cancellationToken.isCancellationRequested()) { return results; } - if (refactor.isApplicable(context)) { - (results || (results = [])).push({ name: refactor.name, description: refactor.description }); + const infos = refactor.getAvailableActions(context); + if (infos && infos.length) { + (results || (results = [])).push(...infos); } } return results; } - export function getRefactorCodeActions(context: RefactorContext, refactorName: string): CodeAction[] | undefined { + export function getEditsForRefactor(context: RefactorContext, refactorName: string, actionName: string): RefactorEditInfo | undefined { const refactor = refactors.get(refactorName); - return refactor && refactor.getCodeActions(context); + return refactor && refactor.getEditsForAction(context, actionName); } } } diff --git a/src/services/refactors/convertFunctionToEs6Class.ts b/src/services/refactors/convertFunctionToEs6Class.ts index a34e0ccca2f..d275924b76a 100644 --- a/src/services/refactors/convertFunctionToEs6Class.ts +++ b/src/services/refactors/convertFunctionToEs6Class.ts @@ -1,16 +1,18 @@ /* @internal */ namespace ts.refactor { + const actionName = "convert"; + const convertFunctionToES6Class: Refactor = { name: "Convert to ES2015 class", description: Diagnostics.Convert_function_to_an_ES2015_class.message, - getCodeActions, - isApplicable + getEditsForAction, + getAvailableActions }; registerRefactor(convertFunctionToES6Class); - function isApplicable(context: RefactorContext): boolean { + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] { const start = context.startPosition; const node = getTokenAtPosition(context.file, start, /*includeJsDocComment*/ false); const checker = context.program.getTypeChecker(); @@ -20,10 +22,28 @@ namespace ts.refactor { symbol = (symbol.valueDeclaration as VariableDeclaration).initializer.symbol; } - return symbol && symbol.flags & SymbolFlags.Function && symbol.members && symbol.members.size > 0; + if (symbol && (symbol.flags & SymbolFlags.Function) && symbol.members && (symbol.members.size > 0)) { + return [ + { + name: convertFunctionToES6Class.name, + description: convertFunctionToES6Class.description, + actions: [ + { + description: convertFunctionToES6Class.description, + name: actionName + } + ] + } + ]; + } } - function getCodeActions(context: RefactorContext): CodeAction[] | undefined { + function getEditsForAction(context: RefactorContext, action: string): RefactorEditInfo | undefined { + // Somehow wrong action got invoked? + if (actionName !== action) { + return undefined; + } + const start = context.startPosition; const sourceFile = context.file; const checker = context.program.getTypeChecker(); @@ -35,7 +55,7 @@ namespace ts.refactor { const deletes: (() => any)[] = []; if (!(ctorSymbol.flags & (SymbolFlags.Function | SymbolFlags.Variable))) { - return []; + return undefined; } const ctorDeclaration = ctorSymbol.valueDeclaration; @@ -63,7 +83,7 @@ namespace ts.refactor { } if (!newClassDeclaration) { - return []; + return undefined; } // Because the preceding node could be touched, we need to insert nodes before delete nodes. @@ -72,10 +92,9 @@ namespace ts.refactor { deleteCallback(); } - return [{ - description: formatStringFromArgs(Diagnostics.Convert_function_0_to_class.message, [ctorSymbol.name]), - changes: changeTracker.getChanges() - }]; + return { + edits: changeTracker.getChanges() + }; function deleteNode(node: Node, inList = false) { if (deletedNodes.some(n => isNodeDescendantOf(node, n))) { diff --git a/src/services/services.ts b/src/services/services.ts index 9e01d094308..b508285b182 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -37,7 +37,7 @@ namespace ts { let ruleProvider: formatting.RulesProvider; function createNode(kind: TKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject | IdentifierObject { - const node = kind >= SyntaxKind.FirstNode ? new NodeObject(kind, pos, end) : + const node = isNodeKind(kind) ? new NodeObject(kind, pos, end) : kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) : new TokenObject(kind, pos, end); node.parent = parent; @@ -103,10 +103,10 @@ namespace ts { return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd()); } - private addSyntheticNodes(nodes: Node[], pos: number, end: number, useJSDocScanner?: boolean): number { + private addSyntheticNodes(nodes: Node[], pos: number, end: number): number { scanner.setTextPos(pos); while (pos < end) { - const token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan(); + const token = scanner.scan(); Debug.assert(token !== SyntaxKind.EndOfFileToken); // Else it would infinitely loop const textPos = scanner.getTextPos(); if (textPos <= end) { @@ -136,54 +136,50 @@ namespace ts { } private createChildren(sourceFile?: SourceFileLike) { - if (isJSDocTag(this)) { + if (!isNodeKind(this.kind)) { + this._children = emptyArray; + return; + } + + if (isJSDocCommentContainingNode(this)) { /** Don't add trivia for "tokens" since this is in a comment. */ const children: Node[] = []; this.forEachChild(child => { children.push(child); }); this._children = children; + return; } - else if (this.kind >= SyntaxKind.FirstNode) { - const children: Node[] = []; - scanner.setText((sourceFile || this.getSourceFile()).text); - let pos = this.pos; - const useJSDocScanner = this.kind >= SyntaxKind.FirstJSDocTagNode && this.kind <= SyntaxKind.LastJSDocTagNode; - const processNode = (node: Node) => { - const isJSDocTagNode = isJSDocTag(node); - if (!isJSDocTagNode && pos < node.pos) { - pos = this.addSyntheticNodes(children, pos, node.pos, useJSDocScanner); - } - children.push(node); - if (!isJSDocTagNode) { - pos = node.end; - } - }; - const processNodes = (nodes: NodeArray) => { - if (pos < nodes.pos) { - pos = this.addSyntheticNodes(children, pos, nodes.pos, useJSDocScanner); - } - children.push(this.createSyntaxList(nodes)); - pos = nodes.end; - }; - // jsDocComments need to be the first children - if (this.jsDoc) { - for (const jsDocComment of this.jsDoc) { - processNode(jsDocComment); - } + + const children: Node[] = []; + scanner.setText((sourceFile || this.getSourceFile()).text); + let pos = this.pos; + const processNode = (node: Node) => { + pos = this.addSyntheticNodes(children, pos, node.pos); + children.push(node); + pos = node.end; + }; + const processNodes = (nodes: NodeArray) => { + if (pos < nodes.pos) { + pos = this.addSyntheticNodes(children, pos, nodes.pos); } - // For syntactic classifications, all trivia are classcified together, including jsdoc comments. - // For that to work, the jsdoc comments should still be the leading trivia of the first child. - // Restoring the scanner position ensures that. - pos = this.pos; - forEachChild(this, processNode, processNodes); - if (pos < this.end) { - this.addSyntheticNodes(children, pos, this.end); + children.push(this.createSyntaxList(nodes)); + pos = nodes.end; + }; + // jsDocComments need to be the first children + if (this.jsDoc) { + for (const jsDocComment of this.jsDoc) { + processNode(jsDocComment); } - scanner.setText(undefined); - this._children = children; } - else { - this._children = emptyArray; + // For syntactic classifications, all trivia are classcified together, including jsdoc comments. + // For that to work, the jsdoc comments should still be the leading trivia of the first child. + // Restoring the scanner position ensures that. + pos = this.pos; + forEachChild(this, processNode, processNodes); + if (pos < this.end) { + this.addSyntheticNodes(children, pos, this.end); } + scanner.setText(undefined); + this._children = children; } public getChildCount(sourceFile?: SourceFile): number { @@ -684,8 +680,9 @@ namespace ts { forEachChild(decl.name, visit); break; } - if (decl.initializer) + if (decl.initializer) { visit(decl.initializer); + } } // falls through case SyntaxKind.EnumMember: @@ -732,6 +729,15 @@ namespace ts { } } + class SourceMapSourceObject implements SourceMapSource { + lineMap: number[]; + constructor (public fileName: string, public text: string, public skipTrivia?: (pos: number) => number) {} + + public getLineAndCharacterOfPosition(pos: number): LineAndCharacter { + return ts.getLineAndCharacterOfPosition(this, pos); + } + } + function getServicesObjectAllocator(): ObjectAllocator { return { getNodeConstructor: () => NodeObject, @@ -742,6 +748,7 @@ namespace ts { getSymbolConstructor: () => SymbolObject, getTypeConstructor: () => TypeObject, getSignatureConstructor: () => SignatureObject, + getSourceMapSourceConstructor: () => SourceMapSourceObject, }; } @@ -815,7 +822,7 @@ namespace ts { private _compilationSettings: CompilerOptions; private currentDirectory: string; - constructor(private host: LanguageServiceHost, private getCanonicalFileName: (fileName: string) => string) { + constructor(private host: LanguageServiceHost, getCanonicalFileName: (fileName: string) => string) { // script id => script index this.currentDirectory = host.getCurrentDirectory(); this.fileNameToEntry = createFileMap(); @@ -850,22 +857,17 @@ namespace ts { return entry; } - private getEntry(path: Path): HostFileInformation { + public getEntryByPath(path: Path): HostFileInformation { return this.fileNameToEntry.get(path); } - private contains(path: Path): boolean { + public containsEntryByPath(path: Path): boolean { return this.fileNameToEntry.contains(path); } - public getOrCreateEntry(fileName: string): HostFileInformation { - const path = toPath(fileName, this.currentDirectory, this.getCanonicalFileName); - return this.getOrCreateEntryByPath(fileName, path); - } - public getOrCreateEntryByPath(fileName: string, path: Path): HostFileInformation { - return this.contains(path) - ? this.getEntry(path) + return this.containsEntryByPath(path) + ? this.getEntryByPath(path) : this.createEntry(fileName, path); } @@ -882,12 +884,12 @@ namespace ts { } public getVersion(path: Path): string { - const file = this.getEntry(path); + const file = this.getEntryByPath(path); return file && file.version; } public getScriptSnapshot(path: Path): IScriptSnapshot { - const file = this.getEntry(path); + const file = this.getEntryByPath(path); return file && file.scriptSnapshot; } } @@ -1152,12 +1154,19 @@ namespace ts { getCurrentDirectory: () => currentDirectory, fileExists: (fileName): boolean => { // stub missing host functionality - return hostCache.getOrCreateEntry(fileName) !== undefined; + const path = toPath(fileName, currentDirectory, getCanonicalFileName); + return hostCache.containsEntryByPath(path) ? + !!hostCache.getEntryByPath(path) : + (host.fileExists && host.fileExists(fileName)); }, readFile: (fileName): string => { // stub missing host functionality - const entry = hostCache.getOrCreateEntry(fileName); - return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); + const path = toPath(fileName, currentDirectory, getCanonicalFileName); + if (hostCache.containsEntryByPath(path)) { + const entry = hostCache.getEntryByPath(path); + return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); + } + return host.readFile && host.readFile(fileName); }, directoryExists: directoryName => { return directoryProbablyExists(directoryName, host); @@ -1321,7 +1330,9 @@ namespace ts { if (program) { forEach(program.getSourceFiles(), f => documentRegistry.releaseDocument(f.fileName, program.getCompilerOptions())); + program = undefined; } + host = undefined; } /// Diagnostics @@ -1827,6 +1838,13 @@ namespace ts { return false; } + switch (openingBrace) { + case CharacterCodes.singleQuote: + case CharacterCodes.doubleQuote: + case CharacterCodes.backtick: + return !isInComment(sourceFile, position); + } + return true; } @@ -2001,15 +2019,16 @@ namespace ts { return refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange)); } - function getRefactorCodeActions( + function getEditsForRefactor( fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, - refactorName: string): CodeAction[] | undefined { + refactorName: string, + actionName: string): RefactorEditInfo { synchronizeHostData(); const file = getValidSourceFile(fileName); - return refactor.getRefactorCodeActions(getRefactorContext(file, positionOrRange, formatOptions), refactorName); + return refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, formatOptions), refactorName, actionName); } return { @@ -2017,8 +2036,6 @@ namespace ts { cleanupSemanticCache, getSyntacticDiagnostics, getSemanticDiagnostics, - getApplicableRefactors, - getRefactorCodeActions, getCompilerOptionsDiagnostics, getSyntacticClassifications, getSemanticClassifications, @@ -2056,7 +2073,9 @@ namespace ts { getEmitOutput, getNonBoundSourceFile, getSourceFile, - getProgram + getProgram, + getApplicableRefactors, + getEditsForRefactor, }; } diff --git a/src/services/shims.ts b/src/services/shims.ts index 91c9d5d598f..1c37f598021 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -1237,4 +1237,4 @@ namespace TypeScript.Services { // TODO: it should be moved into a namespace though. /* @internal */ -const toolsVersion = "2.4"; +const toolsVersion = "2.5"; diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 910c31c36b3..345f0718fe3 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -4,8 +4,10 @@ namespace ts.SymbolDisplay { export function getSymbolKind(typeChecker: TypeChecker, symbol: Symbol, location: Node): ScriptElementKind { const { flags } = symbol; - if (flags & SymbolFlags.Class) return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ? + if (flags & SymbolFlags.Class) { + return getDeclarationOfKind(symbol, SyntaxKind.ClassExpression) ? ScriptElementKind.localClassElement : ScriptElementKind.classElement; + } if (flags & SymbolFlags.Enum) return ScriptElementKind.enumElement; if (flags & SymbolFlags.TypeAlias) return ScriptElementKind.typeElement; if (flags & SymbolFlags.Interface) return ScriptElementKind.interfaceElement; diff --git a/src/services/types.ts b/src/services/types.ts index e042276e650..2d47da2fd1d 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -71,6 +71,10 @@ namespace ts { getLineAndCharacterOfPosition(pos: number): LineAndCharacter; } + export interface SourceMapSource { + getLineAndCharacterOfPosition(pos: number): LineAndCharacter; + } + /** * Represents an immutable snapshot of a script at a specified time.Once acquired, the * snapshot is observably immutable. i.e. the same calls with the same parameters will return @@ -261,8 +265,9 @@ namespace ts { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[], formatOptions: FormatCodeSettings): CodeAction[]; + getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange): ApplicableRefactorInfo[]; - getRefactorCodeActions(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string): CodeAction[] | undefined; + getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string): RefactorEditInfo | undefined; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; @@ -353,11 +358,60 @@ namespace ts { changes: FileTextChanges[]; } + /** + * A set of one or more available refactoring actions, grouped under a parent refactoring. + */ export interface ApplicableRefactorInfo { + /** + * The programmatic name of the refactoring + */ name: string; + /** + * A description of this refactoring category to show to the user. + * If the refactoring gets inlined (see below), this text will not be visible. + */ description: string; + /** + * Inlineable refactorings can have their actions hoisted out to the top level + * of a context menu. Non-inlineanable refactorings should always be shown inside + * their parent grouping. + * + * If not specified, this value is assumed to be 'true' + */ + inlineable?: boolean; + + actions: RefactorActionInfo[]; } + /** + * Represents a single refactoring action - for example, the "Extract Method..." refactor might + * offer several actions, each corresponding to a surround class or closure to extract into. + */ + export type RefactorActionInfo = { + /** + * The programmatic name of the refactoring action + */ + name: string; + + /** + * A description of this refactoring action to show to the user. + * If the parent refactoring is inlined away, this will be the only text shown, + * so this description should make sense by itself if the parent is inlineable=true + */ + description: string; + }; + + /** + * A set of edits to make in response to a refactor action, plus an optional + * location where renaming should be invoked from + */ + export type RefactorEditInfo = { + edits: FileTextChanges[]; + renameFilename?: string; + renameLocation?: number; + }; + + export interface TextInsertion { newText: string; /** The position in newText the caret should point to after the insertion. */ diff --git a/src/services/utilities.ts b/src/services/utilities.ts index b642b790576..78c71403736 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -82,7 +82,7 @@ namespace ts { else if (node.parent.kind === SyntaxKind.ExportAssignment) { return SemanticMeaning.All; } - else if (isInRightSideOfImport(node)) { + else if (isInRightSideOfInternalImportEqualsDeclaration(node)) { return getMeaningFromRightHandSideOfImportEquals(node); } else if (isDeclarationName(node)) { @@ -94,6 +94,10 @@ namespace ts { else if (isNamespaceReference(node)) { return SemanticMeaning.Namespace; } + else if (isTypeParameterDeclaration(node.parent)) { + Debug.assert(isJSDocTemplateTag(node.parent.parent)); // Else would be handled by isDeclarationName + return SemanticMeaning.Type; + } else { return SemanticMeaning.Value; } @@ -114,7 +118,7 @@ namespace ts { return SemanticMeaning.Namespace; } - function isInRightSideOfImport(node: Node) { + export function isInRightSideOfInternalImportEqualsDeclaration(node: Node) { while (node.parent.kind === SyntaxKind.QualifiedName) { node = node.parent; } @@ -615,18 +619,21 @@ namespace ts { return getTouchingToken(sourceFile, position, includeJsDocComment, n => isPropertyName(n.kind)); } - /** Returns the token if position is in [start, end) or if position === end and includeItemAtEndPosition(token) === true */ - export function getTouchingToken(sourceFile: SourceFile, position: number, includeJsDocComment: boolean, includeItemAtEndPosition?: (n: Node) => boolean): Node { - return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includeItemAtEndPosition, includeJsDocComment); + /** + * Returns the token if position is in [start, end). + * If position === end, returns the preceding token if includeItemAtEndPosition(previousToken) === true + */ + export function getTouchingToken(sourceFile: SourceFile, position: number, includeJsDocComment: boolean, includePrecedingTokenAtEndPosition?: (n: Node) => boolean): Node { + return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includePrecedingTokenAtEndPosition, /*includeEndPosition*/ false, includeJsDocComment); } /** Returns a token if position is in [start-of-leading-trivia, end) */ - export function getTokenAtPosition(sourceFile: SourceFile, position: number, includeJsDocComment: boolean): Node { - return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includeItemAtEndPosition*/ undefined, includeJsDocComment); + export function getTokenAtPosition(sourceFile: SourceFile, position: number, includeJsDocComment: boolean, includeEndPosition?: boolean): Node { + return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, includeEndPosition, includeJsDocComment); } /** Get the token whose text contains the position */ - function getTokenAtPositionWorker(sourceFile: SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeItemAtEndPosition: (n: Node) => boolean, includeJsDocComment: boolean): Node { + function getTokenAtPositionWorker(sourceFile: SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includePrecedingTokenAtEndPosition: (n: Node) => boolean, includeEndPosition: boolean, includeJsDocComment: boolean): Node { let current: Node = sourceFile; outer: while (true) { if (isToken(current)) { @@ -636,7 +643,7 @@ namespace ts { // find the child that contains 'position' for (const child of current.getChildren()) { - if (isJSDocNode(child) && !includeJsDocComment) { + if (!includeJsDocComment && isJSDocNode(child)) { continue; } @@ -646,13 +653,13 @@ namespace ts { } const end = child.getEnd(); - if (position < end || (position === end && child.kind === SyntaxKind.EndOfFileToken)) { + if (position < end || (position === end && (child.kind === SyntaxKind.EndOfFileToken || includeEndPosition))) { current = child; continue outer; } - else if (includeItemAtEndPosition && end === position) { + else if (includePrecedingTokenAtEndPosition && end === position) { const previousToken = findPrecedingToken(position, sourceFile, child); - if (previousToken && includeItemAtEndPosition(previousToken)) { + if (previousToken && includePrecedingTokenAtEndPosition(previousToken)) { return previousToken; } } @@ -707,7 +714,7 @@ namespace ts { } } - export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node): Node { + export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node, includeJsDoc?: boolean): Node { return find(startNode || sourceFile); function findRightmostToken(n: Node): Node { @@ -738,7 +745,7 @@ namespace ts { // NOTE: JsxText is a weird kind of node that can contain only whitespaces (since they are not counted as trivia). // if this is the case - then we should assume that token in question is located in previous child. if (position < child.end && (nodeHasTokens(child) || child.kind === SyntaxKind.JsxText)) { - const start = child.getStart(sourceFile); + const start = child.getStart(sourceFile, includeJsDoc); const lookInPreviousChild = (start >= position) || // cursor in the leading trivia (child.kind === SyntaxKind.JsxText && start === child.end); // whitespace only JsxText @@ -755,7 +762,7 @@ namespace ts { } } - Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile); + Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile || isJSDocCommentContainingNode(n)); // Here we know that none of child token nodes embrace the position, // the only known case is when position is at the end of the file. @@ -901,42 +908,6 @@ namespace ts { } } - /** - * Get the corresponding JSDocTag node if the position is in a jsDoc comment - */ - export function getJsDocTagAtPosition(sourceFile: SourceFile, position: number): JSDocTag { - let node = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); - if (isToken(node)) { - switch (node.kind) { - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.ConstKeyword: - // if the current token is var, let or const, skip the VariableDeclarationList - node = node.parent === undefined ? undefined : node.parent.parent; - break; - default: - node = node.parent; - break; - } - } - - if (node) { - if (node.jsDoc) { - for (const jsDoc of node.jsDoc) { - if (jsDoc.tags) { - for (const tag of jsDoc.tags) { - if (tag.pos <= position && position <= tag.end) { - return tag; - } - } - } - } - } - } - - return undefined; - } - function nodeHasTokens(n: Node): boolean { // If we have a token or node that has a non-zero width, it must have tokens. // Note, that getWidth() does not take trivia into account. diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json index 92b9cb450e6..b47a07e8487 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argSynonymForParamTag.json @@ -40,6 +40,7 @@ "end": 27, "text": "name1" }, + "isBracketed": false, "comment": "Description" }, "length": 1, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json index f398fb3af41..cf86fda872e 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.argumentSynonymForParamTag.json @@ -40,6 +40,7 @@ "end": 32, "text": "name1" }, + "isBracketed": false, "comment": "Description" }, "length": 1, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json index e70fc95367f..506487232e0 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.oneParamTag.json @@ -40,6 +40,7 @@ "end": 29, "text": "name1" }, + "isBracketed": false, "comment": "" }, "length": 1, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json index 0dbdd83d2ba..abc116d7452 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTag1.json @@ -40,6 +40,7 @@ "end": 29, "text": "name1" }, + "isBracketed": false, "comment": "Description text follows" }, "length": 1, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json index 204d94779b3..9d66ca3dd55 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType1.json @@ -40,6 +40,7 @@ "end": 20, "text": "name1" }, + "isBracketed": false, "comment": "" }, "length": 1, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json index 7c79459768b..01d08a103c1 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramTagNameThenType2.json @@ -40,6 +40,7 @@ "end": 20, "text": "name1" }, + "isBracketed": false, "comment": "Description" }, "length": 1, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json index 2ff182483d9..ab15d24f618 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.paramWithoutType.json @@ -30,6 +30,7 @@ "end": 18, "text": "foo" }, + "isBracketed": false, "comment": "" }, "length": 1, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json index b51ab3598e6..5ba60030f1b 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTag2.json @@ -40,6 +40,7 @@ "end": 29, "text": "name1" }, + "isBracketed": false, "comment": "" }, "1": { @@ -79,6 +80,7 @@ "end": 55, "text": "name2" }, + "isBracketed": false, "comment": "" }, "length": 2, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json index 3c20d5edcbc..7d26097bb34 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.twoParamTagOnSameLine.json @@ -40,6 +40,7 @@ "end": 29, "text": "name1" }, + "isBracketed": false, "comment": "" }, "1": { @@ -79,6 +80,7 @@ "end": 51, "text": "name2" }, + "isBracketed": false, "comment": "" }, "length": 2, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json index 7a8f9c4bcc9..13826b63d9c 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.typedefTagWithChildrenTags.json @@ -103,7 +103,8 @@ "pos": 66, "end": 69, "text": "age" - } + }, + "isBracketed": false }, { "kind": "JSDocPropertyTag", @@ -141,7 +142,8 @@ "pos": 93, "end": 97, "text": "name" - } + }, + "isBracketed": false } ] }, diff --git a/tests/baselines/reference/argumentsObjectCreatesRestForJs.symbols b/tests/baselines/reference/argumentsObjectCreatesRestForJs.symbols new file mode 100644 index 00000000000..6a95dbc86d8 --- /dev/null +++ b/tests/baselines/reference/argumentsObjectCreatesRestForJs.symbols @@ -0,0 +1,44 @@ +=== tests/cases/compiler/main.js === +function allRest() { arguments; } +>allRest : Symbol(allRest, Decl(main.js, 0, 0)) +>arguments : Symbol(arguments) + +allRest(); +>allRest : Symbol(allRest, Decl(main.js, 0, 0)) + +allRest(1, 2, 3); +>allRest : Symbol(allRest, Decl(main.js, 0, 0)) + +function someRest(x, y) { arguments; } +>someRest : Symbol(someRest, Decl(main.js, 2, 17)) +>x : Symbol(x, Decl(main.js, 3, 18)) +>y : Symbol(y, Decl(main.js, 3, 20)) +>arguments : Symbol(arguments) + +someRest(); // x and y are still optional because they are in a JS file +>someRest : Symbol(someRest, Decl(main.js, 2, 17)) + +someRest(1, 2, 3); +>someRest : Symbol(someRest, Decl(main.js, 2, 17)) + +/** + * @param {number} x - a thing + */ +function jsdocced(x) { arguments; } +>jsdocced : Symbol(jsdocced, Decl(main.js, 5, 18)) +>x : Symbol(x, Decl(main.js, 10, 18)) +>arguments : Symbol(arguments) + +jsdocced(1); +>jsdocced : Symbol(jsdocced, Decl(main.js, 5, 18)) + +function dontDoubleRest(x, ...y) { arguments; } +>dontDoubleRest : Symbol(dontDoubleRest, Decl(main.js, 11, 12)) +>x : Symbol(x, Decl(main.js, 13, 24)) +>y : Symbol(y, Decl(main.js, 13, 26)) +>arguments : Symbol(arguments) + +dontDoubleRest(1, 2, 3); +>dontDoubleRest : Symbol(dontDoubleRest, Decl(main.js, 11, 12)) + + diff --git a/tests/baselines/reference/argumentsObjectCreatesRestForJs.types b/tests/baselines/reference/argumentsObjectCreatesRestForJs.types new file mode 100644 index 00000000000..10596fb10c7 --- /dev/null +++ b/tests/baselines/reference/argumentsObjectCreatesRestForJs.types @@ -0,0 +1,60 @@ +=== tests/cases/compiler/main.js === +function allRest() { arguments; } +>allRest : (...args: any[]) => void +>arguments : IArguments + +allRest(); +>allRest() : void +>allRest : (...args: any[]) => void + +allRest(1, 2, 3); +>allRest(1, 2, 3) : void +>allRest : (...args: any[]) => void +>1 : 1 +>2 : 2 +>3 : 3 + +function someRest(x, y) { arguments; } +>someRest : (x: any, y: any, ...args: any[]) => void +>x : any +>y : any +>arguments : IArguments + +someRest(); // x and y are still optional because they are in a JS file +>someRest() : void +>someRest : (x: any, y: any, ...args: any[]) => void + +someRest(1, 2, 3); +>someRest(1, 2, 3) : void +>someRest : (x: any, y: any, ...args: any[]) => void +>1 : 1 +>2 : 2 +>3 : 3 + +/** + * @param {number} x - a thing + */ +function jsdocced(x) { arguments; } +>jsdocced : (x: number) => void +>x : number +>arguments : IArguments + +jsdocced(1); +>jsdocced(1) : void +>jsdocced : (x: number) => void +>1 : 1 + +function dontDoubleRest(x, ...y) { arguments; } +>dontDoubleRest : (x: any, ...y: any[]) => void +>x : any +>y : any[] +>arguments : IArguments + +dontDoubleRest(1, 2, 3); +>dontDoubleRest(1, 2, 3) : void +>dontDoubleRest : (x: any, ...y: any[]) => void +>1 : 1 +>2 : 2 +>3 : 3 + + diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt index 0e8605efafd..28fe7c738a6 100644 --- a/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithCallSignatures3.errors.txt @@ -1,11 +1,58 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(47,1): error TS2322: Type '(x: number) => number[]' is not assignable to type '(x: T) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(50,1): error TS2322: Type '(x: number) => string[]' is not assignable to type '(x: T) => string[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(53,1): error TS2322: Type '(x: number) => void' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(56,1): error TS2322: Type '(x: string, y: number) => string' is not assignable to type '(x: T, y: U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(59,1): error TS2322: Type '(x: (arg: string) => number) => string' is not assignable to type '(x: (arg: T) => U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'string' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(62,1): error TS2322: Type '(x: (arg: Base) => Derived) => Base' is not assignable to type '(x: (arg: T) => U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(65,1): error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type '(x: (arg: T) => U) => (r: T) => U'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(68,1): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(71,1): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(74,1): error TS2322: Type '(...x: Derived[]) => Derived' is not assignable to type '(...x: T[]) => T'. + Type 'Derived' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(77,1): error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '(x: T, y: T) => T'. Types of parameters 'y' and 'y' are incompatible. - Types of parameters 'arg2' and 'arg2' are incompatible. - Type 'Base' is not assignable to type '{ foo: string; bing: number; }'. - Property 'bing' is missing in type 'Base'. + Type 'T' is not assignable to type '{ foo: string; bar: string; }'. + Type 'Base' is not assignable to type '{ foo: string; bar: string; }'. + Property 'bar' is missing in type 'Base'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(80,1): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '(x: Base[], y: T) => Derived[]'. + Types of parameters 'y' and 'y' are incompatible. + Type 'T' is not assignable to type 'Derived2[]'. + Type 'Base[]' is not assignable to type 'Derived2[]'. + Type 'Base' is not assignable to type 'Derived2'. + Property 'baz' is missing in type 'Base'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(83,1): error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '(x: Base[], y: T) => T'. + Type 'Derived[]' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '(x: { a: T; b: T; }) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'string'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (1 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (14 errors) ==== // these are all permitted with the current rules, since we do not do contextual signature instantiation class Base { foo: string; } @@ -53,51 +100,111 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var b: (x: T) => T[]; a = b; // ok b = a; // ok + ~ +!!! error TS2322: Type '(x: number) => number[]' is not assignable to type '(x: T) => T[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'number'. var b2: (x: T) => string[]; a2 = b2; // ok b2 = a2; // ok + ~~ +!!! error TS2322: Type '(x: number) => string[]' is not assignable to type '(x: T) => string[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'number'. var b3: (x: T) => T; a3 = b3; // ok b3 = a3; // ok + ~~ +!!! error TS2322: Type '(x: number) => void' is not assignable to type '(x: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'number'. var b4: (x: T, y: U) => T; a4 = b4; // ok b4 = a4; // ok + ~~ +!!! error TS2322: Type '(x: string, y: number) => string' is not assignable to type '(x: T, y: U) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'string'. var b5: (x: (arg: T) => U) => T; a5 = b5; // ok b5 = a5; // ok + ~~ +!!! error TS2322: Type '(x: (arg: string) => number) => string' is not assignable to type '(x: (arg: T) => U) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type 'T'. var b6: (x: (arg: T) => U) => T; a6 = b6; // ok b6 = a6; // ok + ~~ +!!! error TS2322: Type '(x: (arg: Base) => Derived) => Base' is not assignable to type '(x: (arg: T) => U) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b7: (x: (arg: T) => U) => (r: T) => U; a7 = b7; // ok b7 = a7; // ok + ~~ +!!! error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type '(x: (arg: T) => U) => (r: T) => U'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b8: (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U; a8 = b8; // ok b8 = a8; // ok + ~~ +!!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b9: (x: (arg: T) => U, y: (arg2: { foo: string; bing: number }) => U) => (r: T) => U; a9 = b9; // ok b9 = a9; // ok ~~ !!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'. -!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. -!!! error TS2322: Types of parameters 'arg2' and 'arg2' are incompatible. -!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; bing: number; }'. -!!! error TS2322: Property 'bing' is missing in type 'Base'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b10: (...x: T[]) => T; a10 = b10; // ok b10 = a10; // ok + ~~~ +!!! error TS2322: Type '(...x: Derived[]) => Derived' is not assignable to type '(...x: T[]) => T'. +!!! error TS2322: Type 'Derived' is not assignable to type 'T'. var b11: (x: T, y: T) => T; a11 = b11; // ok b11 = a11; // ok + ~~~ +!!! error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '(x: T, y: T) => T'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type '{ foo: string; bar: string; }'. +!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; bar: string; }'. +!!! error TS2322: Property 'bar' is missing in type 'Base'. var b12: >(x: Array, y: T) => Array; a12 = b12; // ok b12 = a12; // ok + ~~~ +!!! error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '(x: Base[], y: T) => Derived[]'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'. +!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. +!!! error TS2322: Property 'baz' is missing in type 'Base'. var b13: >(x: Array, y: T) => T; a13 = b13; // ok b13 = a13; // ok + ~~~ +!!! error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '(x: Base[], y: T) => T'. +!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'. var b14: (x: { a: T; b: T }) => T; a14 = b14; // ok b14 = a14; // ok + ~~~ +!!! error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '(x: { a: T; b: T; }) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'string'. var b15: (x: T) => T[]; a15 = b15; // ok b15 = a15; // ok diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt index df391b27f98..39d3a2a3593 100644 --- a/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithCallSignatures4.errors.txt @@ -1,3 +1,10 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(45,9): error TS2322: Type '(x: number) => string[]' is not assignable to type '(x: T) => U[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(49,9): error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type '(x: (arg: T) => U) => (r: T) => V'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(52,9): error TS2322: Type '(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U' is not assignable to type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived'. Types of parameters 'y' and 'y' are incompatible. Types of parameters 'arg2' and 'arg2' are incompatible. @@ -5,14 +12,49 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Types of property 'foo' are incompatible. Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(53,9): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'. - Types of parameters 'y' and 'y' are incompatible. - Types of parameters 'arg2' and 'arg2' are incompatible. - Type 'Base' is not assignable to type '{ foo: number; }'. - Types of property 'foo' are incompatible. - Type 'string' is not assignable to type 'number'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(58,9): error TS2322: Type '(...x: Base[]) => Base' is not assignable to type '(...x: T[]) => T'. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(62,9): error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '(x: T, y: T) => T'. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(66,9): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '(x: Base[], y: Base[]) => T'. + Type 'Derived[]' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(69,9): error TS2322: Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(70,9): error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '(x: { a: T; b: T; }) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(73,9): error TS2322: Type '(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(74,9): error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '(x: { a: T; b: T; }) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'string'. + Type 'Base' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(89,9): error TS2322: Type '(x: T) => string[]' is not assignable to type '(x: T) => T[]'. + Type 'string[]' is not assignable to type 'T[]'. + Type 'string' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(90,9): error TS2322: Type '(x: T) => T[]' is not assignable to type '(x: T) => string[]'. + Type 'T[]' is not assignable to type 'string[]'. + Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(95,9): error TS2322: Type '(x: T) => T[]' is not assignable to type '(x: T) => string[]'. + Type 'T[]' is not assignable to type 'string[]'. + Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(96,9): error TS2322: Type '(x: T) => string[]' is not assignable to type '(x: T) => T[]'. + Type 'string[]' is not assignable to type 'T[]'. + Type 'string' is not assignable to type 'T'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts (2 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts (15 errors) ==== // These are mostly permitted with the current loose rules. All ok unless otherwise noted. module Errors { @@ -58,10 +100,19 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var b2: (x: T) => U[]; a2 = b2; b2 = a2; + ~~ +!!! error TS2322: Type '(x: number) => string[]' is not assignable to type '(x: T) => U[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'number'. var b7: (x: (arg: T) => U) => (r: T) => V; a7 = b7; b7 = a7; + ~~ +!!! error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type '(x: (arg: T) => U) => (r: T) => V'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b8: (x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U; a8 = b8; // error, { foo: number } and Base are incompatible @@ -75,32 +126,62 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b8 = a8; // error, { foo: number } and Base are incompatible ~~ !!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'. -!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. -!!! error TS2322: Types of parameters 'arg2' and 'arg2' are incompatible. -!!! error TS2322: Type 'Base' is not assignable to type '{ foo: number; }'. -!!! error TS2322: Types of property 'foo' are incompatible. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b10: (...x: T[]) => T; a10 = b10; b10 = a10; + ~~~ +!!! error TS2322: Type '(...x: Base[]) => Base' is not assignable to type '(...x: T[]) => T'. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b11: (x: T, y: T) => T; a11 = b11; b11 = a11; + ~~~ +!!! error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '(x: T, y: T) => T'. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b12: >(x: Array, y: Array) => T; a12 = b12; b12 = a12; + ~~~ +!!! error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '(x: Base[], y: Base[]) => T'. +!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'. var b15: (x: { a: T; b: T }) => T; a15 = b15; + ~~~ +!!! error TS2322: Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. b15 = a15; + ~~~ +!!! error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '(x: { a: T; b: T; }) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'string'. var b15a: (x: { a: T; b: T }) => number; a15 = b15a; + ~~~ +!!! error TS2322: Type '(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type 'Base'. b15a = a15; + ~~~~ +!!! error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '(x: { a: T; b: T; }) => number'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'string'. +!!! error TS2322: Type 'Base' is not assignable to type 'string'. var b16: (x: (a: T) => T) => T[]; a16 = b16; @@ -116,12 +197,28 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var a2: (x: T) => T[]; var b2: (x: T) => string[]; a2 = b2; + ~~ +!!! error TS2322: Type '(x: T) => string[]' is not assignable to type '(x: T) => T[]'. +!!! error TS2322: Type 'string[]' is not assignable to type 'T[]'. +!!! error TS2322: Type 'string' is not assignable to type 'T'. b2 = a2; + ~~ +!!! error TS2322: Type '(x: T) => T[]' is not assignable to type '(x: T) => string[]'. +!!! error TS2322: Type 'T[]' is not assignable to type 'string[]'. +!!! error TS2322: Type 'T' is not assignable to type 'string'. // target type has generic call signature var a3: (x: T) => string[]; var b3: (x: T) => T[]; a3 = b3; + ~~ +!!! error TS2322: Type '(x: T) => T[]' is not assignable to type '(x: T) => string[]'. +!!! error TS2322: Type 'T[]' is not assignable to type 'string[]'. +!!! error TS2322: Type 'T' is not assignable to type 'string'. b3 = a3; + ~~ +!!! error TS2322: Type '(x: T) => string[]' is not assignable to type '(x: T) => T[]'. +!!! error TS2322: Type 'string[]' is not assignable to type 'T[]'. +!!! error TS2322: Type 'string' is not assignable to type 'T'. } } \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt new file mode 100644 index 00000000000..ba8f5304aa2 --- /dev/null +++ b/tests/baselines/reference/assignmentCompatWithCallSignatures5.errors.txt @@ -0,0 +1,93 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(40,1): error TS2322: Type '(x: T) => void' is not assignable to type '(x: T) => T'. + Type 'void' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(55,1): error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: U; b: V; }) => U[]'. + Type '(U | V)[]' is not assignable to type 'U[]'. + Type 'U | V' is not assignable to type 'U'. + Type 'V' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(58,1): error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: U; b: V; }) => U[]'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'. + Types of property 'a' are incompatible. + Type 'U' is not assignable to type 'Base'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts (3 errors) ==== + // checking assignment compat for function types. No errors in this file + + class Base { foo: string; } + class Derived extends Base { bar: string; } + class Derived2 extends Derived { baz: string; } + class OtherDerived extends Base { bing: string; } + + var a: (x: T) => T[]; + var a2: (x: T) => string[]; + var a3: (x: T) => void; + var a4: (x: T, y: U) => string; + var a5: (x: (arg: T) => U) => T; + var a6: (x: (arg: T) => Derived) => T; + var a11: (x: { foo: T }, y: { foo: T; bar: T }) => Base; + var a15: (x: { a: T; b: T }) => T[]; + var a16: (x: { a: T; b: T }) => T[]; + var a17: { + (x: (a: T) => T): T[]; + (x: (a: T) => T): T[]; + }; + var a18: { + (x: { + (a: T): T; + (a: T): T; + }): any[]; + (x: { + (a: T): T; + (a: T): T; + }): any[]; + }; + + var b: (x: T) => T[]; + a = b; // ok + b = a; // ok + var b2: (x: T) => string[]; + a2 = b2; // ok + b2 = a2; // ok + var b3: (x: T) => T; + a3 = b3; // ok + b3 = a3; // ok + ~~ +!!! error TS2322: Type '(x: T) => void' is not assignable to type '(x: T) => T'. +!!! error TS2322: Type 'void' is not assignable to type 'T'. + var b4: (x: T, y: U) => string; + a4 = b4; // ok + b4 = a4; // ok + var b5: (x: (arg: T) => U) => T; + a5 = b5; // ok + b5 = a5; // ok + var b6: (x: (arg: T) => U) => T; + a6 = b6; // ok + b6 = a6; // ok + var b11: (x: { foo: T }, y: { foo: U; bar: U }) => Base; + a11 = b11; // ok + b11 = a11; // ok + var b15: (x: { a: U; b: V; }) => U[]; + a15 = b15; // ok, T = U, T = V + b15 = a15; // ok + ~~~ +!!! error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: U; b: V; }) => U[]'. +!!! error TS2322: Type '(U | V)[]' is not assignable to type 'U[]'. +!!! error TS2322: Type 'U | V' is not assignable to type 'U'. +!!! error TS2322: Type 'V' is not assignable to type 'U'. + var b16: (x: { a: T; b: T }) => T[]; + a15 = b16; // ok + b15 = a16; // ok + ~~~ +!!! error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: U; b: V; }) => U[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type 'Base'. + var b17: (x: (a: T) => T) => T[]; + a17 = b17; // ok + b17 = a17; // ok + var b18: (x: (a: T) => T) => any[]; + a18 = b18; // ok + b18 = a18; // ok + \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt b/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt new file mode 100644 index 00000000000..b8399a1855b --- /dev/null +++ b/tests/baselines/reference/assignmentCompatWithCallSignatures6.errors.txt @@ -0,0 +1,61 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(30,1): error TS2322: Type '(x: T) => void' is not assignable to type '(x: T) => T'. + Type 'void' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(42,1): error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: T; b: T; }) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'Base'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts (2 errors) ==== + // checking assignment compatibility relations for function types. All valid + + class Base { foo: string; } + class Derived extends Base { bar: string; } + class Derived2 extends Derived { baz: string; } + class OtherDerived extends Base { bing: string; } + + interface A { + a: (x: T) => T[]; + a2: (x: T) => string[]; + a3: (x: T) => void; + a4: (x: T, y: U) => string; + a5: (x: (arg: T) => U) => T; + a6: (x: (arg: T) => Derived) => T; + a11: (x: { foo: T }, y: { foo: T; bar: T }) => Base; + a15: (x: { a: T; b: T }) => T[]; + a16: (x: { a: T; b: T }) => T[]; + } + + var x: A; + + var b: (x: T) => T[]; + x.a = b; + b = x.a; + var b2: (x: T) => string[]; + x.a2 = b2; + b2 = x.a2; + var b3: (x: T) => T; + x.a3 = b3; + b3 = x.a3; + ~~ +!!! error TS2322: Type '(x: T) => void' is not assignable to type '(x: T) => T'. +!!! error TS2322: Type 'void' is not assignable to type 'T'. + var b4: (x: T, y: U) => string; + x.a4 = b4; + b4 = x.a4; + var b5: (x: (arg: T) => U) => T; + x.a5 = b5; + b5 = x.a5; + var b11: (x: { foo: T }, y: { foo: U; bar: U }) => Base; + x.a11 = b11; + b11 = x.a11; + var b16: (x: { a: T; b: T }) => T[]; + x.a16 = b16; + b16 = x.a16; + ~~~ +!!! error TS2322: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: T; b: T; }) => T[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'Base'. \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt index 995a9b67ccd..f9a5be732c9 100644 --- a/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures3.errors.txt @@ -1,11 +1,58 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(47,1): error TS2322: Type 'new (x: number) => number[]' is not assignable to type 'new (x: T) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(50,1): error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new (x: T) => string[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(53,1): error TS2322: Type 'new (x: number) => void' is not assignable to type 'new (x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(56,1): error TS2322: Type 'new (x: string, y: number) => string' is not assignable to type 'new (x: T, y: U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(59,1): error TS2322: Type 'new (x: (arg: string) => number) => string' is not assignable to type 'new (x: (arg: T) => U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'string' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(62,1): error TS2322: Type 'new (x: (arg: Base) => Derived) => Base' is not assignable to type 'new (x: (arg: T) => U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(65,1): error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new (x: (arg: T) => U) => (r: T) => U'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(68,1): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(71,1): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new (x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(74,1): error TS2322: Type 'new (...x: Derived[]) => Derived' is not assignable to type 'new (...x: T[]) => T'. + Type 'Derived' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(77,1): error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new (x: T, y: T) => T'. Types of parameters 'y' and 'y' are incompatible. - Types of parameters 'arg2' and 'arg2' are incompatible. - Type 'Base' is not assignable to type '{ foo: string; bing: number; }'. - Property 'bing' is missing in type 'Base'. + Type 'T' is not assignable to type '{ foo: string; bar: string; }'. + Type 'Base' is not assignable to type '{ foo: string; bar: string; }'. + Property 'bar' is missing in type 'Base'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(80,1): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new (x: Base[], y: T) => Derived[]'. + Types of parameters 'y' and 'y' are incompatible. + Type 'T' is not assignable to type 'Derived2[]'. + Type 'Base[]' is not assignable to type 'Derived2[]'. + Type 'Base' is not assignable to type 'Derived2'. + Property 'baz' is missing in type 'Base'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(83,1): error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new (x: Base[], y: T) => T'. + Type 'Derived[]' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new (x: { a: T; b: T; }) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'string'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (1 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (14 errors) ==== // checking assignment compatibility relations for function types. All of these are valid. class Base { foo: string; } @@ -53,51 +100,111 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var b: new (x: T) => T[]; a = b; // ok b = a; // ok + ~ +!!! error TS2322: Type 'new (x: number) => number[]' is not assignable to type 'new (x: T) => T[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'number'. var b2: new (x: T) => string[]; a2 = b2; // ok b2 = a2; // ok + ~~ +!!! error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new (x: T) => string[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'number'. var b3: new (x: T) => T; a3 = b3; // ok b3 = a3; // ok + ~~ +!!! error TS2322: Type 'new (x: number) => void' is not assignable to type 'new (x: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'number'. var b4: new (x: T, y: U) => T; a4 = b4; // ok b4 = a4; // ok + ~~ +!!! error TS2322: Type 'new (x: string, y: number) => string' is not assignable to type 'new (x: T, y: U) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'string'. var b5: new (x: (arg: T) => U) => T; a5 = b5; // ok b5 = a5; // ok + ~~ +!!! error TS2322: Type 'new (x: (arg: string) => number) => string' is not assignable to type 'new (x: (arg: T) => U) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type 'T'. var b6: new (x: (arg: T) => U) => T; a6 = b6; // ok b6 = a6; // ok + ~~ +!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => Base' is not assignable to type 'new (x: (arg: T) => U) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b7: new (x: (arg: T) => U) => (r: T) => U; a7 = b7; // ok b7 = a7; // ok + ~~ +!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new (x: (arg: T) => U) => (r: T) => U'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b8: new (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U; a8 = b8; // ok b8 = a8; // ok + ~~ +!!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b9: new (x: (arg: T) => U, y: (arg2: { foo: string; bing: number }) => U) => (r: T) => U; a9 = b9; // ok b9 = a9; // ok ~~ !!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new (x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'. -!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. -!!! error TS2322: Types of parameters 'arg2' and 'arg2' are incompatible. -!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; bing: number; }'. -!!! error TS2322: Property 'bing' is missing in type 'Base'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b10: new (...x: T[]) => T; a10 = b10; // ok b10 = a10; // ok + ~~~ +!!! error TS2322: Type 'new (...x: Derived[]) => Derived' is not assignable to type 'new (...x: T[]) => T'. +!!! error TS2322: Type 'Derived' is not assignable to type 'T'. var b11: new (x: T, y: T) => T; a11 = b11; // ok b11 = a11; // ok + ~~~ +!!! error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new (x: T, y: T) => T'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type '{ foo: string; bar: string; }'. +!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; bar: string; }'. +!!! error TS2322: Property 'bar' is missing in type 'Base'. var b12: new >(x: Array, y: T) => Array; a12 = b12; // ok b12 = a12; // ok + ~~~ +!!! error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new (x: Base[], y: T) => Derived[]'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'. +!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'. +!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. +!!! error TS2322: Property 'baz' is missing in type 'Base'. var b13: new >(x: Array, y: T) => T; a13 = b13; // ok b13 = a13; // ok + ~~~ +!!! error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new (x: Base[], y: T) => T'. +!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'. var b14: new (x: { a: T; b: T }) => T; a14 = b14; // ok b14 = a14; // ok + ~~~ +!!! error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new (x: { a: T; b: T; }) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'string'. var b15: new (x: T) => T[]; a15 = b15; // ok b15 = a15; // ok diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt index 6b2f4a0de17..8679b1d85f1 100644 --- a/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures4.errors.txt @@ -1,3 +1,10 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(45,9): error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new (x: T) => U[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(49,9): error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type 'new (x: (arg: T) => U) => (r: T) => V'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(52,9): error TS2322: Type 'new (x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U' is not assignable to type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived'. Types of parameters 'y' and 'y' are incompatible. Types of parameters 'arg2' and 'arg2' are incompatible. @@ -5,11 +12,34 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Types of property 'foo' are incompatible. Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(53,9): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new (x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'. - Types of parameters 'y' and 'y' are incompatible. - Types of parameters 'arg2' and 'arg2' are incompatible. - Type 'Base' is not assignable to type '{ foo: number; }'. - Types of property 'foo' are incompatible. - Type 'string' is not assignable to type 'number'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(58,9): error TS2322: Type 'new (...x: Base[]) => Base' is not assignable to type 'new (...x: T[]) => T'. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(62,9): error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new (x: T, y: T) => T'. + Type 'Base' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(66,9): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new (x: Base[], y: Base[]) => T'. + Type 'Derived[]' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(69,9): error TS2322: Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(70,9): error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new (x: { a: T; b: T; }) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(73,9): error TS2322: Type 'new (x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(74,9): error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new (x: { a: T; b: T; }) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'string'. + Type 'Base' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(77,9): error TS2322: Type 'new (x: (a: T) => T) => T[]' is not assignable to type '{ new (x: { new (a: number): number; new (a?: number): number; }): number[]; new (x: { new (a: boolean): boolean; new (a?: boolean): boolean; }): boolean[]; }'. Types of parameters 'x' and 'x' are incompatible. Type '{ new (a: number): number; new (a?: number): number; }' is not assignable to type '(a: any) => any'. @@ -26,9 +56,21 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme Types of parameters 'x' and 'x' are incompatible. Type '(a: any) => any' is not assignable to type '{ new (a: T): T; new (a: T): T; }'. Type '(a: any) => any' provides no match for the signature 'new (a: T): T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(89,9): error TS2322: Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => T[]'. + Type 'string[]' is not assignable to type 'T[]'. + Type 'string' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(90,9): error TS2322: Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => string[]'. + Type 'T[]' is not assignable to type 'string[]'. + Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(95,9): error TS2322: Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => string[]'. + Type 'T[]' is not assignable to type 'string[]'. + Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(96,9): error TS2322: Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => T[]'. + Type 'string[]' is not assignable to type 'T[]'. + Type 'string' is not assignable to type 'T'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts (6 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts (19 errors) ==== // checking assignment compatibility relations for function types. module Errors { @@ -74,10 +116,19 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var b2: new (x: T) => U[]; a2 = b2; // ok b2 = a2; // ok + ~~ +!!! error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new (x: T) => U[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'number'. var b7: new (x: (arg: T) => U) => (r: T) => V; a7 = b7; // ok b7 = a7; // ok + ~~ +!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type 'new (x: (arg: T) => U) => (r: T) => V'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b8: new (x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U; a8 = b8; // error, type mismatch @@ -91,32 +142,62 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b8 = a8; // error ~~ !!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new (x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'. -!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. -!!! error TS2322: Types of parameters 'arg2' and 'arg2' are incompatible. -!!! error TS2322: Type 'Base' is not assignable to type '{ foo: number; }'. -!!! error TS2322: Types of property 'foo' are incompatible. -!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b10: new (...x: T[]) => T; a10 = b10; // ok b10 = a10; // ok + ~~~ +!!! error TS2322: Type 'new (...x: Base[]) => Base' is not assignable to type 'new (...x: T[]) => T'. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b11: new (x: T, y: T) => T; a11 = b11; // ok b11 = a11; // ok + ~~~ +!!! error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new (x: T, y: T) => T'. +!!! error TS2322: Type 'Base' is not assignable to type 'T'. var b12: new >(x: Array, y: Array) => T; a12 = b12; // ok b12 = a12; // ok + ~~~ +!!! error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new (x: Base[], y: Base[]) => T'. +!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'. var b15: new (x: { a: T; b: T }) => T; a15 = b15; // ok + ~~~ +!!! error TS2322: Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'. +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. b15 = a15; // ok + ~~~ +!!! error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new (x: { a: T; b: T; }) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'string'. var b15a: new (x: { a: T; b: T }) => number; a15 = b15a; // ok + ~~~ +!!! error TS2322: Type 'new (x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type 'Base'. b15a = a15; // ok + ~~~~ +!!! error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new (x: { a: T; b: T; }) => number'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'string'. +!!! error TS2322: Type 'Base' is not assignable to type 'string'. var b16: new (x: (a: T) => T) => T[]; a16 = b16; // error @@ -152,12 +233,28 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme var a2: new (x: T) => T[]; var b2: new (x: T) => string[]; a2 = b2; // ok + ~~ +!!! error TS2322: Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => T[]'. +!!! error TS2322: Type 'string[]' is not assignable to type 'T[]'. +!!! error TS2322: Type 'string' is not assignable to type 'T'. b2 = a2; // ok + ~~ +!!! error TS2322: Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => string[]'. +!!! error TS2322: Type 'T[]' is not assignable to type 'string[]'. +!!! error TS2322: Type 'T' is not assignable to type 'string'. // target type has generic call signature var a3: new (x: T) => string[]; var b3: new (x: T) => T[]; a3 = b3; // ok + ~~ +!!! error TS2322: Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => string[]'. +!!! error TS2322: Type 'T[]' is not assignable to type 'string[]'. +!!! error TS2322: Type 'T' is not assignable to type 'string'. b3 = a3; // ok + ~~ +!!! error TS2322: Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => T[]'. +!!! error TS2322: Type 'string[]' is not assignable to type 'T[]'. +!!! error TS2322: Type 'string' is not assignable to type 'T'. } } \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt new file mode 100644 index 00000000000..23e0c682fdc --- /dev/null +++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures5.errors.txt @@ -0,0 +1,93 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(40,1): error TS2322: Type 'new (x: T) => void' is not assignable to type 'new (x: T) => T'. + Type 'void' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(55,1): error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: U; b: V; }) => U[]'. + Type '(U | V)[]' is not assignable to type 'U[]'. + Type 'U | V' is not assignable to type 'U'. + Type 'V' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(58,1): error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: U; b: V; }) => U[]'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'. + Types of property 'a' are incompatible. + Type 'U' is not assignable to type 'Base'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts (3 errors) ==== + // checking assignment compat for function types. All valid + + class Base { foo: string; } + class Derived extends Base { bar: string; } + class Derived2 extends Derived { baz: string; } + class OtherDerived extends Base { bing: string; } + + var a: new (x: T) => T[]; + var a2: new (x: T) => string[]; + var a3: new (x: T) => void; + var a4: new (x: T, y: U) => string; + var a5: new (x: new (arg: T) => U) => T; + var a6: new (x: new (arg: T) => Derived) => T; + var a11: new (x: { foo: T }, y: { foo: T; bar: T }) => Base; + var a15: new (x: { a: T; b: T }) => T[]; + var a16: new (x: { a: T; b: T }) => T[]; + var a17: { + new (x: new (a: T) => T): T[]; + new (x: new (a: T) => T): T[]; + }; + var a18: { + new (x: { + new (a: T): T; + new (a: T): T; + }): any[]; + new (x: { + new (a: T): T; + new (a: T): T; + }): any[]; + }; + + var b: new (x: T) => T[]; + a = b; // ok + b = a; // ok + var b2: new (x: T) => string[]; + a2 = b2; // ok + b2 = a2; // ok + var b3: new (x: T) => T; + a3 = b3; // ok + b3 = a3; // ok + ~~ +!!! error TS2322: Type 'new (x: T) => void' is not assignable to type 'new (x: T) => T'. +!!! error TS2322: Type 'void' is not assignable to type 'T'. + var b4: new (x: T, y: U) => string; + a4 = b4; // ok + b4 = a4; // ok + var b5: new (x: new (arg: T) => U) => T; + a5 = b5; // ok + b5 = a5; // ok + var b6: new (x: new (arg: T) => U) => T; + a6 = b6; // ok + b6 = a6; // ok + var b11: new (x: { foo: T }, y: { foo: U; bar: U }) => Base; + a11 = b11; // ok + b11 = a11; // ok + var b15: new (x: { a: U; b: V; }) => U[]; + a15 = b15; // ok + b15 = a15; // ok + ~~~ +!!! error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: U; b: V; }) => U[]'. +!!! error TS2322: Type '(U | V)[]' is not assignable to type 'U[]'. +!!! error TS2322: Type 'U | V' is not assignable to type 'U'. +!!! error TS2322: Type 'V' is not assignable to type 'U'. + var b16: new (x: { a: T; b: T }) => T[]; + a15 = b16; // ok + b15 = a16; // ok + ~~~ +!!! error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: U; b: V; }) => U[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type 'Base'. + var b17: new (x: new (a: T) => T) => T[]; + a17 = b17; // ok + b17 = a17; // ok + var b18: new (x: new (a: T) => T) => any[]; + a18 = b18; // ok + b18 = a18; // ok + \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt b/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt new file mode 100644 index 00000000000..f89db500202 --- /dev/null +++ b/tests/baselines/reference/assignmentCompatWithConstructSignatures6.errors.txt @@ -0,0 +1,61 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(30,1): error TS2322: Type 'new (x: T) => void' is not assignable to type 'new (x: T) => T'. + Type 'void' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(42,1): error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: T; b: T; }) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'Base'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts (2 errors) ==== + // checking assignment compatibility relations for function types. All valid. + + class Base { foo: string; } + class Derived extends Base { bar: string; } + class Derived2 extends Derived { baz: string; } + class OtherDerived extends Base { bing: string; } + + interface A { + a: new (x: T) => T[]; + a2: new (x: T) => string[]; + a3: new (x: T) => void; + a4: new (x: T, y: U) => string; + a5: new (x: (arg: T) => U) => T; + a6: new (x: (arg: T) => Derived) => T; + a11: new (x: { foo: T }, y: { foo: T; bar: T }) => Base; + a15: new (x: { a: T; b: T }) => T[]; + a16: new (x: { a: T; b: T }) => T[]; + } + + var x: A; + + var b: new (x: T) => T[]; + x.a = b; + b = x.a; + var b2: new (x: T) => string[]; + x.a2 = b2; + b2 = x.a2; + var b3: new (x: T) => T; + x.a3 = b3; + b3 = x.a3; + ~~ +!!! error TS2322: Type 'new (x: T) => void' is not assignable to type 'new (x: T) => T'. +!!! error TS2322: Type 'void' is not assignable to type 'T'. + var b4: new (x: T, y: U) => string; + x.a4 = b4; + b4 = x.a4; + var b5: new (x: (arg: T) => U) => T; + x.a5 = b5; + b5 = x.a5; + var b11: new (x: { foo: T }, y: { foo: U; bar: U }) => Base; + x.a11 = b11; + b11 = x.a11; + var b16: new (x: { a: T; b: T }) => T[]; + x.a16 = b16; + b16 = x.a16; + ~~~ +!!! error TS2322: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: T; b: T; }) => T[]'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'. +!!! error TS2322: Types of property 'a' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'Base'. \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt new file mode 100644 index 00000000000..7e39c3305a3 --- /dev/null +++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures2.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts(16,1): error TS2322: Type 'A' is not assignable to type 'B'. + Types of parameters 'y' and 'y' are incompatible. + Type 'S' is not assignable to type 'S[]'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts (1 errors) ==== + // some complex cases of assignment compat of generic signatures. No contextual signature instantiation + + interface A { + (x: T, ...y: T[][]): void + } + + interface B { + (x: S, ...y: S[]): void + } + + var a: A; + var b: B; + + // Both ok + a = b; + b = a; + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type 'S' is not assignable to type 'S[]'. + \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignatures4.errors.txt b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures4.errors.txt new file mode 100644 index 00000000000..a38822b8044 --- /dev/null +++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignatures4.errors.txt @@ -0,0 +1,27 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures4.ts(12,1): error TS2322: Type '>(z: T) => void' is not assignable to type '>>(z: T) => void'. + Types of parameters 'z' and 'z' are incompatible. + Type 'T' is not assignable to type 'I2'. + Type 'I2>' is not assignable to type 'I2'. + Type 'I2' is not assignable to type 'T'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures4.ts (1 errors) ==== + // some complex cases of assignment compat of generic signatures. + + interface I2 { + p: T + } + + var x: >(z: T) => void + var y: >>(z: T) => void + + // These both do not make sense as we would eventually be comparing I2 to I2>, and they are self referencing anyway + x = y + y = x + ~ +!!! error TS2322: Type '>(z: T) => void' is not assignable to type '>>(z: T) => void'. +!!! error TS2322: Types of parameters 'z' and 'z' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'I2'. +!!! error TS2322: Type 'I2>' is not assignable to type 'I2'. +!!! error TS2322: Type 'I2' is not assignable to type 'T'. + \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.errors.txt b/tests/baselines/reference/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.errors.txt index a18da8fd8f7..dbad415c5f8 100644 --- a/tests/baselines/reference/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.errors.txt @@ -1,12 +1,74 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(14,13): error TS2322: Type '(x: T) => any' is not assignable to type '() => T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(23,13): error TS2322: Type '(x: T, y: T) => any' is not assignable to type '(x: T) => T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(63,9): error TS2322: Type '() => T' is not assignable to type '() => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(64,9): error TS2322: Type '(x?: T) => T' is not assignable to type '() => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(65,9): error TS2322: Type '(x: T) => T' is not assignable to type '() => T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(66,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '() => T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(67,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '() => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(69,9): error TS2322: Type '() => T' is not assignable to type '(x?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(70,9): error TS2322: Type '(x?: T) => T' is not assignable to type '(x?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(71,9): error TS2322: Type '(x: T) => T' is not assignable to type '(x?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(72,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '(x?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(73,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '(x?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(75,9): error TS2322: Type '() => T' is not assignable to type '(x: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(76,9): error TS2322: Type '(x?: T) => T' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(77,9): error TS2322: Type '(x: T) => T' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(78,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(79,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(81,9): error TS2322: Type '() => T' is not assignable to type '(x: T, y?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(82,9): error TS2322: Type '(x?: T) => T' is not assignable to type '(x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(83,9): error TS2322: Type '(x: T) => T' is not assignable to type '(x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(84,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '(x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(85,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '(x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(87,9): error TS2322: Type '() => T' is not assignable to type '(x?: T, y?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(88,9): error TS2322: Type '(x?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(89,9): error TS2322: Type '(x: T) => T' is not assignable to type '(x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(90,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(91,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(107,13): error TS2322: Type '(x: T) => any' is not assignable to type '() => T'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(116,13): error TS2322: Type '(x: T, y: T) => any' is not assignable to type '(x: T) => T'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts (6 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts (29 errors) ==== // call signatures in derived types must have the same or fewer optional parameters as the target for assignment module ClassTypeParam { @@ -74,7 +136,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme // all errors b.a = t.a; + ~~~ +!!! error TS2322: Type '() => T' is not assignable to type '() => T'. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a = t.a2; + ~~~ +!!! error TS2322: Type '(x?: T) => T' is not assignable to type '() => T'. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a = t.a3; ~~~ !!! error TS2322: Type '(x: T) => T' is not assignable to type '() => T'. @@ -82,30 +150,109 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme ~~~ !!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '() => T'. b.a = t.a5; + ~~~ +!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '() => T'. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a2 = t.a; + ~~~~ +!!! error TS2322: Type '() => T' is not assignable to type '(x?: T) => T'. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a2 = t.a2; + ~~~~ +!!! error TS2322: Type '(x?: T) => T' is not assignable to type '(x?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a2 = t.a3; + ~~~~ +!!! error TS2322: Type '(x: T) => T' is not assignable to type '(x?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a2 = t.a4; + ~~~~ +!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '(x?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a2 = t.a5; + ~~~~ +!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '(x?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a3 = t.a; + ~~~~ +!!! error TS2322: Type '() => T' is not assignable to type '(x: T) => T'. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a3 = t.a2; + ~~~~ +!!! error TS2322: Type '(x?: T) => T' is not assignable to type '(x: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a3 = t.a3; + ~~~~ +!!! error TS2322: Type '(x: T) => T' is not assignable to type '(x: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a3 = t.a4; + ~~~~ +!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '(x: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a3 = t.a5; + ~~~~ +!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '(x: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a4 = t.a; + ~~~~ +!!! error TS2322: Type '() => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a4 = t.a2; + ~~~~ +!!! error TS2322: Type '(x?: T) => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a4 = t.a3; + ~~~~ +!!! error TS2322: Type '(x: T) => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a4 = t.a4; + ~~~~ +!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a4 = t.a5; + ~~~~ +!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a5 = t.a; + ~~~~ +!!! error TS2322: Type '() => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a5 = t.a2; + ~~~~ +!!! error TS2322: Type '(x?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a5 = t.a3; + ~~~~ +!!! error TS2322: Type '(x: T) => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a5 = t.a4; + ~~~~ +!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. b.a5 = t.a5; + ~~~~ +!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. } } diff --git a/tests/baselines/reference/assignmentStricterConstraints.errors.txt b/tests/baselines/reference/assignmentStricterConstraints.errors.txt new file mode 100644 index 00000000000..c83e2fa3440 --- /dev/null +++ b/tests/baselines/reference/assignmentStricterConstraints.errors.txt @@ -0,0 +1,19 @@ +tests/cases/compiler/assignmentStricterConstraints.ts(7,1): error TS2322: Type '(x: T, y: S) => void' is not assignable to type '(x: T, y: S) => void'. + Types of parameters 'y' and 'y' are incompatible. + Type 'S' is not assignable to type 'T'. + + +==== tests/cases/compiler/assignmentStricterConstraints.ts (1 errors) ==== + var f = function (x: T, y: S): void { + x = y + } + + var g = function (x: T, y: S): void { } + + g = f + ~ +!!! error TS2322: Type '(x: T, y: S) => void' is not assignable to type '(x: T, y: S) => void'. +!!! error TS2322: Types of parameters 'y' and 'y' are incompatible. +!!! error TS2322: Type 'S' is not assignable to type 'T'. + g(1, "") + \ No newline at end of file diff --git a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt index 42940c0e412..027551ae4b8 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt +++ b/tests/baselines/reference/asyncFunctionDeclaration15_es5.errors.txt @@ -4,10 +4,10 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(9,23): error TS1055: Type 'PromiseLike' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. - Type 'Thenable' is not assignable to type 'PromiseLike'. + Type 'Thenable' is not assignable to type 'PromiseLike'. Types of property 'then' are incompatible. - Type '() => void' is not assignable to type '(onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. - Type 'void' is not assignable to type 'PromiseLike'. + Type '() => void' is not assignable to type '(onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. + Type 'void' is not assignable to type 'PromiseLike'. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(17,16): error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member. tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(23,25): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member. @@ -35,10 +35,10 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1 !!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. ~~~~~~~~ !!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value. -!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike'. +!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike'. !!! error TS1055: Types of property 'then' are incompatible. -!!! error TS1055: Type '() => void' is not assignable to type '(onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. -!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike'. +!!! error TS1055: Type '() => void' is not assignable to type '(onfulfilled?: (value: T) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. +!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike'. async function fn7() { return; } // valid: Promise async function fn8() { return 1; } // valid: Promise async function fn9() { return null; } // valid: Promise diff --git a/tests/baselines/reference/awaitLiteralValues.errors.txt b/tests/baselines/reference/awaitLiteralValues.errors.txt new file mode 100644 index 00000000000..cf3e155c280 --- /dev/null +++ b/tests/baselines/reference/awaitLiteralValues.errors.txt @@ -0,0 +1,45 @@ +tests/cases/compiler/awaitLiteralValues.ts(2,5): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitLiteralValues.ts(6,5): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitLiteralValues.ts(10,5): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitLiteralValues.ts(14,5): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitLiteralValues.ts(18,5): error TS1308: 'await' expression is only allowed within an async function. +tests/cases/compiler/awaitLiteralValues.ts(22,5): error TS1308: 'await' expression is only allowed within an async function. + + +==== tests/cases/compiler/awaitLiteralValues.ts (6 errors) ==== + function awaitString() { + await 'literal'; + ~~~~~ +!!! error TS1308: 'await' expression is only allowed within an async function. + } + + function awaitNumber() { + await 1; + ~~~~~ +!!! error TS1308: 'await' expression is only allowed within an async function. + } + + function awaitTrue() { + await true; + ~~~~~ +!!! error TS1308: 'await' expression is only allowed within an async function. + } + + function awaitFalse() { + await false; + ~~~~~ +!!! error TS1308: 'await' expression is only allowed within an async function. + } + + function awaitNull() { + await null; + ~~~~~ +!!! error TS1308: 'await' expression is only allowed within an async function. + } + + function awaitUndefined() { + await undefined; + ~~~~~ +!!! error TS1308: 'await' expression is only allowed within an async function. + } + \ No newline at end of file diff --git a/tests/baselines/reference/awaitLiteralValues.js b/tests/baselines/reference/awaitLiteralValues.js new file mode 100644 index 00000000000..cc5a06a0c19 --- /dev/null +++ b/tests/baselines/reference/awaitLiteralValues.js @@ -0,0 +1,45 @@ +//// [awaitLiteralValues.ts] +function awaitString() { + await 'literal'; +} + +function awaitNumber() { + await 1; +} + +function awaitTrue() { + await true; +} + +function awaitFalse() { + await false; +} + +function awaitNull() { + await null; +} + +function awaitUndefined() { + await undefined; +} + + +//// [awaitLiteralValues.js] +function awaitString() { + yield 'literal'; +} +function awaitNumber() { + yield 1; +} +function awaitTrue() { + yield true; +} +function awaitFalse() { + yield false; +} +function awaitNull() { + yield null; +} +function awaitUndefined() { + yield undefined; +} diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt index d6efdd66868..3d9ecd65e3d 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance.errors.txt @@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign Types of property 'a' are incompatible. Type '(x: number) => string' is not assignable to type '(x: number) => number'. Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts(63,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type '(x: T) => string' is not assignable to type '(x: T) => T'. + Type 'string' is not assignable to type 'T'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts (1 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts (2 errors) ==== module CallSignature { interface Base { // T // M's @@ -73,6 +77,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign // S's interface I3 extends Base2 { + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type '(x: T) => string' is not assignable to type '(x: T) => T'. +!!! error TS2430: Type 'string' is not assignable to type 'T'. // N's a2: (x: T) => string; // error because base returns non-void; } diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt index f5e05567b25..5bf725b06e3 100644 --- a/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance3.errors.txt @@ -11,9 +11,31 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign Type '{ foo: number; }' is not assignable to type 'Base'. Types of property 'foo' are incompatible. Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(76,19): error TS2430: Interface 'I6' incorrectly extends interface 'A'. + Types of property 'a15' are incompatible. + Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(80,19): error TS2430: Interface 'I7' incorrectly extends interface 'A'. + Types of property 'a15' are incompatible. + Type '(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(100,19): error TS2430: Interface 'I6' incorrectly extends interface 'B'. + Types of property 'a2' are incompatible. + Type '(x: T) => string[]' is not assignable to type '(x: T) => T[]'. + Type 'string[]' is not assignable to type 'T[]'. + Type 'string' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(109,19): error TS2430: Interface 'I7' incorrectly extends interface 'C'. + Types of property 'a2' are incompatible. + Type '(x: T) => T[]' is not assignable to type '(x: T) => string[]'. + Type 'T[]' is not assignable to type 'string[]'. + Type 'T' is not assignable to type 'string'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts (2 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts (6 errors) ==== // checking subtype relations for function types as it relates to contextual signature instantiation // error cases @@ -105,10 +127,24 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign } interface I6 extends A { + ~~ +!!! error TS2430: Interface 'I6' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a15' are incompatible. +!!! error TS2430: Type '(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'. +!!! error TS2430: Type 'string | number' is not assignable to type 'number'. +!!! error TS2430: Type 'string' is not assignable to type 'number'. a15: (x: { a: T; b: T }) => T; // error, T is {} which isn't an acceptable return type } interface I7 extends A { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a15' are incompatible. +!!! error TS2430: Type '(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'Base'. a15: (x: { a: T; b: T }) => number; // error, T defaults to Base, which is not compatible with number or string } @@ -129,6 +165,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign } interface I6 extends B { + ~~ +!!! error TS2430: Interface 'I6' incorrectly extends interface 'B'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type '(x: T) => string[]' is not assignable to type '(x: T) => T[]'. +!!! error TS2430: Type 'string[]' is not assignable to type 'T[]'. +!!! error TS2430: Type 'string' is not assignable to type 'T'. a2: (x: T) => string[]; // error } @@ -138,6 +180,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign } interface I7 extends C { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'C'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type '(x: T) => T[]' is not assignable to type '(x: T) => string[]'. +!!! error TS2430: Type 'T[]' is not assignable to type 'string[]'. +!!! error TS2430: Type 'T' is not assignable to type 'string'. a2: (x: T) => T[]; // error } } diff --git a/tests/baselines/reference/callSignatureAssignabilityInInheritance6.errors.txt b/tests/baselines/reference/callSignatureAssignabilityInInheritance6.errors.txt new file mode 100644 index 00000000000..602e40dfcfb --- /dev/null +++ b/tests/baselines/reference/callSignatureAssignabilityInInheritance6.errors.txt @@ -0,0 +1,142 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(24,11): error TS2430: Interface 'I' incorrectly extends interface 'A'. + Types of property 'a' are incompatible. + Type '(x: T) => T[]' is not assignable to type '(x: T) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(28,11): error TS2430: Interface 'I2' incorrectly extends interface 'A'. + Types of property 'a2' are incompatible. + Type '(x: T) => string[]' is not assignable to type '(x: T) => string[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(32,11): error TS2430: Interface 'I3' incorrectly extends interface 'A'. + Types of property 'a3' are incompatible. + Type '(x: T) => T' is not assignable to type '(x: T) => void'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(36,11): error TS2430: Interface 'I4' incorrectly extends interface 'A'. + Types of property 'a4' are incompatible. + Type '(x: T, y: U) => string' is not assignable to type '(x: T, y: U) => string'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(40,11): error TS2430: Interface 'I5' incorrectly extends interface 'A'. + Types of property 'a5' are incompatible. + Type '(x: (arg: T) => U) => T' is not assignable to type '(x: (arg: T) => U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(44,11): error TS2430: Interface 'I7' incorrectly extends interface 'A'. + Types of property 'a11' are incompatible. + Type '(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type '(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated. + Types of property 'foo' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(48,11): error TS2430: Interface 'I9' incorrectly extends interface 'A'. + Types of property 'a16' are incompatible. + Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: T; b: T; }) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + Type 'Base' is not assignable to type 'T'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts (7 errors) ==== + // checking subtype relations for function types as it relates to contextual signature instantiation + // same as subtypingWithCallSignatures4 but using class type parameters instead of generic signatures + // all are errors + + class Base { foo: string; } + class Derived extends Base { bar: string; } + class Derived2 extends Derived { baz: string; } + class OtherDerived extends Base { bing: string; } + + interface A { // T + // M's + a: (x: T) => T[]; + a2: (x: T) => string[]; + a3: (x: T) => void; + a4: (x: T, y: U) => string; + a5: (x: (arg: T) => U) => T; + a6: (x: (arg: T) => Derived) => T; + a11: (x: { foo: T }, y: { foo: T; bar: T }) => Base; + a15: (x: { a: T; b: T }) => T[]; + a16: (x: { a: T; b: T }) => T[]; + } + + // S's + interface I extends A { + ~ +!!! error TS2430: Interface 'I' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type '(x: T) => T[]' is not assignable to type '(x: T) => T[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a: (x: T) => T[]; + } + + interface I2 extends A { + ~~ +!!! error TS2430: Interface 'I2' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type '(x: T) => string[]' is not assignable to type '(x: T) => string[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a2: (x: T) => string[]; + } + + interface I3 extends A { + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type '(x: T) => T' is not assignable to type '(x: T) => void'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a3: (x: T) => T; + } + + interface I4 extends A { + ~~ +!!! error TS2430: Interface 'I4' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type '(x: T, y: U) => string' is not assignable to type '(x: T, y: U) => string'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a4: (x: T, y: U) => string; + } + + interface I5 extends A { + ~~ +!!! error TS2430: Interface 'I5' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type '(x: (arg: T) => U) => T' is not assignable to type '(x: (arg: T) => U) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a5: (x: (arg: T) => U) => T; + } + + interface I7 extends A { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a11' are incompatible. +!!! error TS2430: Type '(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type '(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Types of property 'foo' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a11: (x: { foo: T }, y: { foo: U; bar: U }) => Base; + } + + interface I9 extends A { + ~~ +!!! error TS2430: Interface 'I9' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a16' are incompatible. +!!! error TS2430: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '(x: { a: T; b: T; }) => T[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Type 'Base' is not assignable to type 'T'. + a16: (x: { a: T; b: T }) => T[]; + } \ No newline at end of file diff --git a/tests/baselines/reference/checkJsdocReturnTag2.errors.txt b/tests/baselines/reference/checkJsdocReturnTag2.errors.txt new file mode 100644 index 00000000000..23a450c83ca --- /dev/null +++ b/tests/baselines/reference/checkJsdocReturnTag2.errors.txt @@ -0,0 +1,25 @@ +tests/cases/conformance/jsdoc/returns.js(6,5): error TS2322: Type '5' is not assignable to type 'string'. +tests/cases/conformance/jsdoc/returns.js(13,5): error TS2322: Type 'true | 5' is not assignable to type 'string | number'. + Type 'true' is not assignable to type 'string | number'. + + +==== tests/cases/conformance/jsdoc/returns.js (2 errors) ==== + // @ts-check + /** + * @returns {string} This comment is not currently exposed + */ + function f() { + return 5; + ~~~~~~~~~ +!!! error TS2322: Type '5' is not assignable to type 'string'. + } + + /** + * @returns {string | number} This comment is not currently exposed + */ + function f1() { + return 5 || true; + ~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type 'true | 5' is not assignable to type 'string | number'. +!!! error TS2322: Type 'true' is not assignable to type 'string | number'. + } \ No newline at end of file diff --git a/tests/baselines/reference/checkJsdocTypeTag1.types b/tests/baselines/reference/checkJsdocTypeTag1.types index 9368640edcb..898cf58806a 100644 --- a/tests/baselines/reference/checkJsdocTypeTag1.types +++ b/tests/baselines/reference/checkJsdocTypeTag1.types @@ -61,10 +61,10 @@ x(1); /** @type {function (number)} */ const x1 = (a) => a + 1; >x1 : (arg0: number) => any ->(a) => a + 1 : (a: any) => any ->a : any ->a + 1 : any ->a : any +>(a) => a + 1 : (a: number) => number +>a : number +>a + 1 : number +>a : number >1 : 1 x1(0); @@ -75,10 +75,10 @@ x1(0); /** @type {function (number): number} */ const x2 = (a) => a + 1; >x2 : (arg0: number) => number ->(a) => a + 1 : (a: any) => any ->a : any ->a + 1 : any ->a : any +>(a) => a + 1 : (a: number) => number +>a : number +>a + 1 : number +>a : number >1 : 1 x2(0); diff --git a/tests/baselines/reference/checkJsdocTypeTag2.errors.txt b/tests/baselines/reference/checkJsdocTypeTag2.errors.txt index ca02c578a36..3590c10e278 100644 --- a/tests/baselines/reference/checkJsdocTypeTag2.errors.txt +++ b/tests/baselines/reference/checkJsdocTypeTag2.errors.txt @@ -1,9 +1,10 @@ tests/cases/conformance/jsdoc/0.js(3,5): error TS2322: Type 'true' is not assignable to type 'string'. tests/cases/conformance/jsdoc/0.js(6,5): error TS2322: Type '"hello"' is not assignable to type 'number'. tests/cases/conformance/jsdoc/0.js(10,4): error TS2345: Argument of type '"string"' is not assignable to parameter of type 'number'. -tests/cases/conformance/jsdoc/0.js(13,7): error TS2451: Cannot redeclare block-scoped variable 'x2'. tests/cases/conformance/jsdoc/0.js(17,1): error TS2322: Type 'number' is not assignable to type 'string'. -tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-scoped variable 'x2'. +tests/cases/conformance/jsdoc/0.js(20,21): error TS2339: Property 'concat' does not exist on type 'number'. +tests/cases/conformance/jsdoc/0.js(24,7): error TS2322: Type '(a: number) => number' is not assignable to type '(arg0: number) => string'. + Type 'number' is not assignable to type 'string'. ==== tests/cases/conformance/jsdoc/0.js (6 errors) ==== @@ -26,8 +27,6 @@ tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-s /** @type {function (number): number} */ const x2 = (a) => a + 1; - ~~ -!!! error TS2451: Cannot redeclare block-scoped variable 'x2'. /** @type {string} */ var a; @@ -36,7 +35,14 @@ tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-s !!! error TS2322: Type 'number' is not assignable to type 'string'. /** @type {function (number): number} */ - const x2 = (a) => a.concat("hi"); + const x3 = (a) => a.concat("hi"); + ~~~~~~ +!!! error TS2339: Property 'concat' does not exist on type 'number'. + x3(0); + + /** @type {function (number): string} */ + const x4 = (a) => a + 1; ~~ -!!! error TS2451: Cannot redeclare block-scoped variable 'x2'. - x2(0); \ No newline at end of file +!!! error TS2322: Type '(a: number) => number' is not assignable to type '(arg0: number) => string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + x4(0); \ No newline at end of file diff --git a/tests/baselines/reference/checkJsdocTypeTag2.js b/tests/baselines/reference/checkJsdocTypeTag2.js index 23b436e2031..0e550d3ba33 100644 --- a/tests/baselines/reference/checkJsdocTypeTag2.js +++ b/tests/baselines/reference/checkJsdocTypeTag2.js @@ -18,8 +18,12 @@ var a; a = x2(0); /** @type {function (number): number} */ -const x2 = (a) => a.concat("hi"); -x2(0); +const x3 = (a) => a.concat("hi"); +x3(0); + +/** @type {function (number): string} */ +const x4 = (a) => a + 1; +x4(0); //// [0.js] // @ts-check @@ -36,5 +40,8 @@ var x2 = function (a) { return a + 1; }; var a; a = x2(0); /** @type {function (number): number} */ -var x2 = function (a) { return a.concat("hi"); }; -x2(0); +var x3 = function (a) { return a.concat("hi"); }; +x3(0); +/** @type {function (number): string} */ +var x4 = function (a) { return a + 1; }; +x4(0); diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt index 51278fc3f44..cc2c1e871e5 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance.errors.txt @@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc Types of property 'a' are incompatible. Type 'new (x: number) => string' is not assignable to type 'new (x: number) => number'. Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts(67,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type 'new (x: T) => string' is not assignable to type 'new (x: T) => T'. + Type 'string' is not assignable to type 'T'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts (1 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts (2 errors) ==== // Checking basic subtype relations with construct signatures module ConstructSignature { @@ -77,6 +81,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc // S's interface I3 extends Base2 { + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new (x: T) => string' is not assignable to type 'new (x: T) => T'. +!!! error TS2430: Type 'string' is not assignable to type 'T'. // N's a2: new (x: T) => string; // error because base returns non-void; } diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt index 7bd76159391..9646acd071f 100644 --- a/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance3.errors.txt @@ -11,9 +11,31 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc Type '{ foo: number; }' is not assignable to type 'Base'. Types of property 'foo' are incompatible. Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(66,19): error TS2430: Interface 'I6' incorrectly extends interface 'A'. + Types of property 'a15' are incompatible. + Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'. + Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(70,19): error TS2430: Interface 'I7' incorrectly extends interface 'A'. + Types of property 'a15' are incompatible. + Type 'new (x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'Base'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(86,19): error TS2430: Interface 'I6' incorrectly extends interface 'B'. + Types of property 'a2' are incompatible. + Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => T[]'. + Type 'string[]' is not assignable to type 'T[]'. + Type 'string' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(95,19): error TS2430: Interface 'I7' incorrectly extends interface 'C'. + Types of property 'a2' are incompatible. + Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => string[]'. + Type 'T[]' is not assignable to type 'string[]'. + Type 'T' is not assignable to type 'string'. -==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts (2 errors) ==== +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts (6 errors) ==== // checking subtype relations for function types as it relates to contextual signature instantiation // error cases @@ -95,10 +117,24 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc } interface I6 extends A { + ~~ +!!! error TS2430: Interface 'I6' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a15' are incompatible. +!!! error TS2430: Type 'new (x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'. +!!! error TS2430: Type 'string | number' is not assignable to type 'number'. +!!! error TS2430: Type 'string' is not assignable to type 'number'. a15: new (x: { a: T; b: T }) => T; // error, T is {} which isn't an acceptable return type } interface I7 extends A { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a15' are incompatible. +!!! error TS2430: Type 'new (x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'Base'. a15: new (x: { a: T; b: T }) => number; // error, T defaults to Base, which is not compatible with number or string } @@ -115,6 +151,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc } interface I6 extends B { + ~~ +!!! error TS2430: Interface 'I6' incorrectly extends interface 'B'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => T[]'. +!!! error TS2430: Type 'string[]' is not assignable to type 'T[]'. +!!! error TS2430: Type 'string' is not assignable to type 'T'. a2: new (x: T) => string[]; // error } @@ -124,6 +166,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc } interface I7 extends C { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'C'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => string[]'. +!!! error TS2430: Type 'T[]' is not assignable to type 'string[]'. +!!! error TS2430: Type 'T' is not assignable to type 'string'. a2: new (x: T) => T[]; // error } diff --git a/tests/baselines/reference/constructSignatureAssignabilityInInheritance6.errors.txt b/tests/baselines/reference/constructSignatureAssignabilityInInheritance6.errors.txt new file mode 100644 index 00000000000..6245fead919 --- /dev/null +++ b/tests/baselines/reference/constructSignatureAssignabilityInInheritance6.errors.txt @@ -0,0 +1,142 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(24,11): error TS2430: Interface 'I' incorrectly extends interface 'A'. + Types of property 'a' are incompatible. + Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(28,11): error TS2430: Interface 'I2' incorrectly extends interface 'A'. + Types of property 'a2' are incompatible. + Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => string[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(32,11): error TS2430: Interface 'I3' incorrectly extends interface 'A'. + Types of property 'a3' are incompatible. + Type 'new (x: T) => T' is not assignable to type 'new (x: T) => void'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(36,11): error TS2430: Interface 'I4' incorrectly extends interface 'A'. + Types of property 'a4' are incompatible. + Type 'new (x: T, y: U) => string' is not assignable to type 'new (x: T, y: U) => string'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(40,11): error TS2430: Interface 'I5' incorrectly extends interface 'A'. + Types of property 'a5' are incompatible. + Type 'new (x: (arg: T) => U) => T' is not assignable to type 'new (x: (arg: T) => U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(44,11): error TS2430: Interface 'I7' incorrectly extends interface 'A'. + Types of property 'a11' are incompatible. + Type 'new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated. + Types of property 'foo' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(48,11): error TS2430: Interface 'I9' incorrectly extends interface 'A'. + Types of property 'a16' are incompatible. + Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: T; b: T; }) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + Type 'Base' is not assignable to type 'T'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts (7 errors) ==== + // checking subtype relations for function types as it relates to contextual signature instantiation + // same as subtypingWithConstructSignatures4 but using class type parameters instead of generic signatures + // all are errors + + class Base { foo: string; } + class Derived extends Base { bar: string; } + class Derived2 extends Derived { baz: string; } + class OtherDerived extends Base { bing: string; } + + interface A { // T + // M's + a: new (x: T) => T[]; + a2: new (x: T) => string[]; + a3: new (x: T) => void; + a4: new (x: T, y: U) => string; + a5: new (x: (arg: T) => U) => T; + a6: new (x: (arg: T) => Derived) => T; + a11: new (x: { foo: T }, y: { foo: T; bar: T }) => Base; + a15: new (x: { a: T; b: T }) => T[]; + a16: new (x: { a: T; b: T }) => T[]; + } + + // S's + interface I extends A { + ~ +!!! error TS2430: Interface 'I' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => T[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a: new (x: T) => T[]; + } + + interface I2 extends A { + ~~ +!!! error TS2430: Interface 'I2' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => string[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a2: new (x: T) => string[]; + } + + interface I3 extends A { + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type 'new (x: T) => T' is not assignable to type 'new (x: T) => void'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a3: new (x: T) => T; + } + + interface I4 extends A { + ~~ +!!! error TS2430: Interface 'I4' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type 'new (x: T, y: U) => string' is not assignable to type 'new (x: T, y: U) => string'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a4: new (x: T, y: U) => string; + } + + interface I5 extends A { + ~~ +!!! error TS2430: Interface 'I5' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type 'new (x: (arg: T) => U) => T' is not assignable to type 'new (x: (arg: T) => U) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a5: new (x: (arg: T) => U) => T; + } + + interface I7 extends A { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a11' are incompatible. +!!! error TS2430: Type 'new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Types of property 'foo' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a11: new (x: { foo: T }, y: { foo: U; bar: U }) => Base; + } + + interface I9 extends A { + ~~ +!!! error TS2430: Interface 'I9' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a16' are incompatible. +!!! error TS2430: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: T; b: T; }) => T[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Type 'Base' is not assignable to type 'T'. + a16: new (x: { a: T; b: T }) => T[]; + } \ No newline at end of file diff --git a/tests/baselines/reference/constructorFunctions.symbols b/tests/baselines/reference/constructorFunctions.symbols new file mode 100644 index 00000000000..f55075794ab --- /dev/null +++ b/tests/baselines/reference/constructorFunctions.symbols @@ -0,0 +1,76 @@ +=== tests/cases/conformance/salsa/index.js === +function C1() { +>C1 : Symbol(C1, Decl(index.js, 0, 0)) + + if (!(this instanceof C1)) return new C1(); +>C1 : Symbol(C1, Decl(index.js, 0, 0)) +>C1 : Symbol(C1, Decl(index.js, 0, 0)) + + this.x = 1; +>x : Symbol(C1.x, Decl(index.js, 1, 47)) +} + +const c1_v1 = C1(); +>c1_v1 : Symbol(c1_v1, Decl(index.js, 5, 5)) +>C1 : Symbol(C1, Decl(index.js, 0, 0)) + +const c1_v2 = new C1(); +>c1_v2 : Symbol(c1_v2, Decl(index.js, 6, 5)) +>C1 : Symbol(C1, Decl(index.js, 0, 0)) + +var C2 = function () { +>C2 : Symbol(C2, Decl(index.js, 8, 3)) + + if (!(this instanceof C2)) return new C2(); +>C2 : Symbol(C2, Decl(index.js, 8, 3)) +>C2 : Symbol(C2, Decl(index.js, 8, 3)) + + this.x = 1; +>x : Symbol(C2.x, Decl(index.js, 9, 47)) + +}; + +const c2_v1 = C2(); +>c2_v1 : Symbol(c2_v1, Decl(index.js, 13, 5)) +>C2 : Symbol(C2, Decl(index.js, 8, 3)) + +const c2_v2 = new C2(); +>c2_v2 : Symbol(c2_v2, Decl(index.js, 14, 5)) +>C2 : Symbol(C2, Decl(index.js, 8, 3)) + +/** @class */ +function C3() { +>C3 : Symbol(C3, Decl(index.js, 14, 23)) + + if (!(this instanceof C3)) return new C3(); +>C3 : Symbol(C3, Decl(index.js, 14, 23)) +>C3 : Symbol(C3, Decl(index.js, 14, 23)) + +}; + +const c3_v1 = C3(); +>c3_v1 : Symbol(c3_v1, Decl(index.js, 21, 5)) +>C3 : Symbol(C3, Decl(index.js, 14, 23)) + +const c3_v2 = new C3(); +>c3_v2 : Symbol(c3_v2, Decl(index.js, 22, 5)) +>C3 : Symbol(C3, Decl(index.js, 14, 23)) + +/** @class */ +var C4 = function () { +>C4 : Symbol(C4, Decl(index.js, 25, 3)) + + if (!(this instanceof C4)) return new C4(); +>C4 : Symbol(C4, Decl(index.js, 25, 3)) +>C4 : Symbol(C4, Decl(index.js, 25, 3)) + +}; + +const c4_v1 = C4(); +>c4_v1 : Symbol(c4_v1, Decl(index.js, 29, 5)) +>C4 : Symbol(C4, Decl(index.js, 25, 3)) + +const c4_v2 = new C4(); +>c4_v2 : Symbol(c4_v2, Decl(index.js, 30, 5)) +>C4 : Symbol(C4, Decl(index.js, 25, 3)) + diff --git a/tests/baselines/reference/constructorFunctions.types b/tests/baselines/reference/constructorFunctions.types new file mode 100644 index 00000000000..3429758b017 --- /dev/null +++ b/tests/baselines/reference/constructorFunctions.types @@ -0,0 +1,114 @@ +=== tests/cases/conformance/salsa/index.js === +function C1() { +>C1 : () => typeof C1 + + if (!(this instanceof C1)) return new C1(); +>!(this instanceof C1) : boolean +>(this instanceof C1) : boolean +>this instanceof C1 : boolean +>this : any +>C1 : () => typeof C1 +>new C1() : { x: number; } +>C1 : () => typeof C1 + + this.x = 1; +>this.x = 1 : 1 +>this.x : any +>this : any +>x : any +>1 : 1 +} + +const c1_v1 = C1(); +>c1_v1 : { x: number; } +>C1() : { x: number; } +>C1 : () => typeof C1 + +const c1_v2 = new C1(); +>c1_v2 : { x: number; } +>new C1() : { x: number; } +>C1 : () => typeof C1 + +var C2 = function () { +>C2 : () => any +>function () { if (!(this instanceof C2)) return new C2(); this.x = 1;} : () => any + + if (!(this instanceof C2)) return new C2(); +>!(this instanceof C2) : boolean +>(this instanceof C2) : boolean +>this instanceof C2 : boolean +>this : any +>C2 : () => any +>new C2() : { x: number; } +>C2 : () => any + + this.x = 1; +>this.x = 1 : 1 +>this.x : any +>this : any +>x : any +>1 : 1 + +}; + +const c2_v1 = C2(); +>c2_v1 : { x: number; } +>C2() : { x: number; } +>C2 : () => any + +const c2_v2 = new C2(); +>c2_v2 : { x: number; } +>new C2() : { x: number; } +>C2 : () => any + +/** @class */ +function C3() { +>C3 : () => typeof C3 + + if (!(this instanceof C3)) return new C3(); +>!(this instanceof C3) : boolean +>(this instanceof C3) : boolean +>this instanceof C3 : boolean +>this : any +>C3 : () => typeof C3 +>new C3() : {} +>C3 : () => typeof C3 + +}; + +const c3_v1 = C3(); +>c3_v1 : {} +>C3() : {} +>C3 : () => typeof C3 + +const c3_v2 = new C3(); +>c3_v2 : {} +>new C3() : {} +>C3 : () => typeof C3 + +/** @class */ +var C4 = function () { +>C4 : () => any +>function () { if (!(this instanceof C4)) return new C4();} : () => any + + if (!(this instanceof C4)) return new C4(); +>!(this instanceof C4) : boolean +>(this instanceof C4) : boolean +>this instanceof C4 : boolean +>this : any +>C4 : () => any +>new C4() : {} +>C4 : () => any + +}; + +const c4_v1 = C4(); +>c4_v1 : {} +>C4() : {} +>C4 : () => any + +const c4_v2 = new C4(); +>c4_v2 : {} +>new C4() : {} +>C4 : () => any + diff --git a/tests/baselines/reference/contextualTypeFromJSDoc.symbols b/tests/baselines/reference/contextualTypeFromJSDoc.symbols new file mode 100644 index 00000000000..5ebe1e01ca7 --- /dev/null +++ b/tests/baselines/reference/contextualTypeFromJSDoc.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/types/contextualTypes/jsdoc/index.js === +/** @type {Array<[string, {x?:number, y?:number}]>} */ +const arr = [ +>arr : Symbol(arr, Decl(index.js, 1, 5)) + + ['a', { x: 1 }], +>x : Symbol(x, Decl(index.js, 2, 11)) + + ['b', { y: 2 }] +>y : Symbol(y, Decl(index.js, 3, 11)) + +]; + +/** @return {Array<[string, {x?:number, y?:number}]>} */ +function f() { +>f : Symbol(f, Decl(index.js, 4, 2)) + + return [ + ['a', { x: 1 }], +>x : Symbol(x, Decl(index.js, 9, 15)) + + ['b', { y: 2 }] +>y : Symbol(y, Decl(index.js, 10, 15)) + + ]; +} + +class C { +>C : Symbol(C, Decl(index.js, 12, 1)) + + /** @param {Array<[string, {x?:number, y?:number}]>} value */ + set x(value) { } +>x : Symbol(C.x, Decl(index.js, 14, 9), Decl(index.js, 16, 20)) +>value : Symbol(value, Decl(index.js, 16, 10)) + + get x() { +>x : Symbol(C.x, Decl(index.js, 14, 9), Decl(index.js, 16, 20)) + + return [ + ['a', { x: 1 }], +>x : Symbol(x, Decl(index.js, 19, 19)) + + ['b', { y: 2 }] +>y : Symbol(y, Decl(index.js, 20, 19)) + + ]; + } +} diff --git a/tests/baselines/reference/contextualTypeFromJSDoc.types b/tests/baselines/reference/contextualTypeFromJSDoc.types new file mode 100644 index 00000000000..f1121935d38 --- /dev/null +++ b/tests/baselines/reference/contextualTypeFromJSDoc.types @@ -0,0 +1,77 @@ +=== tests/cases/conformance/types/contextualTypes/jsdoc/index.js === +/** @type {Array<[string, {x?:number, y?:number}]>} */ +const arr = [ +>arr : [string, { x?: number; y?: number; }][] +>[ ['a', { x: 1 }], ['b', { y: 2 }]] : ([string, { x: number; }] | [string, { y: number; }])[] + + ['a', { x: 1 }], +>['a', { x: 1 }] : [string, { x: number; }] +>'a' : "a" +>{ x: 1 } : { x: number; } +>x : number +>1 : 1 + + ['b', { y: 2 }] +>['b', { y: 2 }] : [string, { y: number; }] +>'b' : "b" +>{ y: 2 } : { y: number; } +>y : number +>2 : 2 + +]; + +/** @return {Array<[string, {x?:number, y?:number}]>} */ +function f() { +>f : () => [string, { x?: number; y?: number; }][] + + return [ +>[ ['a', { x: 1 }], ['b', { y: 2 }] ] : ([string, { x: number; }] | [string, { y: number; }])[] + + ['a', { x: 1 }], +>['a', { x: 1 }] : [string, { x: number; }] +>'a' : "a" +>{ x: 1 } : { x: number; } +>x : number +>1 : 1 + + ['b', { y: 2 }] +>['b', { y: 2 }] : [string, { y: number; }] +>'b' : "b" +>{ y: 2 } : { y: number; } +>y : number +>2 : 2 + + ]; +} + +class C { +>C : C + + /** @param {Array<[string, {x?:number, y?:number}]>} value */ + set x(value) { } +>x : [string, { x?: number; y?: number; }][] +>value : [string, { x?: number; y?: number; }][] + + get x() { +>x : [string, { x?: number; y?: number; }][] + + return [ +>[ ['a', { x: 1 }], ['b', { y: 2 }] ] : ([string, { x: number; }] | [string, { y: number; }])[] + + ['a', { x: 1 }], +>['a', { x: 1 }] : [string, { x: number; }] +>'a' : "a" +>{ x: 1 } : { x: number; } +>x : number +>1 : 1 + + ['b', { y: 2 }] +>['b', { y: 2 }] : [string, { y: number; }] +>'b' : "b" +>{ y: 2 } : { y: number; } +>y : number +>2 : 2 + + ]; + } +} diff --git a/tests/baselines/reference/contextualTypingWithGenericSignature.types b/tests/baselines/reference/contextualTypingWithGenericSignature.types index 68c5f3c422d..cb70022a20b 100644 --- a/tests/baselines/reference/contextualTypingWithGenericSignature.types +++ b/tests/baselines/reference/contextualTypingWithGenericSignature.types @@ -16,10 +16,10 @@ var f2: { }; f2 = (x, y) => { return x } ->f2 = (x, y) => { return x } : (x: any, y: any) => any +>f2 = (x, y) => { return x } : (x: T, y: U) => T >f2 : (x: T, y: U) => T ->(x, y) => { return x } : (x: any, y: any) => any ->x : any ->y : any ->x : any +>(x, y) => { return x } : (x: T, y: U) => T +>x : T +>y : U +>x : T diff --git a/tests/baselines/reference/declarationEmitIndexTypeArray.js b/tests/baselines/reference/declarationEmitIndexTypeArray.js new file mode 100644 index 00000000000..a84080fb5c4 --- /dev/null +++ b/tests/baselines/reference/declarationEmitIndexTypeArray.js @@ -0,0 +1,25 @@ +//// [declarationEmitIndexTypeArray.ts] +function doSomethingWithKeys(...keys: (keyof T)[]) { } + +const utilityFunctions = { + doSomethingWithKeys +}; + + +//// [declarationEmitIndexTypeArray.js] +function doSomethingWithKeys() { + var keys = []; + for (var _i = 0; _i < arguments.length; _i++) { + keys[_i] = arguments[_i]; + } +} +var utilityFunctions = { + doSomethingWithKeys: doSomethingWithKeys +}; + + +//// [declarationEmitIndexTypeArray.d.ts] +declare function doSomethingWithKeys(...keys: (keyof T)[]): void; +declare const utilityFunctions: { + doSomethingWithKeys: (...keys: (keyof T)[]) => void; +}; diff --git a/tests/baselines/reference/declarationEmitIndexTypeArray.symbols b/tests/baselines/reference/declarationEmitIndexTypeArray.symbols new file mode 100644 index 00000000000..1f6cb302881 --- /dev/null +++ b/tests/baselines/reference/declarationEmitIndexTypeArray.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/declarationEmitIndexTypeArray.ts === +function doSomethingWithKeys(...keys: (keyof T)[]) { } +>doSomethingWithKeys : Symbol(doSomethingWithKeys, Decl(declarationEmitIndexTypeArray.ts, 0, 0)) +>T : Symbol(T, Decl(declarationEmitIndexTypeArray.ts, 0, 29)) +>keys : Symbol(keys, Decl(declarationEmitIndexTypeArray.ts, 0, 32)) +>T : Symbol(T, Decl(declarationEmitIndexTypeArray.ts, 0, 29)) + +const utilityFunctions = { +>utilityFunctions : Symbol(utilityFunctions, Decl(declarationEmitIndexTypeArray.ts, 2, 5)) + + doSomethingWithKeys +>doSomethingWithKeys : Symbol(doSomethingWithKeys, Decl(declarationEmitIndexTypeArray.ts, 2, 26)) + +}; + diff --git a/tests/baselines/reference/declarationEmitIndexTypeArray.types b/tests/baselines/reference/declarationEmitIndexTypeArray.types new file mode 100644 index 00000000000..67f8905639e --- /dev/null +++ b/tests/baselines/reference/declarationEmitIndexTypeArray.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/declarationEmitIndexTypeArray.ts === +function doSomethingWithKeys(...keys: (keyof T)[]) { } +>doSomethingWithKeys : (...keys: keyof T[]) => void +>T : T +>keys : keyof T[] +>T : T + +const utilityFunctions = { +>utilityFunctions : { doSomethingWithKeys: (...keys: keyof T[]) => void; } +>{ doSomethingWithKeys} : { doSomethingWithKeys: (...keys: keyof T[]) => void; } + + doSomethingWithKeys +>doSomethingWithKeys : (...keys: keyof T[]) => void + +}; + diff --git a/tests/baselines/reference/declarationEmitParameterProperty.js b/tests/baselines/reference/declarationEmitParameterProperty.js new file mode 100644 index 00000000000..262222e3c68 --- /dev/null +++ b/tests/baselines/reference/declarationEmitParameterProperty.js @@ -0,0 +1,24 @@ +//// [declarationEmitParameterProperty.ts] +export class Foo { + constructor(public bar?: string) { + } +} + + +//// [declarationEmitParameterProperty.js] +"use strict"; +exports.__esModule = true; +var Foo = (function () { + function Foo(bar) { + this.bar = bar; + } + return Foo; +}()); +exports.Foo = Foo; + + +//// [declarationEmitParameterProperty.d.ts] +export declare class Foo { + bar: string | undefined; + constructor(bar?: string | undefined); +} diff --git a/tests/baselines/reference/declarationEmitParameterProperty.symbols b/tests/baselines/reference/declarationEmitParameterProperty.symbols new file mode 100644 index 00000000000..d9e88e52cb0 --- /dev/null +++ b/tests/baselines/reference/declarationEmitParameterProperty.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/declarationEmitParameterProperty.ts === +export class Foo { +>Foo : Symbol(Foo, Decl(declarationEmitParameterProperty.ts, 0, 0)) + + constructor(public bar?: string) { +>bar : Symbol(Foo.bar, Decl(declarationEmitParameterProperty.ts, 1, 14)) + } +} + diff --git a/tests/baselines/reference/declarationEmitParameterProperty.types b/tests/baselines/reference/declarationEmitParameterProperty.types new file mode 100644 index 00000000000..3adfecf0c75 --- /dev/null +++ b/tests/baselines/reference/declarationEmitParameterProperty.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/declarationEmitParameterProperty.ts === +export class Foo { +>Foo : Foo + + constructor(public bar?: string) { +>bar : string | undefined + } +} + diff --git a/tests/baselines/reference/decoratorCallGeneric.errors.txt b/tests/baselines/reference/decoratorCallGeneric.errors.txt index c8443420740..c2e4042743e 100644 --- a/tests/baselines/reference/decoratorCallGeneric.errors.txt +++ b/tests/baselines/reference/decoratorCallGeneric.errors.txt @@ -1,6 +1,7 @@ -tests/cases/conformance/decorators/decoratorCallGeneric.ts(7,2): error TS1238: Unable to resolve signature of class decorator when called as an expression. - The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'C' is not a valid type argument because it is not a supertype of candidate 'void'. +tests/cases/conformance/decorators/decoratorCallGeneric.ts(7,2): error TS2345: Argument of type 'typeof C' is not assignable to parameter of type 'I'. + Types of property 'm' are incompatible. + Type '() => void' is not assignable to type '() => C'. + Type 'void' is not assignable to type 'C'. ==== tests/cases/conformance/decorators/decoratorCallGeneric.ts (1 errors) ==== @@ -12,9 +13,10 @@ tests/cases/conformance/decorators/decoratorCallGeneric.ts(7,2): error TS1238: U @dec ~~~ -!!! error TS1238: Unable to resolve signature of class decorator when called as an expression. -!!! error TS1238: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS1238: Type argument candidate 'C' is not a valid type argument because it is not a supertype of candidate 'void'. +!!! error TS2345: Argument of type 'typeof C' is not assignable to parameter of type 'I'. +!!! error TS2345: Types of property 'm' are incompatible. +!!! error TS2345: Type '() => void' is not assignable to type '() => C'. +!!! error TS2345: Type 'void' is not assignable to type 'C'. class C { _brand: any; static m() {} diff --git a/tests/baselines/reference/decoratorOnClass9.js b/tests/baselines/reference/decoratorOnClass9.js new file mode 100644 index 00000000000..eac4dcf690a --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass9.js @@ -0,0 +1,55 @@ +//// [decoratorOnClass9.ts] +declare var dec: any; + +class A {} + +// https://github.com/Microsoft/TypeScript/issues/16417 +@dec +class B extends A { + static x = 1; + static y = B.x; + m() { + return B.x; + } +} + +//// [decoratorOnClass9.js] +var __extends = (this && this.__extends) || (function () { + var 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 function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var A = (function () { + function A() { + } + return A; +}()); +// https://github.com/Microsoft/TypeScript/issues/16417 +var B = (function (_super) { + __extends(B, _super); + function B() { + return _super !== null && _super.apply(this, arguments) || this; + } + B_1 = B; + B.prototype.m = function () { + return B_1.x; + }; + B.x = 1; + B.y = B_1.x; + B = B_1 = __decorate([ + dec + ], B); + return B; + var B_1; +}(A)); diff --git a/tests/baselines/reference/decoratorOnClass9.symbols b/tests/baselines/reference/decoratorOnClass9.symbols new file mode 100644 index 00000000000..134c696da2a --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass9.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/decorators/class/decoratorOnClass9.ts === +declare var dec: any; +>dec : Symbol(dec, Decl(decoratorOnClass9.ts, 0, 11)) + +class A {} +>A : Symbol(A, Decl(decoratorOnClass9.ts, 0, 21)) + +// https://github.com/Microsoft/TypeScript/issues/16417 +@dec +>dec : Symbol(dec, Decl(decoratorOnClass9.ts, 0, 11)) + +class B extends A { +>B : Symbol(B, Decl(decoratorOnClass9.ts, 2, 10)) +>A : Symbol(A, Decl(decoratorOnClass9.ts, 0, 21)) + + static x = 1; +>x : Symbol(B.x, Decl(decoratorOnClass9.ts, 6, 19)) + + static y = B.x; +>y : Symbol(B.y, Decl(decoratorOnClass9.ts, 7, 17)) +>B.x : Symbol(B.x, Decl(decoratorOnClass9.ts, 6, 19)) +>B : Symbol(B, Decl(decoratorOnClass9.ts, 2, 10)) +>x : Symbol(B.x, Decl(decoratorOnClass9.ts, 6, 19)) + + m() { +>m : Symbol(B.m, Decl(decoratorOnClass9.ts, 8, 19)) + + return B.x; +>B.x : Symbol(B.x, Decl(decoratorOnClass9.ts, 6, 19)) +>B : Symbol(B, Decl(decoratorOnClass9.ts, 2, 10)) +>x : Symbol(B.x, Decl(decoratorOnClass9.ts, 6, 19)) + } +} diff --git a/tests/baselines/reference/decoratorOnClass9.types b/tests/baselines/reference/decoratorOnClass9.types new file mode 100644 index 00000000000..d2825c15b08 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClass9.types @@ -0,0 +1,34 @@ +=== tests/cases/conformance/decorators/class/decoratorOnClass9.ts === +declare var dec: any; +>dec : any + +class A {} +>A : A + +// https://github.com/Microsoft/TypeScript/issues/16417 +@dec +>dec : any + +class B extends A { +>B : B +>A : A + + static x = 1; +>x : number +>1 : 1 + + static y = B.x; +>y : number +>B.x : number +>B : typeof B +>x : number + + m() { +>m : () => number + + return B.x; +>B.x : number +>B : typeof B +>x : number + } +} diff --git a/tests/baselines/reference/defaultBestCommonTypesHaveDecls.errors.txt b/tests/baselines/reference/defaultBestCommonTypesHaveDecls.errors.txt index 3b81fe0864e..a59e8c59fdf 100644 --- a/tests/baselines/reference/defaultBestCommonTypesHaveDecls.errors.txt +++ b/tests/baselines/reference/defaultBestCommonTypesHaveDecls.errors.txt @@ -1,7 +1,6 @@ tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(2,6): error TS2339: Property 'length' does not exist on type '{}'. tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(5,6): error TS2339: Property 'length' does not exist on type 'Object'. -tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(8,14): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate '""'. +tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(8,24): error TS2345: Argument of type '""' is not assignable to parameter of type '1'. ==== tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts (3 errors) ==== @@ -17,9 +16,8 @@ tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(8,14): error TS2453: The function concat(x: T, y: T): T { return null; } var result = concat(1, ""); // error - ~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate '""'. + ~~ +!!! error TS2345: Argument of type '""' is not assignable to parameter of type '1'. var elementCount = result.length; function concat2(x: T, y: U) { return null; } diff --git a/tests/baselines/reference/es6modulekindWithES5Target11.js b/tests/baselines/reference/es6modulekindWithES5Target11.js index e958b0ca1c6..a89da173951 100644 --- a/tests/baselines/reference/es6modulekindWithES5Target11.js +++ b/tests/baselines/reference/es6modulekindWithES5Target11.js @@ -16,9 +16,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, return c > 3 && r && Object.defineProperty(target, key, r), r; }; var C = (function () { - var C = C_1 = function C() { + function C() { this.p = 1; - }; + } + C_1 = C; C.x = function () { return C_1.y; }; C.prototype.method = function () { }; C.y = 1; diff --git a/tests/baselines/reference/excessPropertyCheckWithSpread.errors.txt b/tests/baselines/reference/excessPropertyCheckWithSpread.errors.txt new file mode 100644 index 00000000000..422d7fc280c --- /dev/null +++ b/tests/baselines/reference/excessPropertyCheckWithSpread.errors.txt @@ -0,0 +1,30 @@ +tests/cases/compiler/excessPropertyCheckWithSpread.ts(6,3): error TS2345: Argument of type '{ n: number; a: number; }' is not assignable to parameter of type '{ a: any; }'. + Object literal may only specify known properties, and 'n' does not exist in type '{ a: any; }'. +tests/cases/compiler/excessPropertyCheckWithSpread.ts(16,3): error TS2345: Argument of type '{ opt: string | number; a: number; }' is not assignable to parameter of type '{ a: any; }'. + Object literal may only specify known properties, and 'opt' does not exist in type '{ a: any; }'. + + +==== tests/cases/compiler/excessPropertyCheckWithSpread.ts (2 errors) ==== + declare function f({ a: number }): void + interface I { + readonly n: number; + } + declare let i: I; + f({ a: 1, ...i }); + ~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ n: number; a: number; }' is not assignable to parameter of type '{ a: any; }'. +!!! error TS2345: Object literal may only specify known properties, and 'n' does not exist in type '{ a: any; }'. + + interface R { + opt?: number + } + interface L { + opt: string + } + declare let l: L; + declare let r: R; + f({ a: 1, ...l, ...r }); + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ opt: string | number; a: number; }' is not assignable to parameter of type '{ a: any; }'. +!!! error TS2345: Object literal may only specify known properties, and 'opt' does not exist in type '{ a: any; }'. + \ No newline at end of file diff --git a/tests/baselines/reference/excessPropertyCheckWithSpread.js b/tests/baselines/reference/excessPropertyCheckWithSpread.js new file mode 100644 index 00000000000..d8dac07a3fb --- /dev/null +++ b/tests/baselines/reference/excessPropertyCheckWithSpread.js @@ -0,0 +1,30 @@ +//// [excessPropertyCheckWithSpread.ts] +declare function f({ a: number }): void +interface I { + readonly n: number; +} +declare let i: I; +f({ a: 1, ...i }); + +interface R { + opt?: number +} +interface L { + opt: string +} +declare let l: L; +declare let r: R; +f({ a: 1, ...l, ...r }); + + +//// [excessPropertyCheckWithSpread.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +f(__assign({ a: 1 }, i)); +f(__assign({ a: 1 }, l, r)); diff --git a/tests/baselines/reference/fixTypeParameterInSignatureWithRestParameters.errors.txt b/tests/baselines/reference/fixTypeParameterInSignatureWithRestParameters.errors.txt index e1cde0c1632..aa163edc32e 100644 --- a/tests/baselines/reference/fixTypeParameterInSignatureWithRestParameters.errors.txt +++ b/tests/baselines/reference/fixTypeParameterInSignatureWithRestParameters.errors.txt @@ -1,10 +1,8 @@ -tests/cases/compiler/fixTypeParameterInSignatureWithRestParameters.ts(2,1): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate '""'. +tests/cases/compiler/fixTypeParameterInSignatureWithRestParameters.ts(2,8): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'. ==== tests/cases/compiler/fixTypeParameterInSignatureWithRestParameters.ts (1 errors) ==== function bar(item1: T, item2: T) { } bar(1, ""); // Should be ok - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate '""'. \ No newline at end of file + ~~ +!!! error TS2345: Argument of type '""' is not assignable to parameter of type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly1.symbols b/tests/baselines/reference/fixingTypeParametersRepeatedly1.symbols index 86f91c82663..3d0c33ebfc0 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly1.symbols +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly1.symbols @@ -45,7 +45,5 @@ g("", x => null, x => x.toLowerCase()); >g : Symbol(g, Decl(fixingTypeParametersRepeatedly1.ts, 1, 39), Decl(fixingTypeParametersRepeatedly1.ts, 4, 63)) >x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 5)) >x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 16)) ->x.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) >x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 16)) ->toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --)) diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly1.types b/tests/baselines/reference/fixingTypeParametersRepeatedly1.types index 41e705ba943..d7326a515f5 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly1.types +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly1.types @@ -48,16 +48,16 @@ declare function g(); >g : { (x: T, y: (p: T) => T, z: (p: T) => T): T; (): any; } g("", x => null, x => x.toLowerCase()); ->g("", x => null, x => x.toLowerCase()) : string +>g("", x => null, x => x.toLowerCase()) : any >g : { (x: T, y: (p: T) => T, z: (p: T) => T): T; (): any; } >"" : "" >x => null : (x: string) => any >x : string >null : null ->x => x.toLowerCase() : (x: string) => string ->x : string ->x.toLowerCase() : string ->x.toLowerCase : () => string ->x : string ->toLowerCase : () => string +>x => x.toLowerCase() : (x: any) => any +>x : any +>x.toLowerCase() : any +>x.toLowerCase : any +>x : any +>toLowerCase : any diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt b/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt index e56b58a268d..900d605d5fc 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt @@ -1,11 +1,9 @@ tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(11,27): error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'. Type 'Base' is not assignable to type 'Derived'. Property 'toBase' is missing in type 'Base'. -tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(17,27): error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'. - Type 'Base' is not assignable to type 'Derived'. -==== tests/cases/compiler/fixingTypeParametersRepeatedly2.ts (2 errors) ==== +==== tests/cases/compiler/fixingTypeParametersRepeatedly2.ts (1 errors) ==== interface Base { baseProp; } @@ -26,7 +24,4 @@ tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(17,27): error TS2345: Ar // The same error should be observed in both cases. declare function bar(x: T, func: (p: T) => T): T; declare function bar(x: T, func: (p: T) => T): T; - var result = bar(derived, d => d.toBase()); - ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'. -!!! error TS2345: Type 'Base' is not assignable to type 'Derived'. \ No newline at end of file + var result = bar(derived, d => d.toBase()); \ No newline at end of file diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly3.types b/tests/baselines/reference/fixingTypeParametersRepeatedly3.types index 3bf926276d2..beb195df5ed 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly3.types +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly3.types @@ -66,8 +66,8 @@ declare function bar(x: T, func: (p: T) => T): T; >T : T var result2 = bar(derived, d => d.toBase()); ->result2 : Derived ->bar(derived, d => d.toBase()) : Derived +>result2 : Base +>bar(derived, d => d.toBase()) : Base >bar : { (x: T, func: (p: T) => T): T; (x: T, func: (p: T) => T): T; } >derived : Derived >d => d.toBase() : (d: Derived) => Base diff --git a/tests/baselines/reference/for-of39.errors.txt b/tests/baselines/reference/for-of39.errors.txt index 48db183a58c..73802daf5a5 100644 --- a/tests/baselines/reference/for-of39.errors.txt +++ b/tests/baselines/reference/for-of39.errors.txt @@ -1,12 +1,28 @@ -tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,15): error TS2453: The type argument for type parameter 'V' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'boolean' is not a valid type argument because it is not a supertype of candidate 'number'. +tests/cases/conformance/es6/for-ofStatements/for-of39.ts(1,19): error TS2345: Argument of type '([string, true] | [string, 0])[]' is not assignable to parameter of type 'Iterable<[string, boolean]>'. + Types of property '[Symbol.iterator]' are incompatible. + Type '() => IterableIterator<[string, true] | [string, 0]>' is not assignable to type '() => Iterator<[string, boolean]>'. + Type 'IterableIterator<[string, true] | [string, 0]>' is not assignable to type 'Iterator<[string, boolean]>'. + Types of property 'next' are incompatible. + Type '(value?: any) => IteratorResult<[string, true] | [string, 0]>' is not assignable to type '(value?: any) => IteratorResult<[string, boolean]>'. + Type 'IteratorResult<[string, true] | [string, 0]>' is not assignable to type 'IteratorResult<[string, boolean]>'. + Type '[string, true] | [string, 0]' is not assignable to type '[string, boolean]'. + Type '[string, 0]' is not assignable to type '[string, boolean]'. + Type '0' is not assignable to type 'boolean'. ==== tests/cases/conformance/es6/for-ofStatements/for-of39.ts (1 errors) ==== var map = new Map([["", true], ["", 0]]); - ~~~ -!!! error TS2453: The type argument for type parameter 'V' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'boolean' is not a valid type argument because it is not a supertype of candidate 'number'. + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '([string, true] | [string, 0])[]' is not assignable to parameter of type 'Iterable<[string, boolean]>'. +!!! error TS2345: Types of property '[Symbol.iterator]' are incompatible. +!!! error TS2345: Type '() => IterableIterator<[string, true] | [string, 0]>' is not assignable to type '() => Iterator<[string, boolean]>'. +!!! error TS2345: Type 'IterableIterator<[string, true] | [string, 0]>' is not assignable to type 'Iterator<[string, boolean]>'. +!!! error TS2345: Types of property 'next' are incompatible. +!!! error TS2345: Type '(value?: any) => IteratorResult<[string, true] | [string, 0]>' is not assignable to type '(value?: any) => IteratorResult<[string, boolean]>'. +!!! error TS2345: Type 'IteratorResult<[string, true] | [string, 0]>' is not assignable to type 'IteratorResult<[string, boolean]>'. +!!! error TS2345: Type '[string, true] | [string, 0]' is not assignable to type '[string, boolean]'. +!!! error TS2345: Type '[string, 0]' is not assignable to type '[string, boolean]'. +!!! error TS2345: Type '0' is not assignable to type 'boolean'. for (var [k, v] of map) { k; v; diff --git a/tests/baselines/reference/functionTypeArgumentAssignmentCompat.errors.txt b/tests/baselines/reference/functionTypeArgumentAssignmentCompat.errors.txt index 366e1732b29..2fa3cafcb1a 100644 --- a/tests/baselines/reference/functionTypeArgumentAssignmentCompat.errors.txt +++ b/tests/baselines/reference/functionTypeArgumentAssignmentCompat.errors.txt @@ -1,7 +1,9 @@ +tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(9,1): error TS2322: Type '() => S[]' is not assignable to type '(x: T) => T'. + Type '{}[]' is not assignable to type 'T'. tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(12,1): error TS2304: Cannot find name 'console'. -==== tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts (1 errors) ==== +==== tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts (2 errors) ==== var f : { (x:T): T; } @@ -11,6 +13,9 @@ tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(12,1): error TS2304 } = () => []; f = g; + ~ +!!! error TS2322: Type '() => S[]' is not assignable to type '(x: T) => T'. +!!! error TS2322: Type '{}[]' is not assignable to type 'T'. var s = f("str").toUpperCase(); console.log(s); diff --git a/tests/baselines/reference/generatorTypeCheck63.errors.txt b/tests/baselines/reference/generatorTypeCheck63.errors.txt index ed2ed36a438..1466530dd0c 100644 --- a/tests/baselines/reference/generatorTypeCheck63.errors.txt +++ b/tests/baselines/reference/generatorTypeCheck63.errors.txt @@ -1,11 +1,13 @@ -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(24,14): error TS2322: Type '(a: State | 1) => IterableIterator' is not assignable to type 'Strategy'. - Type 'IterableIterator' is not assignable to type 'IterableIterator'. - Type 'State | 1' is not assignable to type 'State'. - Type '1' is not assignable to type 'State'. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(24,61): error TS2345: Argument of type '(state: State) => IterableIterator' is not assignable to parameter of type '(a: StrategicState) => IterableIterator'. + Type 'IterableIterator' is not assignable to type 'IterableIterator'. + Type 'State | 1' is not assignable to type 'StrategicState'. + Type '1' has no properties in common with type 'StrategicState'. tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(29,70): error TS7025: Generator implicitly has type 'IterableIterator' because it does not yield any values. Consider supplying a return type. -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(32,42): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'State' is not a valid type argument because it is not a supertype of candidate '1'. -tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): error TS2322: Type '(a: State | 1) => IterableIterator' is not assignable to type 'Strategy'. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(32,62): error TS2345: Argument of type '(state: State) => IterableIterator<1>' is not assignable to parameter of type '(a: State) => IterableIterator'. + Type 'IterableIterator<1>' is not assignable to type 'IterableIterator'. + Type '1' is not assignable to type 'State'. +tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,62): error TS2345: Argument of type '(state: State) => IterableIterator' is not assignable to parameter of type '(a: StrategicState) => IterableIterator'. + Type 'IterableIterator' is not assignable to type 'IterableIterator'. ==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts (4 errors) ==== @@ -33,11 +35,11 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): err } export const Nothing: Strategy = strategy("Nothing", function* (state: State) { - ~~~~~~~ -!!! error TS2322: Type '(a: State | 1) => IterableIterator' is not assignable to type 'Strategy'. -!!! error TS2322: Type 'IterableIterator' is not assignable to type 'IterableIterator'. -!!! error TS2322: Type 'State | 1' is not assignable to type 'State'. -!!! error TS2322: Type '1' is not assignable to type 'State'. + ~~~~~~~~ +!!! error TS2345: Argument of type '(state: State) => IterableIterator' is not assignable to parameter of type '(a: StrategicState) => IterableIterator'. +!!! error TS2345: Type 'IterableIterator' is not assignable to type 'IterableIterator'. +!!! error TS2345: Type 'State | 1' is not assignable to type 'StrategicState'. +!!! error TS2345: Type '1' has no properties in common with type 'StrategicState'. yield 1; return state; }); @@ -48,15 +50,17 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): err }); export const Nothing2: Strategy = strategy("Nothing", function* (state: State) { - ~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'State' is not a valid type argument because it is not a supertype of candidate '1'. + ~~~~~~~~ +!!! error TS2345: Argument of type '(state: State) => IterableIterator<1>' is not assignable to parameter of type '(a: State) => IterableIterator'. +!!! error TS2345: Type 'IterableIterator<1>' is not assignable to type 'IterableIterator'. +!!! error TS2345: Type '1' is not assignable to type 'State'. return 1; }); export const Nothing3: Strategy = strategy("Nothing", function* (state: State) { - ~~~~~~~~ -!!! error TS2322: Type '(a: State | 1) => IterableIterator' is not assignable to type 'Strategy'. + ~~~~~~~~ +!!! error TS2345: Argument of type '(state: State) => IterableIterator' is not assignable to parameter of type '(a: StrategicState) => IterableIterator'. +!!! error TS2345: Type 'IterableIterator' is not assignable to type 'IterableIterator'. yield state; return 1; }); \ No newline at end of file diff --git a/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.errors.txt b/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.errors.txt new file mode 100644 index 00000000000..9e9a7e9505d --- /dev/null +++ b/tests/baselines/reference/genericArgumentCallSigAssignmentCompat.errors.txt @@ -0,0 +1,30 @@ +tests/cases/compiler/genericArgumentCallSigAssignmentCompat.ts(16,31): error TS2345: Argument of type '(value: T) => T' is not assignable to parameter of type 'Iterator'. + Type 'string | number | boolean' is not assignable to type 'boolean'. + Type 'string' is not assignable to type 'boolean'. + + +==== tests/cases/compiler/genericArgumentCallSigAssignmentCompat.ts (1 errors) ==== + module Underscore { + export interface Iterator { + (value: T, index: any, list: any): U; + } + + export interface Static { + all(list: T[], iterator?: Iterator, context?: any): boolean; + identity(value: T): T; + } + } + + declare var _: Underscore.Static; + + // No error, Call signatures of types '(value: T) => T' and 'Underscore.Iterator<{}, boolean>' are compatible when instantiated with any. + // Ideally, we would not have a generic signature here, because it should be instantiated with {} during inferential typing + _.all([true, 1, null, 'yes'], _.identity); + ~~~~~~~~~~ +!!! error TS2345: Argument of type '(value: T) => T' is not assignable to parameter of type 'Iterator'. +!!! error TS2345: Type 'string | number | boolean' is not assignable to type 'boolean'. +!!! error TS2345: Type 'string' is not assignable to type 'boolean'. + + // Ok, because fixing makes us infer boolean for T + _.all([true], _.identity); + \ No newline at end of file diff --git a/tests/baselines/reference/genericAssignmentCompatOfFunctionSignatures1.errors.txt b/tests/baselines/reference/genericAssignmentCompatOfFunctionSignatures1.errors.txt new file mode 100644 index 00000000000..b2c6aa42013 --- /dev/null +++ b/tests/baselines/reference/genericAssignmentCompatOfFunctionSignatures1.errors.txt @@ -0,0 +1,34 @@ +tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts(4,1): error TS2322: Type '(x: T, z: U) => void' is not assignable to type '(x: T, z: U) => void'. + Types of parameters 'z' and 'z' are incompatible. + Type 'U' is not assignable to type '{ a: T; b: number; }'. + Type '{ a: T; b: string; }' is not assignable to type '{ a: T; b: number; }'. + Types of property 'b' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts(5,1): error TS2322: Type '(x: T, z: U) => void' is not assignable to type '(x: T, z: U) => void'. + Types of parameters 'z' and 'z' are incompatible. + Type 'U' is not assignable to type '{ a: T; b: string; }'. + Type '{ a: T; b: number; }' is not assignable to type '{ a: T; b: string; }'. + Types of property 'b' are incompatible. + Type 'number' is not assignable to type 'string'. + + +==== tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts (2 errors) ==== + var x1 = function foo3(x: T, z: U) { } + var x2 = function foo3(x: T, z: U) { } + + x1 = x2; + ~~ +!!! error TS2322: Type '(x: T, z: U) => void' is not assignable to type '(x: T, z: U) => void'. +!!! error TS2322: Types of parameters 'z' and 'z' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type '{ a: T; b: number; }'. +!!! error TS2322: Type '{ a: T; b: string; }' is not assignable to type '{ a: T; b: number; }'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + x2 = x1; + ~~ +!!! error TS2322: Type '(x: T, z: U) => void' is not assignable to type '(x: T, z: U) => void'. +!!! error TS2322: Types of parameters 'z' and 'z' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type '{ a: T; b: string; }'. +!!! error TS2322: Type '{ a: T; b: number; }' is not assignable to type '{ a: T; b: string; }'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithFunctionTypedArguments.errors.txt b/tests/baselines/reference/genericCallWithFunctionTypedArguments.errors.txt index 80b04c069d5..ca3e195a8a7 100644 --- a/tests/baselines/reference/genericCallWithFunctionTypedArguments.errors.txt +++ b/tests/baselines/reference/genericCallWithFunctionTypedArguments.errors.txt @@ -1,13 +1,16 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(26,10): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(30,15): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(33,15): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(34,16): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(35,15): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(26,18): error TS2345: Argument of type '(a: number) => string' is not assignable to parameter of type '(a: number) => 1'. + Type 'string' is not assignable to type '1'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(30,23): error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. + Types of parameters 'x' and 'a' are incompatible. + Type '1' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(33,23): error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. + Types of parameters 'x' and 'a' are incompatible. + Type '1' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(34,24): error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. + Types of parameters 'x' and 'a' are incompatible. + Type '1' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(35,23): error TS2345: Argument of type '(a: number) => string' is not assignable to parameter of type '(a: number) => 1'. + Type 'string' is not assignable to type '1'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts (5 errors) ==== @@ -37,28 +40,31 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFun var r7 = foo3(1, (a: Z) => '', ''); // string var r8 = foo3(1, function (a) { return '' }, 1); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~~~~~~~ +!!! error TS2345: Argument of type '(a: number) => string' is not assignable to parameter of type '(a: number) => 1'. +!!! error TS2345: Type 'string' is not assignable to type '1'. var r9 = foo3(1, (a) => '', ''); // string function other(t: T, u: U) { var r10 = foo2(1, (x: T) => ''); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. +!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. +!!! error TS2345: Type '1' is not assignable to type 'T'. var r10 = foo2(1, (x) => ''); // string var r11 = foo3(1, (x: T) => '', ''); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. +!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. +!!! error TS2345: Type '1' is not assignable to type 'T'. var r11b = foo3(1, (x: T) => '', 1); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. +!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. +!!! error TS2345: Type '1' is not assignable to type 'T'. var r12 = foo3(1, function (a) { return '' }, 1); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~~~~~~~ +!!! error TS2345: Argument of type '(a: number) => string' is not assignable to parameter of type '(a: number) => 1'. +!!! error TS2345: Type 'string' is not assignable to type '1'. } \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithFunctionTypedArguments2.errors.txt b/tests/baselines/reference/genericCallWithFunctionTypedArguments2.errors.txt index 90f87de070d..a46ee6c0f8e 100644 --- a/tests/baselines/reference/genericCallWithFunctionTypedArguments2.errors.txt +++ b/tests/baselines/reference/genericCallWithFunctionTypedArguments2.errors.txt @@ -1,7 +1,9 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts(29,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts(40,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts(29,18): error TS2345: Argument of type 'I2' is not assignable to parameter of type 'new (a: 1) => string'. + Types of parameters 'x' and 'a' are incompatible. + Type '1' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts(40,18): error TS2345: Argument of type 'I2' is not assignable to parameter of type 'new (a: 1) => string'. + Types of parameters 'x' and 'a' are incompatible. + Type '1' is not assignable to type 'string'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts (2 errors) ==== @@ -34,9 +36,10 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFun } var r4 = foo2(1, i2); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~ +!!! error TS2345: Argument of type 'I2' is not assignable to parameter of type 'new (a: 1) => string'. +!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. +!!! error TS2345: Type '1' is not assignable to type 'string'. var r4b = foo2(1, a); // any var r5 = foo2(1, i); // any var r6 = foo2('', i2); // string @@ -48,7 +51,8 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFun var r7 = foo3(null, i, ''); // any var r7b = foo3(null, a, ''); // any var r8 = foo3(1, i2, 1); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~ +!!! error TS2345: Argument of type 'I2' is not assignable to parameter of type 'new (a: 1) => string'. +!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. +!!! error TS2345: Type '1' is not assignable to type 'string'. var r9 = foo3('', i2, ''); // string \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithGenericSignatureArguments.errors.txt b/tests/baselines/reference/genericCallWithGenericSignatureArguments.errors.txt deleted file mode 100644 index 33c01aa544a..00000000000 --- a/tests/baselines/reference/genericCallWithGenericSignatureArguments.errors.txt +++ /dev/null @@ -1,59 +0,0 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts(18,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; y?: number; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; z?: number; }'. - Property 'y' is missing in type '{ x: number; z?: number; }'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts(19,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; z?: number; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y?: number; }'. - Property 'z' is missing in type '{ x: number; y?: number; }'. - - -==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts (2 errors) ==== - // When a function expression is inferentially typed (section 4.9.3) and a type assigned to a parameter in that expression references type parameters for which inferences are being made, - // the corresponding inferred type arguments to become fixed and no further candidate inferences are made for them. - - function foo(a: (x: T) => T, b: (x: T) => T) { - var r: (x: T) => T; - return r; - } - - //var r1 = foo((x: number) => 1, (x: string) => ''); // error - var r1b = foo((x) => 1, (x) => ''); // {} => {} - var r2 = foo((x: Object) => null, (x: string) => ''); // Object => Object - var r3 = foo((x: number) => 1, (x: Object) => null); // number => number - var r3ii = foo((x: number) => 1, (x: number) => 1); // number => number - - var a: { x: number; y?: number; }; - var b: { x: number; z?: number; }; - - var r4 = foo((x: typeof a) => a, (x: typeof b) => b); // typeof a => typeof a - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; y?: number; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; z?: number; }'. -!!! error TS2453: Property 'y' is missing in type '{ x: number; z?: number; }'. - var r5 = foo((x: typeof b) => b, (x: typeof a) => a); // typeof b => typeof b - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; z?: number; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y?: number; }'. -!!! error TS2453: Property 'z' is missing in type '{ x: number; y?: number; }'. - - function other(x: T) { - var r6 = foo((a: T) => a, (b: T) => b); // T => T - var r6b = foo((a) => a, (b) => b); // {} => {} - } - - function other2(x: T) { - var r7 = foo((a: T) => a, (b: T) => b); // T => T - var r7b = foo((a) => a, (b) => b); // {} => {} - var r8 = r7(null); - // BUG 835518 - //var r9 = r7(new Date()); - } - - - function foo2(a: (x: T) => T, b: (x: T) => T) { - var r: (x: T) => T; - return r; - } - - function other3(x: T) { - var r8 = foo2((a: Date) => a, (b: Date) => b); // Date => Date - } \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithGenericSignatureArguments.symbols b/tests/baselines/reference/genericCallWithGenericSignatureArguments.symbols new file mode 100644 index 00000000000..b814c700b8e --- /dev/null +++ b/tests/baselines/reference/genericCallWithGenericSignatureArguments.symbols @@ -0,0 +1,182 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts === +// When a function expression is inferentially typed (section 4.9.3) and a type assigned to a parameter in that expression references type parameters for which inferences are being made, +// the corresponding inferred type arguments to become fixed and no further candidate inferences are made for them. + +function foo(a: (x: T) => T, b: (x: T) => T) { +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 3, 13)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 3, 16)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 3, 20)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 3, 13)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 3, 13)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 3, 31)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 3, 36)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 3, 13)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 3, 13)) + + var r: (x: T) => T; +>r : Symbol(r, Decl(genericCallWithGenericSignatureArguments.ts, 4, 7)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 4, 12)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 3, 13)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 3, 13)) + + return r; +>r : Symbol(r, Decl(genericCallWithGenericSignatureArguments.ts, 4, 7)) +} + +//var r1 = foo((x: number) => 1, (x: string) => ''); // error +var r1b = foo((x) => 1, (x) => ''); // {} => {} +>r1b : Symbol(r1b, Decl(genericCallWithGenericSignatureArguments.ts, 9, 3)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 9, 15)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 9, 25)) + +var r2 = foo((x: Object) => null, (x: string) => ''); // Object => Object +>r2 : Symbol(r2, Decl(genericCallWithGenericSignatureArguments.ts, 10, 3)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 10, 14)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 10, 35)) + +var r3 = foo((x: number) => 1, (x: Object) => null); // number => number +>r3 : Symbol(r3, Decl(genericCallWithGenericSignatureArguments.ts, 11, 3)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 11, 14)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 11, 32)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +var r3ii = foo((x: number) => 1, (x: number) => 1); // number => number +>r3ii : Symbol(r3ii, Decl(genericCallWithGenericSignatureArguments.ts, 12, 3)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 12, 16)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 12, 34)) + +var a: { x: number; y?: number; }; +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 14, 3)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 14, 8)) +>y : Symbol(y, Decl(genericCallWithGenericSignatureArguments.ts, 14, 19)) + +var b: { x: number; z?: number; }; +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 15, 3)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 15, 8)) +>z : Symbol(z, Decl(genericCallWithGenericSignatureArguments.ts, 15, 19)) + +var r4 = foo((x: typeof a) => a, (x: typeof b) => b); // typeof a => typeof a +>r4 : Symbol(r4, Decl(genericCallWithGenericSignatureArguments.ts, 17, 3)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 17, 14)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 14, 3)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 14, 3)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 17, 34)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 15, 3)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 15, 3)) + +var r5 = foo((x: typeof b) => b, (x: typeof a) => a); // typeof b => typeof b +>r5 : Symbol(r5, Decl(genericCallWithGenericSignatureArguments.ts, 18, 3)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 18, 14)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 15, 3)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 15, 3)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 18, 34)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 14, 3)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 14, 3)) + +function other(x: T) { +>other : Symbol(other, Decl(genericCallWithGenericSignatureArguments.ts, 18, 53)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 20, 15)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 20, 18)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 20, 15)) + + var r6 = foo((a: T) => a, (b: T) => b); // T => T +>r6 : Symbol(r6, Decl(genericCallWithGenericSignatureArguments.ts, 21, 7)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 21, 18)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 20, 15)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 21, 18)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 21, 31)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 20, 15)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 21, 31)) + + var r6b = foo((a) => a, (b) => b); // {} => {} +>r6b : Symbol(r6b, Decl(genericCallWithGenericSignatureArguments.ts, 22, 7)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 22, 19)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 22, 19)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 22, 29)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 22, 29)) +} + +function other2(x: T) { +>other2 : Symbol(other2, Decl(genericCallWithGenericSignatureArguments.ts, 23, 1)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 25, 16)) +>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 25, 32)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 25, 16)) + + var r7 = foo((a: T) => a, (b: T) => b); // T => T +>r7 : Symbol(r7, Decl(genericCallWithGenericSignatureArguments.ts, 26, 7)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 26, 18)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 25, 16)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 26, 18)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 26, 31)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 25, 16)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 26, 31)) + + var r7b = foo((a) => a, (b) => b); // {} => {} +>r7b : Symbol(r7b, Decl(genericCallWithGenericSignatureArguments.ts, 27, 7)) +>foo : Symbol(foo, Decl(genericCallWithGenericSignatureArguments.ts, 0, 0)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 27, 19)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 27, 19)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 27, 29)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 27, 29)) + + var r8 = r7(null); +>r8 : Symbol(r8, Decl(genericCallWithGenericSignatureArguments.ts, 28, 7)) +>r7 : Symbol(r7, Decl(genericCallWithGenericSignatureArguments.ts, 26, 7)) + + // BUG 835518 + //var r9 = r7(new Date()); +} + + +function foo2(a: (x: T) => T, b: (x: T) => T) { +>foo2 : Symbol(foo2, Decl(genericCallWithGenericSignatureArguments.ts, 31, 1)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 34, 14)) +>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 34, 30)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 34, 34)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 34, 14)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 34, 14)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 34, 45)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 34, 50)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 34, 14)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 34, 14)) + + var r: (x: T) => T; +>r : Symbol(r, Decl(genericCallWithGenericSignatureArguments.ts, 35, 7)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 35, 12)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 34, 14)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 34, 14)) + + return r; +>r : Symbol(r, Decl(genericCallWithGenericSignatureArguments.ts, 35, 7)) +} + +function other3(x: T) { +>other3 : Symbol(other3, Decl(genericCallWithGenericSignatureArguments.ts, 37, 1)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 39, 16)) +>RegExp : Symbol(RegExp, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(genericCallWithGenericSignatureArguments.ts, 39, 34)) +>T : Symbol(T, Decl(genericCallWithGenericSignatureArguments.ts, 39, 16)) + + var r8 = foo2((a: Date) => a, (b: Date) => b); // Date => Date +>r8 : Symbol(r8, Decl(genericCallWithGenericSignatureArguments.ts, 40, 7)) +>foo2 : Symbol(foo2, Decl(genericCallWithGenericSignatureArguments.ts, 31, 1)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 40, 19)) +>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>a : Symbol(a, Decl(genericCallWithGenericSignatureArguments.ts, 40, 19)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 40, 35)) +>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>b : Symbol(b, Decl(genericCallWithGenericSignatureArguments.ts, 40, 35)) +} diff --git a/tests/baselines/reference/genericCallWithGenericSignatureArguments.types b/tests/baselines/reference/genericCallWithGenericSignatureArguments.types new file mode 100644 index 00000000000..a9301c526c0 --- /dev/null +++ b/tests/baselines/reference/genericCallWithGenericSignatureArguments.types @@ -0,0 +1,225 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts === +// When a function expression is inferentially typed (section 4.9.3) and a type assigned to a parameter in that expression references type parameters for which inferences are being made, +// the corresponding inferred type arguments to become fixed and no further candidate inferences are made for them. + +function foo(a: (x: T) => T, b: (x: T) => T) { +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>T : T +>a : (x: T) => T +>x : T +>T : T +>T : T +>b : (x: T) => T +>x : T +>T : T +>T : T + + var r: (x: T) => T; +>r : (x: T) => T +>x : T +>T : T +>T : T + + return r; +>r : (x: T) => T +} + +//var r1 = foo((x: number) => 1, (x: string) => ''); // error +var r1b = foo((x) => 1, (x) => ''); // {} => {} +>r1b : (x: {}) => {} +>foo((x) => 1, (x) => '') : (x: {}) => {} +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(x) => 1 : (x: {}) => number +>x : {} +>1 : 1 +>(x) => '' : (x: {}) => string +>x : {} +>'' : "" + +var r2 = foo((x: Object) => null, (x: string) => ''); // Object => Object +>r2 : (x: any) => any +>foo((x: Object) => null, (x: string) => '') : (x: any) => any +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(x: Object) => null : (x: Object) => any +>x : Object +>Object : Object +>null : null +>(x: string) => '' : (x: string) => string +>x : string +>'' : "" + +var r3 = foo((x: number) => 1, (x: Object) => null); // number => number +>r3 : (x: any) => any +>foo((x: number) => 1, (x: Object) => null) : (x: any) => any +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(x: number) => 1 : (x: number) => number +>x : number +>1 : 1 +>(x: Object) => null : (x: Object) => any +>x : Object +>Object : Object +>null : null + +var r3ii = foo((x: number) => 1, (x: number) => 1); // number => number +>r3ii : (x: number) => number +>foo((x: number) => 1, (x: number) => 1) : (x: number) => number +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(x: number) => 1 : (x: number) => number +>x : number +>1 : 1 +>(x: number) => 1 : (x: number) => number +>x : number +>1 : 1 + +var a: { x: number; y?: number; }; +>a : { x: number; y?: number; } +>x : number +>y : number + +var b: { x: number; z?: number; }; +>b : { x: number; z?: number; } +>x : number +>z : number + +var r4 = foo((x: typeof a) => a, (x: typeof b) => b); // typeof a => typeof a +>r4 : (x: { x: number; y?: number; }) => { x: number; y?: number; } +>foo((x: typeof a) => a, (x: typeof b) => b) : (x: { x: number; y?: number; }) => { x: number; y?: number; } +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(x: typeof a) => a : (x: { x: number; y?: number; }) => { x: number; y?: number; } +>x : { x: number; y?: number; } +>a : { x: number; y?: number; } +>a : { x: number; y?: number; } +>(x: typeof b) => b : (x: { x: number; z?: number; }) => { x: number; z?: number; } +>x : { x: number; z?: number; } +>b : { x: number; z?: number; } +>b : { x: number; z?: number; } + +var r5 = foo((x: typeof b) => b, (x: typeof a) => a); // typeof b => typeof b +>r5 : (x: { x: number; z?: number; }) => { x: number; z?: number; } +>foo((x: typeof b) => b, (x: typeof a) => a) : (x: { x: number; z?: number; }) => { x: number; z?: number; } +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(x: typeof b) => b : (x: { x: number; z?: number; }) => { x: number; z?: number; } +>x : { x: number; z?: number; } +>b : { x: number; z?: number; } +>b : { x: number; z?: number; } +>(x: typeof a) => a : (x: { x: number; y?: number; }) => { x: number; y?: number; } +>x : { x: number; y?: number; } +>a : { x: number; y?: number; } +>a : { x: number; y?: number; } + +function other(x: T) { +>other : (x: T) => void +>T : T +>x : T +>T : T + + var r6 = foo((a: T) => a, (b: T) => b); // T => T +>r6 : (x: T) => T +>foo((a: T) => a, (b: T) => b) : (x: T) => T +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(a: T) => a : (a: T) => T +>a : T +>T : T +>a : T +>(b: T) => b : (b: T) => T +>b : T +>T : T +>b : T + + var r6b = foo((a) => a, (b) => b); // {} => {} +>r6b : (x: {}) => {} +>foo((a) => a, (b) => b) : (x: {}) => {} +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(a) => a : (a: {}) => {} +>a : {} +>a : {} +>(b) => b : (b: {}) => {} +>b : {} +>b : {} +} + +function other2(x: T) { +>other2 : (x: T) => void +>T : T +>Date : Date +>x : T +>T : T + + var r7 = foo((a: T) => a, (b: T) => b); // T => T +>r7 : (x: T) => T +>foo((a: T) => a, (b: T) => b) : (x: T) => T +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(a: T) => a : (a: T) => T +>a : T +>T : T +>a : T +>(b: T) => b : (b: T) => T +>b : T +>T : T +>b : T + + var r7b = foo((a) => a, (b) => b); // {} => {} +>r7b : (x: {}) => {} +>foo((a) => a, (b) => b) : (x: {}) => {} +>foo : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(a) => a : (a: {}) => {} +>a : {} +>a : {} +>(b) => b : (b: {}) => {} +>b : {} +>b : {} + + var r8 = r7(null); +>r8 : T +>r7(null) : T +>r7 : (x: T) => T +>null : null + + // BUG 835518 + //var r9 = r7(new Date()); +} + + +function foo2(a: (x: T) => T, b: (x: T) => T) { +>foo2 : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>T : T +>Date : Date +>a : (x: T) => T +>x : T +>T : T +>T : T +>b : (x: T) => T +>x : T +>T : T +>T : T + + var r: (x: T) => T; +>r : (x: T) => T +>x : T +>T : T +>T : T + + return r; +>r : (x: T) => T +} + +function other3(x: T) { +>other3 : (x: T) => void +>T : T +>RegExp : RegExp +>x : T +>T : T + + var r8 = foo2((a: Date) => a, (b: Date) => b); // Date => Date +>r8 : (x: Date) => Date +>foo2((a: Date) => a, (b: Date) => b) : (x: Date) => Date +>foo2 : (a: (x: T) => T, b: (x: T) => T) => (x: T) => T +>(a: Date) => a : (a: Date) => Date +>a : Date +>Date : Date +>a : Date +>(b: Date) => b : (b: Date) => Date +>b : Date +>Date : Date +>b : Date +} diff --git a/tests/baselines/reference/genericCallWithGenericSignatureArguments2.errors.txt b/tests/baselines/reference/genericCallWithGenericSignatureArguments2.errors.txt index 714fe32d31a..363f0b0f645 100644 --- a/tests/baselines/reference/genericCallWithGenericSignatureArguments2.errors.txt +++ b/tests/baselines/reference/genericCallWithGenericSignatureArguments2.errors.txt @@ -1,5 +1,6 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(10,29): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(10,51): error TS2345: Argument of type '(x: string) => string' is not assignable to parameter of type '(x: number) => number'. + Types of parameters 'x' and 'x' are incompatible. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(15,21): error TS2345: Argument of type 'Date' is not assignable to parameter of type 'T'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(16,22): error TS2345: Argument of type '1' is not assignable to parameter of type 'T'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments2.ts(25,23): error TS2345: Argument of type '(a: T) => T' is not assignable to parameter of type '(x: Date) => Date'. @@ -27,9 +28,10 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGen } var r1: (x: {}) => {} = foo((x: number) => 1, (x: string) => ''); - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(x: string) => string' is not assignable to parameter of type '(x: number) => number'. +!!! error TS2345: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2345: Type 'number' is not assignable to type 'string'. function other2(x: T) { var r7 = foo((a: T) => a, (b: T) => b); // T => T diff --git a/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt b/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt index 87ae6b63855..4c29b010295 100644 --- a/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt +++ b/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt @@ -1,8 +1,8 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts(32,11): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '(y: string) => string' is not a valid type argument because it is not a supertype of candidate '(a: string) => boolean'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts(32,19): error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => number' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => number'. + Types of parameters 'a1' and 'x' are incompatible. Type 'boolean' is not assignable to type 'string'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts(33,11): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '(n: Object) => number' is not a valid type argument because it is not a supertype of candidate 'number'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts(33,69): error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => number'. + Type 'number' is not assignable to type '(n: Object) => number'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts (2 errors) ==== @@ -38,11 +38,11 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGen var x: (a: string) => boolean; var r11 = foo2(x, (a1: (y: string) => string) => (n: Object) => 1, (a2: (z: string) => string) => 2); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '(y: string) => string' is not a valid type argument because it is not a supertype of candidate '(a: string) => boolean'. -!!! error TS2453: Type 'boolean' is not assignable to type 'string'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => number' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => number'. +!!! error TS2345: Types of parameters 'a1' and 'x' are incompatible. +!!! error TS2345: Type 'boolean' is not assignable to type 'string'. var r12 = foo2(x, (a1: (y: string) => boolean) => (n: Object) => 1, (a2: (z: string) => boolean) => 2); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '(n: Object) => number' is not a valid type argument because it is not a supertype of candidate 'number'. \ No newline at end of file + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => number'. +!!! error TS2345: Type 'number' is not assignable to type '(n: Object) => number'. \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.errors.txt b/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.errors.txt deleted file mode 100644 index 3b896d9a7d8..00000000000 --- a/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.errors.txt +++ /dev/null @@ -1,48 +0,0 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithNonSymmetricSubtypes.ts(12,9): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; y?: number; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; z?: number; }'. - Property 'y' is missing in type '{ x: number; z?: number; }'. -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithNonSymmetricSubtypes.ts(13,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; z?: number; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y?: number; }'. - Property 'z' is missing in type '{ x: number; y?: number; }'. - - -==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithNonSymmetricSubtypes.ts (2 errors) ==== - // generic type argument inference where inference leads to two candidates that are both supertypes of all candidates - // we choose the first candidate so the result is dependent on the order of the arguments provided - - function foo(x: T, y: T) { - var r: T; - return r; - } - - var a: { x: number; y?: number; }; - var b: { x: number; z?: number; }; - - var r = foo(a, b); // { x: number; y?: number; }; - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; y?: number; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; z?: number; }'. -!!! error TS2453: Property 'y' is missing in type '{ x: number; z?: number; }'. - var r2 = foo(b, a); // { x: number; z?: number; }; - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; z?: number; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y?: number; }'. -!!! error TS2453: Property 'z' is missing in type '{ x: number; y?: number; }'. - - var x: { x: number; }; - var y: { x?: number; }; - - var r3 = foo(a, x); // { x: number; y?: number; }; - var r4 = foo(x, a); // { x: number; }; - - var r5 = foo(a, y); // { x?: number; }; - var r5 = foo(y, a); // { x?: number; }; - - var r6 = foo(x, y); // { x?: number; }; - var r6 = foo(y, x); // { x?: number; }; - - var s1: (x: Object) => string; - var s2: (x: string) => string; - - var r7 = foo(s1, s2); // (x: Object) => string; - var r8 = foo(s2, s1); // (x: string) => string; \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.symbols b/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.symbols new file mode 100644 index 00000000000..24cc602fdab --- /dev/null +++ b/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.symbols @@ -0,0 +1,107 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithNonSymmetricSubtypes.ts === +// generic type argument inference where inference leads to two candidates that are both supertypes of all candidates +// we choose the first candidate so the result is dependent on the order of the arguments provided + +function foo(x: T, y: T) { +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>T : Symbol(T, Decl(genericCallWithNonSymmetricSubtypes.ts, 3, 13)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 3, 16)) +>T : Symbol(T, Decl(genericCallWithNonSymmetricSubtypes.ts, 3, 13)) +>y : Symbol(y, Decl(genericCallWithNonSymmetricSubtypes.ts, 3, 21)) +>T : Symbol(T, Decl(genericCallWithNonSymmetricSubtypes.ts, 3, 13)) + + var r: T; +>r : Symbol(r, Decl(genericCallWithNonSymmetricSubtypes.ts, 4, 7)) +>T : Symbol(T, Decl(genericCallWithNonSymmetricSubtypes.ts, 3, 13)) + + return r; +>r : Symbol(r, Decl(genericCallWithNonSymmetricSubtypes.ts, 4, 7)) +} + +var a: { x: number; y?: number; }; +>a : Symbol(a, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 3)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 8)) +>y : Symbol(y, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 19)) + +var b: { x: number; z?: number; }; +>b : Symbol(b, Decl(genericCallWithNonSymmetricSubtypes.ts, 9, 3)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 9, 8)) +>z : Symbol(z, Decl(genericCallWithNonSymmetricSubtypes.ts, 9, 19)) + +var r = foo(a, b); // { x: number; y?: number; }; +>r : Symbol(r, Decl(genericCallWithNonSymmetricSubtypes.ts, 11, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>a : Symbol(a, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 3)) +>b : Symbol(b, Decl(genericCallWithNonSymmetricSubtypes.ts, 9, 3)) + +var r2 = foo(b, a); // { x: number; z?: number; }; +>r2 : Symbol(r2, Decl(genericCallWithNonSymmetricSubtypes.ts, 12, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>b : Symbol(b, Decl(genericCallWithNonSymmetricSubtypes.ts, 9, 3)) +>a : Symbol(a, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 3)) + +var x: { x: number; }; +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 14, 3)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 14, 8)) + +var y: { x?: number; }; +>y : Symbol(y, Decl(genericCallWithNonSymmetricSubtypes.ts, 15, 3)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 15, 8)) + +var r3 = foo(a, x); // { x: number; y?: number; }; +>r3 : Symbol(r3, Decl(genericCallWithNonSymmetricSubtypes.ts, 17, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>a : Symbol(a, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 3)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 14, 3)) + +var r4 = foo(x, a); // { x: number; }; +>r4 : Symbol(r4, Decl(genericCallWithNonSymmetricSubtypes.ts, 18, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 14, 3)) +>a : Symbol(a, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 3)) + +var r5 = foo(a, y); // { x?: number; }; +>r5 : Symbol(r5, Decl(genericCallWithNonSymmetricSubtypes.ts, 20, 3), Decl(genericCallWithNonSymmetricSubtypes.ts, 21, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>a : Symbol(a, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 3)) +>y : Symbol(y, Decl(genericCallWithNonSymmetricSubtypes.ts, 15, 3)) + +var r5 = foo(y, a); // { x?: number; }; +>r5 : Symbol(r5, Decl(genericCallWithNonSymmetricSubtypes.ts, 20, 3), Decl(genericCallWithNonSymmetricSubtypes.ts, 21, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>y : Symbol(y, Decl(genericCallWithNonSymmetricSubtypes.ts, 15, 3)) +>a : Symbol(a, Decl(genericCallWithNonSymmetricSubtypes.ts, 8, 3)) + +var r6 = foo(x, y); // { x?: number; }; +>r6 : Symbol(r6, Decl(genericCallWithNonSymmetricSubtypes.ts, 23, 3), Decl(genericCallWithNonSymmetricSubtypes.ts, 24, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 14, 3)) +>y : Symbol(y, Decl(genericCallWithNonSymmetricSubtypes.ts, 15, 3)) + +var r6 = foo(y, x); // { x?: number; }; +>r6 : Symbol(r6, Decl(genericCallWithNonSymmetricSubtypes.ts, 23, 3), Decl(genericCallWithNonSymmetricSubtypes.ts, 24, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>y : Symbol(y, Decl(genericCallWithNonSymmetricSubtypes.ts, 15, 3)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 14, 3)) + +var s1: (x: Object) => string; +>s1 : Symbol(s1, Decl(genericCallWithNonSymmetricSubtypes.ts, 26, 3)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 26, 9)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +var s2: (x: string) => string; +>s2 : Symbol(s2, Decl(genericCallWithNonSymmetricSubtypes.ts, 27, 3)) +>x : Symbol(x, Decl(genericCallWithNonSymmetricSubtypes.ts, 27, 9)) + +var r7 = foo(s1, s2); // (x: Object) => string; +>r7 : Symbol(r7, Decl(genericCallWithNonSymmetricSubtypes.ts, 29, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>s1 : Symbol(s1, Decl(genericCallWithNonSymmetricSubtypes.ts, 26, 3)) +>s2 : Symbol(s2, Decl(genericCallWithNonSymmetricSubtypes.ts, 27, 3)) + +var r8 = foo(s2, s1); // (x: string) => string; +>r8 : Symbol(r8, Decl(genericCallWithNonSymmetricSubtypes.ts, 30, 3)) +>foo : Symbol(foo, Decl(genericCallWithNonSymmetricSubtypes.ts, 0, 0)) +>s2 : Symbol(s2, Decl(genericCallWithNonSymmetricSubtypes.ts, 27, 3)) +>s1 : Symbol(s1, Decl(genericCallWithNonSymmetricSubtypes.ts, 26, 3)) + diff --git a/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.types b/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.types new file mode 100644 index 00000000000..eaf190ec878 --- /dev/null +++ b/tests/baselines/reference/genericCallWithNonSymmetricSubtypes.types @@ -0,0 +1,117 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithNonSymmetricSubtypes.ts === +// generic type argument inference where inference leads to two candidates that are both supertypes of all candidates +// we choose the first candidate so the result is dependent on the order of the arguments provided + +function foo(x: T, y: T) { +>foo : (x: T, y: T) => T +>T : T +>x : T +>T : T +>y : T +>T : T + + var r: T; +>r : T +>T : T + + return r; +>r : T +} + +var a: { x: number; y?: number; }; +>a : { x: number; y?: number; } +>x : number +>y : number + +var b: { x: number; z?: number; }; +>b : { x: number; z?: number; } +>x : number +>z : number + +var r = foo(a, b); // { x: number; y?: number; }; +>r : { x: number; y?: number; } +>foo(a, b) : { x: number; y?: number; } +>foo : (x: T, y: T) => T +>a : { x: number; y?: number; } +>b : { x: number; z?: number; } + +var r2 = foo(b, a); // { x: number; z?: number; }; +>r2 : { x: number; z?: number; } +>foo(b, a) : { x: number; z?: number; } +>foo : (x: T, y: T) => T +>b : { x: number; z?: number; } +>a : { x: number; y?: number; } + +var x: { x: number; }; +>x : { x: number; } +>x : number + +var y: { x?: number; }; +>y : { x?: number; } +>x : number + +var r3 = foo(a, x); // { x: number; y?: number; }; +>r3 : { x: number; } +>foo(a, x) : { x: number; } +>foo : (x: T, y: T) => T +>a : { x: number; y?: number; } +>x : { x: number; } + +var r4 = foo(x, a); // { x: number; }; +>r4 : { x: number; } +>foo(x, a) : { x: number; } +>foo : (x: T, y: T) => T +>x : { x: number; } +>a : { x: number; y?: number; } + +var r5 = foo(a, y); // { x?: number; }; +>r5 : { x?: number; } +>foo(a, y) : { x?: number; } +>foo : (x: T, y: T) => T +>a : { x: number; y?: number; } +>y : { x?: number; } + +var r5 = foo(y, a); // { x?: number; }; +>r5 : { x?: number; } +>foo(y, a) : { x?: number; } +>foo : (x: T, y: T) => T +>y : { x?: number; } +>a : { x: number; y?: number; } + +var r6 = foo(x, y); // { x?: number; }; +>r6 : { x?: number; } +>foo(x, y) : { x?: number; } +>foo : (x: T, y: T) => T +>x : { x: number; } +>y : { x?: number; } + +var r6 = foo(y, x); // { x?: number; }; +>r6 : { x?: number; } +>foo(y, x) : { x?: number; } +>foo : (x: T, y: T) => T +>y : { x?: number; } +>x : { x: number; } + +var s1: (x: Object) => string; +>s1 : (x: Object) => string +>x : Object +>Object : Object + +var s2: (x: string) => string; +>s2 : (x: string) => string +>x : string + +var r7 = foo(s1, s2); // (x: Object) => string; +>r7 : (x: string) => string +>foo(s1, s2) : (x: string) => string +>foo : (x: T, y: T) => T +>s1 : (x: Object) => string +>s2 : (x: string) => string + +var r8 = foo(s2, s1); // (x: string) => string; +>r8 : (x: Object) => string +>foo(s2, s1) : (x: Object) => string +>foo : (x: T, y: T) => T +>s2 : (x: string) => string +>s1 : (x: Object) => string + diff --git a/tests/baselines/reference/genericCallWithObjectLiteralArgs.errors.txt b/tests/baselines/reference/genericCallWithObjectLiteralArgs.errors.txt index eb45586442d..c1724a8f698 100644 --- a/tests/baselines/reference/genericCallWithObjectLiteralArgs.errors.txt +++ b/tests/baselines/reference/genericCallWithObjectLiteralArgs.errors.txt @@ -1,5 +1,6 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectLiteralArgs.ts(5,9): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectLiteralArgs.ts(5,13): error TS2345: Argument of type '{ bar: number; baz: string; }' is not assignable to parameter of type '{ bar: number; baz: number; }'. + Types of property 'baz' are incompatible. + Type 'string' is not assignable to type 'number'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectLiteralArgs.ts (1 errors) ==== @@ -8,9 +9,10 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObj } var r = foo({ bar: 1, baz: '' }); // error - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ bar: number; baz: string; }' is not assignable to parameter of type '{ bar: number; baz: number; }'. +!!! error TS2345: Types of property 'baz' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var r2 = foo({ bar: 1, baz: 1 }); // T = number var r3 = foo({ bar: foo, baz: foo }); // T = typeof foo var r4 = foo({ bar: 1, baz: '' }); // T = Object \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithObjectLiteralArguments1.errors.txt b/tests/baselines/reference/genericCallWithObjectLiteralArguments1.errors.txt index f389a0a6cae..cbc57364155 100644 --- a/tests/baselines/reference/genericCallWithObjectLiteralArguments1.errors.txt +++ b/tests/baselines/reference/genericCallWithObjectLiteralArguments1.errors.txt @@ -1,5 +1,6 @@ -tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(3,9): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(3,13): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; y: number; }'. + Types of property 'y' are incompatible. + Type 'string' is not assignable to type 'number'. tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(4,22): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; y: number; }'. Types of property 'y' are incompatible. Type 'string' is not assignable to type 'number'. @@ -18,9 +19,10 @@ tests/cases/compiler/genericCallWithObjectLiteralArguments1.ts(7,22): error TS23 function foo(n: { x: T; y: T }, m: T) { return m; } // these are all errors var x = foo({ x: 3, y: "" }, 4); - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; y: number; }'. +!!! error TS2345: Types of property 'y' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var x2 = foo({ x: 3, y: "" }, 4); ~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; y: number; }'. diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgs.errors.txt b/tests/baselines/reference/genericCallWithObjectTypeArgs.errors.txt index ecd76d4ea1b..a845fd543e9 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgs.errors.txt +++ b/tests/baselines/reference/genericCallWithObjectTypeArgs.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgs.ts(20,9): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'C' is not a valid type argument because it is not a supertype of candidate 'D'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgs.ts(20,17): error TS2345: Argument of type 'X' is not assignable to parameter of type 'X'. + Type 'D' is not assignable to type 'C'. Types have separate declarations of a private property 'x'. @@ -24,8 +24,8 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObj var c1 = new X(); var d1 = new X(); var r = foo(c1, d1); // error - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'C' is not a valid type argument because it is not a supertype of candidate 'D'. -!!! error TS2453: Types have separate declarations of a private property 'x'. + ~~ +!!! error TS2345: Argument of type 'X' is not assignable to parameter of type 'X'. +!!! error TS2345: Type 'D' is not assignable to type 'C'. +!!! error TS2345: Types have separate declarations of a private property 'x'. var r2 = foo(c1, c1); // ok \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints3.errors.txt b/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints3.errors.txt index 6c2be7b10d1..ad07374b810 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints3.errors.txt +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndConstraints3.errors.txt @@ -1,6 +1,7 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndConstraints3.ts(18,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'Derived' is not a valid type argument because it is not a supertype of candidate 'Derived2'. - Property 'y' is missing in type 'Derived2'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndConstraints3.ts(18,12): error TS2345: Argument of type '{ x: Derived; y: Derived2; }' is not assignable to parameter of type '{ x: Derived; y: Derived; }'. + Types of property 'y' are incompatible. + Type 'Derived2' is not assignable to type 'Derived'. + Property 'y' is missing in type 'Derived2'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObjectTypeArgsAndConstraints3.ts (1 errors) ==== @@ -22,10 +23,11 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithObj } var r1 = f({ x: new Derived(), y: new Derived2() }); // error because neither is supertype of the other - ~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'Derived' is not a valid type argument because it is not a supertype of candidate 'Derived2'. -!!! error TS2453: Property 'y' is missing in type 'Derived2'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '{ x: Derived; y: Derived2; }' is not assignable to parameter of type '{ x: Derived; y: Derived; }'. +!!! error TS2345: Types of property 'y' are incompatible. +!!! error TS2345: Type 'Derived2' is not assignable to type 'Derived'. +!!! error TS2345: Property 'y' is missing in type 'Derived2'. function f2(a: U) { var r: T; diff --git a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.errors.txt b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.errors.txt deleted file mode 100644 index 2a0807bf6b9..00000000000 --- a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.errors.txt +++ /dev/null @@ -1,56 +0,0 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedConstructorTypedArguments.ts(36,14): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'boolean' is not a valid type argument because it is not a supertype of candidate 'number'. - - -==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedConstructorTypedArguments.ts (1 errors) ==== - // Function typed arguments with multiple signatures must be passed an implementation that matches all of them - // Inferences are made quadratic-pairwise to and from these overload sets - - module NonGenericParameter { - var a: { - new(x: boolean): boolean; - new(x: string): string; - } - - function foo4(cb: typeof a) { - return new cb(null); - } - - var r = foo4(a); - var b: { new (x: T): T }; - var r2 = foo4(b); - } - - module GenericParameter { - function foo5(cb: { new(x: T): string; new(x: number): T }) { - return cb; - } - - var a: { - new (x: boolean): string; - new (x: number): boolean; - } - var r5 = foo5(a); // new{} => string; new(x:number) => {} - var b: { new(x: T): string; new(x: number): T; } - var r7 = foo5(b); // new any => string; new(x:number) => any - - function foo6(cb: { new(x: T): string; new(x: T, y?: T): string }) { - return cb; - } - - var r8 = foo6(a); // error - ~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'boolean' is not a valid type argument because it is not a supertype of candidate 'number'. - var r9 = foo6(b); // new any => string; new(x:any, y?:any) => string - - function foo7(x:T, cb: { new(x: T): string; new(x: T, y?: T): string }) { - return cb; - } - - var r13 = foo7(1, b); // new any => string; new(x:any, y?:any) => string - var c: { new (x: T): string; (x: number): T; } - var c2: { new (x: T): string; new(x: number): T; } - var r14 = foo7(1, c); // new any => string; new(x:any, y?:any) => string - var r15 = foo7(1, c2); // new any => string; new(x:any, y?:any) => string - } \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.symbols b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.symbols new file mode 100644 index 00000000000..b510f554877 --- /dev/null +++ b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.symbols @@ -0,0 +1,163 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedConstructorTypedArguments.ts === +// Function typed arguments with multiple signatures must be passed an implementation that matches all of them +// Inferences are made quadratic-pairwise to and from these overload sets + +module NonGenericParameter { +>NonGenericParameter : Symbol(NonGenericParameter, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 0, 0)) + + var a: { +>a : Symbol(a, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 4, 7)) + + new(x: boolean): boolean; +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 5, 12)) + + new(x: string): string; +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 6, 12)) + } + + function foo4(cb: typeof a) { +>foo4 : Symbol(foo4, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 7, 5)) +>cb : Symbol(cb, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 9, 18)) +>a : Symbol(a, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 4, 7)) + + return new cb(null); +>cb : Symbol(cb, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 9, 18)) + } + + var r = foo4(a); +>r : Symbol(r, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 13, 7)) +>foo4 : Symbol(foo4, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 7, 5)) +>a : Symbol(a, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 4, 7)) + + var b: { new (x: T): T }; +>b : Symbol(b, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 14, 7)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 14, 18)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 14, 21)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 14, 18)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 14, 18)) + + var r2 = foo4(b); +>r2 : Symbol(r2, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 15, 7)) +>foo4 : Symbol(foo4, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 7, 5)) +>b : Symbol(b, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 14, 7)) +} + +module GenericParameter { +>GenericParameter : Symbol(GenericParameter, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 16, 1)) + + function foo5(cb: { new(x: T): string; new(x: number): T }) { +>foo5 : Symbol(foo5, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 18, 25)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 19, 18)) +>cb : Symbol(cb, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 19, 21)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 19, 31)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 19, 18)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 19, 50)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 19, 18)) + + return cb; +>cb : Symbol(cb, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 19, 21)) + } + + var a: { +>a : Symbol(a, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 23, 7)) + + new (x: boolean): string; +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 24, 13)) + + new (x: number): boolean; +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 25, 13)) + } + var r5 = foo5(a); // new{} => string; new(x:number) => {} +>r5 : Symbol(r5, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 27, 7)) +>foo5 : Symbol(foo5, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 18, 25)) +>a : Symbol(a, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 23, 7)) + + var b: { new(x: T): string; new(x: number): T; } +>b : Symbol(b, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 7)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 17)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 20)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 17)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 39)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 42)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 39)) + + var r7 = foo5(b); // new any => string; new(x:number) => any +>r7 : Symbol(r7, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 29, 7)) +>foo5 : Symbol(foo5, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 18, 25)) +>b : Symbol(b, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 7)) + + function foo6(cb: { new(x: T): string; new(x: T, y?: T): string }) { +>foo6 : Symbol(foo6, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 29, 21)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 18)) +>cb : Symbol(cb, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 21)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 31)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 18)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 50)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 18)) +>y : Symbol(y, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 55)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 18)) + + return cb; +>cb : Symbol(cb, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 31, 21)) + } + + var r8 = foo6(a); // error +>r8 : Symbol(r8, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 35, 7)) +>foo6 : Symbol(foo6, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 29, 21)) +>a : Symbol(a, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 23, 7)) + + var r9 = foo6(b); // new any => string; new(x:any, y?:any) => string +>r9 : Symbol(r9, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 36, 7)) +>foo6 : Symbol(foo6, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 29, 21)) +>b : Symbol(b, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 7)) + + function foo7(x:T, cb: { new(x: T): string; new(x: T, y?: T): string }) { +>foo7 : Symbol(foo7, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 36, 21)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 18)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 21)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 18)) +>cb : Symbol(cb, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 25)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 36)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 18)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 55)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 18)) +>y : Symbol(y, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 60)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 18)) + + return cb; +>cb : Symbol(cb, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 38, 25)) + } + + var r13 = foo7(1, b); // new any => string; new(x:any, y?:any) => string +>r13 : Symbol(r13, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 42, 7)) +>foo7 : Symbol(foo7, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 36, 21)) +>b : Symbol(b, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 28, 7)) + + var c: { new (x: T): string; (x: number): T; } +>c : Symbol(c, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 43, 7)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 43, 18)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 43, 21)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 43, 18)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 43, 37)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 43, 40)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 43, 37)) + + var c2: { new (x: T): string; new(x: number): T; } +>c2 : Symbol(c2, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 44, 7)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 44, 19)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 44, 22)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 44, 19)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 44, 41)) +>x : Symbol(x, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 44, 44)) +>T : Symbol(T, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 44, 41)) + + var r14 = foo7(1, c); // new any => string; new(x:any, y?:any) => string +>r14 : Symbol(r14, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 45, 7)) +>foo7 : Symbol(foo7, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 36, 21)) +>c : Symbol(c, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 43, 7)) + + var r15 = foo7(1, c2); // new any => string; new(x:any, y?:any) => string +>r15 : Symbol(r15, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 46, 7)) +>foo7 : Symbol(foo7, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 36, 21)) +>c2 : Symbol(c2, Decl(genericCallWithOverloadedConstructorTypedArguments.ts, 44, 7)) +} diff --git a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.types b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.types new file mode 100644 index 00000000000..15e746f615a --- /dev/null +++ b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.types @@ -0,0 +1,177 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedConstructorTypedArguments.ts === +// Function typed arguments with multiple signatures must be passed an implementation that matches all of them +// Inferences are made quadratic-pairwise to and from these overload sets + +module NonGenericParameter { +>NonGenericParameter : typeof NonGenericParameter + + var a: { +>a : { new (x: boolean): boolean; new (x: string): string; } + + new(x: boolean): boolean; +>x : boolean + + new(x: string): string; +>x : string + } + + function foo4(cb: typeof a) { +>foo4 : (cb: { new (x: boolean): boolean; new (x: string): string; }) => boolean +>cb : { new (x: boolean): boolean; new (x: string): string; } +>a : { new (x: boolean): boolean; new (x: string): string; } + + return new cb(null); +>new cb(null) : boolean +>cb : { new (x: boolean): boolean; new (x: string): string; } +>null : null + } + + var r = foo4(a); +>r : boolean +>foo4(a) : boolean +>foo4 : (cb: { new (x: boolean): boolean; new (x: string): string; }) => boolean +>a : { new (x: boolean): boolean; new (x: string): string; } + + var b: { new (x: T): T }; +>b : new (x: T) => T +>T : T +>x : T +>T : T +>T : T + + var r2 = foo4(b); +>r2 : boolean +>foo4(b) : boolean +>foo4 : (cb: { new (x: boolean): boolean; new (x: string): string; }) => boolean +>b : new (x: T) => T +} + +module GenericParameter { +>GenericParameter : typeof GenericParameter + + function foo5(cb: { new(x: T): string; new(x: number): T }) { +>foo5 : (cb: { new (x: T): string; new (x: number): T; }) => { new (x: T): string; new (x: number): T; } +>T : T +>cb : { new (x: T): string; new (x: number): T; } +>x : T +>T : T +>x : number +>T : T + + return cb; +>cb : { new (x: T): string; new (x: number): T; } + } + + var a: { +>a : { new (x: boolean): string; new (x: number): boolean; } + + new (x: boolean): string; +>x : boolean + + new (x: number): boolean; +>x : number + } + var r5 = foo5(a); // new{} => string; new(x:number) => {} +>r5 : { new (x: boolean): string; new (x: number): boolean; } +>foo5(a) : { new (x: boolean): string; new (x: number): boolean; } +>foo5 : (cb: { new (x: T): string; new (x: number): T; }) => { new (x: T): string; new (x: number): T; } +>a : { new (x: boolean): string; new (x: number): boolean; } + + var b: { new(x: T): string; new(x: number): T; } +>b : { new (x: T): string; new (x: number): T; } +>T : T +>x : T +>T : T +>T : T +>x : number +>T : T + + var r7 = foo5(b); // new any => string; new(x:number) => any +>r7 : { new (x: any): string; new (x: number): any; } +>foo5(b) : { new (x: any): string; new (x: number): any; } +>foo5 : (cb: { new (x: T): string; new (x: number): T; }) => { new (x: T): string; new (x: number): T; } +>b : { new (x: T): string; new (x: number): T; } + + function foo6(cb: { new(x: T): string; new(x: T, y?: T): string }) { +>foo6 : (cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } +>T : T +>cb : { new (x: T): string; new (x: T, y?: T): string; } +>x : T +>T : T +>x : T +>T : T +>y : T +>T : T + + return cb; +>cb : { new (x: T): string; new (x: T, y?: T): string; } + } + + var r8 = foo6(a); // error +>r8 : { new (x: boolean): string; new (x: boolean, y?: boolean): string; } +>foo6(a) : { new (x: boolean): string; new (x: boolean, y?: boolean): string; } +>foo6 : (cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } +>a : { new (x: boolean): string; new (x: number): boolean; } + + var r9 = foo6(b); // new any => string; new(x:any, y?:any) => string +>r9 : { new (x: any): string; new (x: any, y?: any): string; } +>foo6(b) : { new (x: any): string; new (x: any, y?: any): string; } +>foo6 : (cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } +>b : { new (x: T): string; new (x: number): T; } + + function foo7(x:T, cb: { new(x: T): string; new(x: T, y?: T): string }) { +>foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } +>T : T +>x : T +>T : T +>cb : { new (x: T): string; new (x: T, y?: T): string; } +>x : T +>T : T +>x : T +>T : T +>y : T +>T : T + + return cb; +>cb : { new (x: T): string; new (x: T, y?: T): string; } + } + + var r13 = foo7(1, b); // new any => string; new(x:any, y?:any) => string +>r13 : { new (x: any): string; new (x: any, y?: any): string; } +>foo7(1, b) : { new (x: any): string; new (x: any, y?: any): string; } +>foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } +>1 : 1 +>b : { new (x: T): string; new (x: number): T; } + + var c: { new (x: T): string; (x: number): T; } +>c : { (x: number): T; new (x: T): string; } +>T : T +>x : T +>T : T +>T : T +>x : number +>T : T + + var c2: { new (x: T): string; new(x: number): T; } +>c2 : { new (x: T): string; new (x: number): T; } +>T : T +>x : T +>T : T +>T : T +>x : number +>T : T + + var r14 = foo7(1, c); // new any => string; new(x:any, y?:any) => string +>r14 : { new (x: any): string; new (x: any, y?: any): string; } +>foo7(1, c) : { new (x: any): string; new (x: any, y?: any): string; } +>foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } +>1 : 1 +>c : { (x: number): T; new (x: T): string; } + + var r15 = foo7(1, c2); // new any => string; new(x:any, y?:any) => string +>r15 : { new (x: any): string; new (x: any, y?: any): string; } +>foo7(1, c2) : { new (x: any): string; new (x: any, y?: any): string; } +>foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } +>1 : 1 +>c2 : { new (x: T): string; new (x: number): T; } +} diff --git a/tests/baselines/reference/genericClassWithFunctionTypedMemberArguments.errors.txt b/tests/baselines/reference/genericClassWithFunctionTypedMemberArguments.errors.txt index bcfa8d8fbf9..c44a1e155ac 100644 --- a/tests/baselines/reference/genericClassWithFunctionTypedMemberArguments.errors.txt +++ b/tests/baselines/reference/genericClassWithFunctionTypedMemberArguments.errors.txt @@ -1,11 +1,14 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts(57,19): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. -tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts(60,19): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. -tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts(61,20): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. -tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts(62,19): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts(57,29): error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. + Types of parameters 'x' and 'a' are incompatible. + Type '1' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts(60,30): error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. + Types of parameters 'x' and 'a' are incompatible. + Type '1' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts(61,31): error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. + Types of parameters 'x' and 'a' are incompatible. + Type '1' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts(62,30): error TS2345: Argument of type '(a: number) => string' is not assignable to parameter of type '(a: number) => 1'. + Type 'string' is not assignable to type '1'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFunctionTypedMemberArguments.ts (4 errors) ==== @@ -66,22 +69,25 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericClassWithFu function other(t: T, u: U) { var r10 = c.foo2(1, (x: T) => ''); // error - ~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. +!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. +!!! error TS2345: Type '1' is not assignable to type 'T'. var r10 = c.foo2(1, (x) => ''); // string var r11 = c3.foo3(1, (x: T) => '', ''); // error - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. +!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. +!!! error TS2345: Type '1' is not assignable to type 'T'. var r11b = c3.foo3(1, (x: T) => '', 1); // error - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'T'. + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(x: T) => string' is not assignable to parameter of type '(a: 1) => string'. +!!! error TS2345: Types of parameters 'x' and 'a' are incompatible. +!!! error TS2345: Type '1' is not assignable to type 'T'. var r12 = c3.foo3(1, function (a) { return '' }, 1); // error - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~~~~~~~ +!!! error TS2345: Argument of type '(a: number) => string' is not assignable to parameter of type '(a: number) => 1'. +!!! error TS2345: Type 'string' is not assignable to type '1'. } } \ No newline at end of file diff --git a/tests/baselines/reference/genericContextualTypes1.js b/tests/baselines/reference/genericContextualTypes1.js new file mode 100644 index 00000000000..94724123330 --- /dev/null +++ b/tests/baselines/reference/genericContextualTypes1.js @@ -0,0 +1,107 @@ +//// [genericContextualTypes1.ts] +type Box = { value: T }; + +declare function wrap(f: (a: A) => B): (a: A) => B; + +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; + +declare function list(a: T): T[]; + +declare function unlist(a: T[]): T; + +declare function box(x: V): Box; + +declare function unbox(x: Box): W; + +declare function map(a: T[], f: (x: T) => U): U[]; + +declare function identity(x: T): T; + +declare function zip(a: A, b: B): [A, B]; + +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; + +const f00: (x: A) => A[] = list; +const f01: (x: A) => A[] = x => [x]; +const f02: (x: A) => A[] = wrap(list); +const f03: (x: A) => A[] = wrap(x => [x]); + +const f10: (x: T) => Box = compose(a => list(a), b => box(b)); +const f11: (x: T) => Box = compose(list, box); +const f12: (x: Box) => T = compose(a => unbox(a), b => unlist(b)); +const f13: (x: Box) => T = compose(unbox, unlist); + +const arrayMap = (f: (x: T) => U) => (a: T[]) => a.map(f); +const arrayFilter = (f: (x: T) => boolean) => (a: T[]) => a.filter(f); + +const f20: (a: string[]) => number[] = arrayMap(x => x.length); +const f21: (a: A[]) => A[][] = arrayMap(x => [x]); +const f22: (a: A[]) => A[] = arrayMap(identity); +const f23: (a: A[]) => Box[] = arrayMap(value => ({ value })); + +const f30: (a: string[]) => string[] = arrayFilter(x => x.length > 10); +const f31: >(a: T[]) => T[] = arrayFilter(x => x.value > 10); + +const f40: (b: B, a: A) => [A, B] = flip(zip); + +// Repro from #16293 + +type fn = (a: A) => A; +const fn: fn = a => a; + + +//// [genericContextualTypes1.js] +"use strict"; +var f00 = list; +var f01 = function (x) { return [x]; }; +var f02 = wrap(list); +var f03 = wrap(function (x) { return [x]; }); +var f10 = compose(function (a) { return list(a); }, function (b) { return box(b); }); +var f11 = compose(list, box); +var f12 = compose(function (a) { return unbox(a); }, function (b) { return unlist(b); }); +var f13 = compose(unbox, unlist); +var arrayMap = function (f) { return function (a) { return a.map(f); }; }; +var arrayFilter = function (f) { return function (a) { return a.filter(f); }; }; +var f20 = arrayMap(function (x) { return x.length; }); +var f21 = arrayMap(function (x) { return [x]; }); +var f22 = arrayMap(identity); +var f23 = arrayMap(function (value) { return ({ value: value }); }); +var f30 = arrayFilter(function (x) { return x.length > 10; }); +var f31 = arrayFilter(function (x) { return x.value > 10; }); +var f40 = flip(zip); +var fn = function (a) { return a; }; + + +//// [genericContextualTypes1.d.ts] +declare type Box = { + value: T; +}; +declare function wrap(f: (a: A) => B): (a: A) => B; +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; +declare function list(a: T): T[]; +declare function unlist(a: T[]): T; +declare function box(x: V): Box; +declare function unbox(x: Box): W; +declare function map(a: T[], f: (x: T) => U): U[]; +declare function identity(x: T): T; +declare function zip(a: A, b: B): [A, B]; +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; +declare const f00: (x: A) => A[]; +declare const f01: (x: A) => A[]; +declare const f02: (x: A) => A[]; +declare const f03: (x: A) => A[]; +declare const f10: (x: T) => Box; +declare const f11: (x: T) => Box; +declare const f12: (x: Box) => T; +declare const f13: (x: Box) => T; +declare const arrayMap: (f: (x: T) => U) => (a: T[]) => U[]; +declare const arrayFilter: (f: (x: T) => boolean) => (a: T[]) => T[]; +declare const f20: (a: string[]) => number[]; +declare const f21: (a: A[]) => A[][]; +declare const f22: (a: A[]) => A[]; +declare const f23: (a: A[]) => Box[]; +declare const f30: (a: string[]) => string[]; +declare const f31: >(a: T[]) => T[]; +declare const f40: (b: B, a: A) => [A, B]; +declare type fn = (a: A) => A; +declare const fn: fn; diff --git a/tests/baselines/reference/genericContextualTypes1.symbols b/tests/baselines/reference/genericContextualTypes1.symbols new file mode 100644 index 00000000000..29d8766abca --- /dev/null +++ b/tests/baselines/reference/genericContextualTypes1.symbols @@ -0,0 +1,318 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericContextualTypes1.ts === +type Box = { value: T }; +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 0, 9)) +>value : Symbol(value, Decl(genericContextualTypes1.ts, 0, 15)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 0, 9)) + +declare function wrap(f: (a: A) => B): (a: A) => B; +>wrap : Symbol(wrap, Decl(genericContextualTypes1.ts, 0, 27)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 2, 22)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 2, 24)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 2, 28)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 2, 32)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 2, 22)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 2, 24)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 2, 46)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 2, 22)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 2, 24)) + +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 4, 25)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 4, 27)) +>C : Symbol(C, Decl(genericContextualTypes1.ts, 4, 30)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 4, 34)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 4, 38)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 4, 25)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 4, 27)) +>g : Symbol(g, Decl(genericContextualTypes1.ts, 4, 49)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 4, 54)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 4, 27)) +>C : Symbol(C, Decl(genericContextualTypes1.ts, 4, 30)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 4, 68)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 4, 25)) +>C : Symbol(C, Decl(genericContextualTypes1.ts, 4, 30)) + +declare function list(a: T): T[]; +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 6, 22)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 6, 25)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 6, 22)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 6, 22)) + +declare function unlist(a: T[]): T; +>unlist : Symbol(unlist, Decl(genericContextualTypes1.ts, 6, 36)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 8, 24)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 8, 27)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 8, 24)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 8, 24)) + +declare function box(x: V): Box; +>box : Symbol(box, Decl(genericContextualTypes1.ts, 8, 38)) +>V : Symbol(V, Decl(genericContextualTypes1.ts, 10, 21)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 10, 24)) +>V : Symbol(V, Decl(genericContextualTypes1.ts, 10, 21)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>V : Symbol(V, Decl(genericContextualTypes1.ts, 10, 21)) + +declare function unbox(x: Box): W; +>unbox : Symbol(unbox, Decl(genericContextualTypes1.ts, 10, 38)) +>W : Symbol(W, Decl(genericContextualTypes1.ts, 12, 23)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 12, 26)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>W : Symbol(W, Decl(genericContextualTypes1.ts, 12, 23)) +>W : Symbol(W, Decl(genericContextualTypes1.ts, 12, 23)) + +declare function map(a: T[], f: (x: T) => U): U[]; +>map : Symbol(map, Decl(genericContextualTypes1.ts, 12, 40)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 14, 21)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 14, 23)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 14, 27)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 14, 21)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 14, 34)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 14, 39)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 14, 21)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 14, 23)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 14, 23)) + +declare function identity(x: T): T; +>identity : Symbol(identity, Decl(genericContextualTypes1.ts, 14, 56)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 16, 26)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 16, 29)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 16, 26)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 16, 26)) + +declare function zip(a: A, b: B): [A, B]; +>zip : Symbol(zip, Decl(genericContextualTypes1.ts, 16, 38)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 18, 21)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 18, 23)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 18, 27)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 18, 21)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 18, 32)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 18, 23)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 18, 21)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 18, 23)) + +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; +>flip : Symbol(flip, Decl(genericContextualTypes1.ts, 18, 47)) +>X : Symbol(X, Decl(genericContextualTypes1.ts, 20, 22)) +>Y : Symbol(Y, Decl(genericContextualTypes1.ts, 20, 24)) +>Z : Symbol(Z, Decl(genericContextualTypes1.ts, 20, 27)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 20, 31)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 20, 35)) +>X : Symbol(X, Decl(genericContextualTypes1.ts, 20, 22)) +>y : Symbol(y, Decl(genericContextualTypes1.ts, 20, 40)) +>Y : Symbol(Y, Decl(genericContextualTypes1.ts, 20, 24)) +>Z : Symbol(Z, Decl(genericContextualTypes1.ts, 20, 27)) +>y : Symbol(y, Decl(genericContextualTypes1.ts, 20, 55)) +>Y : Symbol(Y, Decl(genericContextualTypes1.ts, 20, 24)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 20, 60)) +>X : Symbol(X, Decl(genericContextualTypes1.ts, 20, 22)) +>Z : Symbol(Z, Decl(genericContextualTypes1.ts, 20, 27)) + +const f00: (x: A) => A[] = list; +>f00 : Symbol(f00, Decl(genericContextualTypes1.ts, 22, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 22, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 22, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 22, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 22, 12)) +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) + +const f01: (x: A) => A[] = x => [x]; +>f01 : Symbol(f01, Decl(genericContextualTypes1.ts, 23, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 23, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 23, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 23, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 23, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 23, 29)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 23, 29)) + +const f02: (x: A) => A[] = wrap(list); +>f02 : Symbol(f02, Decl(genericContextualTypes1.ts, 24, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 24, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 24, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 24, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 24, 12)) +>wrap : Symbol(wrap, Decl(genericContextualTypes1.ts, 0, 27)) +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) + +const f03: (x: A) => A[] = wrap(x => [x]); +>f03 : Symbol(f03, Decl(genericContextualTypes1.ts, 25, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 25, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 25, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 25, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 25, 12)) +>wrap : Symbol(wrap, Decl(genericContextualTypes1.ts, 0, 27)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 25, 35)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 25, 35)) + +const f10: (x: T) => Box = compose(a => list(a), b => box(b)); +>f10 : Symbol(f10, Decl(genericContextualTypes1.ts, 27, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 27, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 27, 15)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 27, 12)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 27, 12)) +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 27, 43)) +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 27, 43)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 27, 56)) +>box : Symbol(box, Decl(genericContextualTypes1.ts, 8, 38)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 27, 56)) + +const f11: (x: T) => Box = compose(list, box); +>f11 : Symbol(f11, Decl(genericContextualTypes1.ts, 28, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 28, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 28, 15)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 28, 12)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 28, 12)) +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) +>box : Symbol(box, Decl(genericContextualTypes1.ts, 8, 38)) + +const f12: (x: Box) => T = compose(a => unbox(a), b => unlist(b)); +>f12 : Symbol(f12, Decl(genericContextualTypes1.ts, 29, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 29, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 29, 15)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 29, 12)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 29, 12)) +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 29, 43)) +>unbox : Symbol(unbox, Decl(genericContextualTypes1.ts, 10, 38)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 29, 43)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 29, 57)) +>unlist : Symbol(unlist, Decl(genericContextualTypes1.ts, 6, 36)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 29, 57)) + +const f13: (x: Box) => T = compose(unbox, unlist); +>f13 : Symbol(f13, Decl(genericContextualTypes1.ts, 30, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 30, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 30, 15)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 30, 12)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 30, 12)) +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>unbox : Symbol(unbox, Decl(genericContextualTypes1.ts, 10, 38)) +>unlist : Symbol(unlist, Decl(genericContextualTypes1.ts, 6, 36)) + +const arrayMap = (f: (x: T) => U) => (a: T[]) => a.map(f); +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 32, 18)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 32, 20)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 32, 24)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 32, 28)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 32, 18)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 32, 20)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 32, 44)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 32, 18)) +>a.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 32, 44)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 32, 24)) + +const arrayFilter = (f: (x: T) => boolean) => (a: T[]) => a.filter(f); +>arrayFilter : Symbol(arrayFilter, Decl(genericContextualTypes1.ts, 33, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 33, 21)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 33, 24)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 33, 28)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 33, 21)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 33, 50)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 33, 21)) +>a.filter : Symbol(Array.filter, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 33, 50)) +>filter : Symbol(Array.filter, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 33, 24)) + +const f20: (a: string[]) => number[] = arrayMap(x => x.length); +>f20 : Symbol(f20, Decl(genericContextualTypes1.ts, 35, 5)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 35, 12)) +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 35, 48)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 35, 48)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +const f21: (a: A[]) => A[][] = arrayMap(x => [x]); +>f21 : Symbol(f21, Decl(genericContextualTypes1.ts, 36, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 36, 12)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 36, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 36, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 36, 12)) +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 36, 43)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 36, 43)) + +const f22: (a: A[]) => A[] = arrayMap(identity); +>f22 : Symbol(f22, Decl(genericContextualTypes1.ts, 37, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 37, 12)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 37, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 37, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 37, 12)) +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>identity : Symbol(identity, Decl(genericContextualTypes1.ts, 14, 56)) + +const f23: (a: A[]) => Box[] = arrayMap(value => ({ value })); +>f23 : Symbol(f23, Decl(genericContextualTypes1.ts, 38, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 38, 12)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 38, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 38, 12)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 38, 12)) +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>value : Symbol(value, Decl(genericContextualTypes1.ts, 38, 46)) +>value : Symbol(value, Decl(genericContextualTypes1.ts, 38, 57)) + +const f30: (a: string[]) => string[] = arrayFilter(x => x.length > 10); +>f30 : Symbol(f30, Decl(genericContextualTypes1.ts, 40, 5)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 40, 12)) +>arrayFilter : Symbol(arrayFilter, Decl(genericContextualTypes1.ts, 33, 5)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 40, 51)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 40, 51)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +const f31: >(a: T[]) => T[] = arrayFilter(x => x.value > 10); +>f31 : Symbol(f31, Decl(genericContextualTypes1.ts, 41, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 41, 12)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 41, 35)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 41, 12)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 41, 12)) +>arrayFilter : Symbol(arrayFilter, Decl(genericContextualTypes1.ts, 33, 5)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 41, 64)) +>x.value : Symbol(value, Decl(genericContextualTypes1.ts, 0, 15)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 41, 64)) +>value : Symbol(value, Decl(genericContextualTypes1.ts, 0, 15)) + +const f40: (b: B, a: A) => [A, B] = flip(zip); +>f40 : Symbol(f40, Decl(genericContextualTypes1.ts, 43, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 43, 12)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 43, 14)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 43, 18)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 43, 14)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 43, 23)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 43, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 43, 12)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 43, 14)) +>flip : Symbol(flip, Decl(genericContextualTypes1.ts, 18, 47)) +>zip : Symbol(zip, Decl(genericContextualTypes1.ts, 16, 38)) + +// Repro from #16293 + +type fn = (a: A) => A; +>fn : Symbol(fn, Decl(genericContextualTypes1.ts, 43, 52), Decl(genericContextualTypes1.ts, 48, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 47, 11)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 47, 14)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 47, 11)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 47, 11)) + +const fn: fn = a => a; +>fn : Symbol(fn, Decl(genericContextualTypes1.ts, 43, 52), Decl(genericContextualTypes1.ts, 48, 5)) +>fn : Symbol(fn, Decl(genericContextualTypes1.ts, 43, 52), Decl(genericContextualTypes1.ts, 48, 5)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 48, 14)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 48, 14)) + diff --git a/tests/baselines/reference/genericContextualTypes1.types b/tests/baselines/reference/genericContextualTypes1.types new file mode 100644 index 00000000000..b1a7aff8eef --- /dev/null +++ b/tests/baselines/reference/genericContextualTypes1.types @@ -0,0 +1,362 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericContextualTypes1.ts === +type Box = { value: T }; +>Box : Box +>T : T +>value : T +>T : T + +declare function wrap(f: (a: A) => B): (a: A) => B; +>wrap : (f: (a: A) => B) => (a: A) => B +>A : A +>B : B +>f : (a: A) => B +>a : A +>A : A +>B : B +>a : A +>A : A +>B : B + +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>A : A +>B : B +>C : C +>f : (a: A) => B +>a : A +>A : A +>B : B +>g : (b: B) => C +>b : B +>B : B +>C : C +>a : A +>A : A +>C : C + +declare function list(a: T): T[]; +>list : (a: T) => T[] +>T : T +>a : T +>T : T +>T : T + +declare function unlist(a: T[]): T; +>unlist : (a: T[]) => T +>T : T +>a : T[] +>T : T +>T : T + +declare function box(x: V): Box; +>box : (x: V) => Box +>V : V +>x : V +>V : V +>Box : Box +>V : V + +declare function unbox(x: Box): W; +>unbox : (x: Box) => W +>W : W +>x : Box +>Box : Box +>W : W +>W : W + +declare function map(a: T[], f: (x: T) => U): U[]; +>map : (a: T[], f: (x: T) => U) => U[] +>T : T +>U : U +>a : T[] +>T : T +>f : (x: T) => U +>x : T +>T : T +>U : U +>U : U + +declare function identity(x: T): T; +>identity : (x: T) => T +>T : T +>x : T +>T : T +>T : T + +declare function zip(a: A, b: B): [A, B]; +>zip : (a: A, b: B) => [A, B] +>A : A +>B : B +>a : A +>A : A +>b : B +>B : B +>A : A +>B : B + +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; +>flip : (f: (x: X, y: Y) => Z) => (y: Y, x: X) => Z +>X : X +>Y : Y +>Z : Z +>f : (x: X, y: Y) => Z +>x : X +>X : X +>y : Y +>Y : Y +>Z : Z +>y : Y +>Y : Y +>x : X +>X : X +>Z : Z + +const f00: (x: A) => A[] = list; +>f00 : (x: A) => A[] +>A : A +>x : A +>A : A +>A : A +>list : (a: T) => T[] + +const f01: (x: A) => A[] = x => [x]; +>f01 : (x: A) => A[] +>A : A +>x : A +>A : A +>A : A +>x => [x] : (x: A) => A[] +>x : A +>[x] : A[] +>x : A + +const f02: (x: A) => A[] = wrap(list); +>f02 : (x: A) => A[] +>A : A +>x : A +>A : A +>A : A +>wrap(list) : (a: A) => A[] +>wrap : (f: (a: A) => B) => (a: A) => B +>list : (a: T) => T[] + +const f03: (x: A) => A[] = wrap(x => [x]); +>f03 : (x: A) => A[] +>A : A +>x : A +>A : A +>A : A +>wrap(x => [x]) : (a: A) => A[] +>wrap : (f: (a: A) => B) => (a: A) => B +>x => [x] : (x: A) => A[] +>x : A +>[x] : A[] +>x : A + +const f10: (x: T) => Box = compose(a => list(a), b => box(b)); +>f10 : (x: T) => Box +>T : T +>x : T +>T : T +>Box : Box +>T : T +>compose(a => list(a), b => box(b)) : (a: T) => Box +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>a => list(a) : (a: T) => T[] +>a : T +>list(a) : T[] +>list : (a: T) => T[] +>a : T +>b => box(b) : (b: T[]) => Box +>b : T[] +>box(b) : Box +>box : (x: V) => Box +>b : T[] + +const f11: (x: T) => Box = compose(list, box); +>f11 : (x: T) => Box +>T : T +>x : T +>T : T +>Box : Box +>T : T +>compose(list, box) : (a: T) => Box +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>list : (a: T) => T[] +>box : (x: V) => Box + +const f12: (x: Box) => T = compose(a => unbox(a), b => unlist(b)); +>f12 : (x: Box) => T +>T : T +>x : Box +>Box : Box +>T : T +>T : T +>compose(a => unbox(a), b => unlist(b)) : (a: Box) => T +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>a => unbox(a) : (a: Box) => T[] +>a : Box +>unbox(a) : T[] +>unbox : (x: Box) => W +>a : Box +>b => unlist(b) : (b: T[]) => T +>b : T[] +>unlist(b) : T +>unlist : (a: T[]) => T +>b : T[] + +const f13: (x: Box) => T = compose(unbox, unlist); +>f13 : (x: Box) => T +>T : T +>x : Box +>Box : Box +>T : T +>T : T +>compose(unbox, unlist) : (a: Box) => T +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>unbox : (x: Box) => W +>unlist : (a: T[]) => T + +const arrayMap = (f: (x: T) => U) => (a: T[]) => a.map(f); +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>(f: (x: T) => U) => (a: T[]) => a.map(f) : (f: (x: T) => U) => (a: T[]) => U[] +>T : T +>U : U +>f : (x: T) => U +>x : T +>T : T +>U : U +>(a: T[]) => a.map(f) : (a: T[]) => U[] +>a : T[] +>T : T +>a.map(f) : U[] +>a.map : (callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[] +>a : T[] +>map : (callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[] +>f : (x: T) => U + +const arrayFilter = (f: (x: T) => boolean) => (a: T[]) => a.filter(f); +>arrayFilter : (f: (x: T) => boolean) => (a: T[]) => T[] +>(f: (x: T) => boolean) => (a: T[]) => a.filter(f) : (f: (x: T) => boolean) => (a: T[]) => T[] +>T : T +>f : (x: T) => boolean +>x : T +>T : T +>(a: T[]) => a.filter(f) : (a: T[]) => T[] +>a : T[] +>T : T +>a.filter(f) : T[] +>a.filter : { (callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; } +>a : T[] +>filter : { (callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; } +>f : (x: T) => boolean + +const f20: (a: string[]) => number[] = arrayMap(x => x.length); +>f20 : (a: string[]) => number[] +>a : string[] +>arrayMap(x => x.length) : (a: string[]) => number[] +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>x => x.length : (x: string) => number +>x : string +>x.length : number +>x : string +>length : number + +const f21: (a: A[]) => A[][] = arrayMap(x => [x]); +>f21 : (a: A[]) => A[][] +>A : A +>a : A[] +>A : A +>A : A +>arrayMap(x => [x]) : (a: A[]) => A[][] +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>x => [x] : (x: A) => A[] +>x : A +>[x] : A[] +>x : A + +const f22: (a: A[]) => A[] = arrayMap(identity); +>f22 : (a: A[]) => A[] +>A : A +>a : A[] +>A : A +>A : A +>arrayMap(identity) : (a: A[]) => A[] +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>identity : (x: T) => T + +const f23: (a: A[]) => Box[] = arrayMap(value => ({ value })); +>f23 : (a: A[]) => Box[] +>A : A +>a : A[] +>A : A +>Box : Box +>A : A +>arrayMap(value => ({ value })) : (a: A[]) => { value: A; }[] +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>value => ({ value }) : (value: A) => { value: A; } +>value : A +>({ value }) : { value: A; } +>{ value } : { value: A; } +>value : A + +const f30: (a: string[]) => string[] = arrayFilter(x => x.length > 10); +>f30 : (a: string[]) => string[] +>a : string[] +>arrayFilter(x => x.length > 10) : (a: string[]) => string[] +>arrayFilter : (f: (x: T) => boolean) => (a: T[]) => T[] +>x => x.length > 10 : (x: string) => boolean +>x : string +>x.length > 10 : boolean +>x.length : number +>x : string +>length : number +>10 : 10 + +const f31: >(a: T[]) => T[] = arrayFilter(x => x.value > 10); +>f31 : >(a: T[]) => T[] +>T : T +>Box : Box +>a : T[] +>T : T +>T : T +>arrayFilter(x => x.value > 10) : (a: T[]) => T[] +>arrayFilter : (f: (x: T) => boolean) => (a: T[]) => T[] +>x => x.value > 10 : (x: T) => boolean +>x : T +>x.value > 10 : boolean +>x.value : number +>x : T +>value : number +>10 : 10 + +const f40: (b: B, a: A) => [A, B] = flip(zip); +>f40 : (b: B, a: A) => [A, B] +>A : A +>B : B +>b : B +>B : B +>a : A +>A : A +>A : A +>B : B +>flip(zip) : (y: B, x: A) => [A, B] +>flip : (f: (x: X, y: Y) => Z) => (y: Y, x: X) => Z +>zip : (a: A, b: B) => [A, B] + +// Repro from #16293 + +type fn = (a: A) => A; +>fn : fn +>A : A +>a : A +>A : A +>A : A + +const fn: fn = a => a; +>fn : fn +>fn : fn +>a => a : (a: A) => A +>a : A +>a : A + diff --git a/tests/baselines/reference/genericDefaults.js b/tests/baselines/reference/genericDefaults.js index 45d889fc49c..06503b89d58 100644 --- a/tests/baselines/reference/genericDefaults.js +++ b/tests/baselines/reference/genericDefaults.js @@ -458,6 +458,15 @@ const Derived02c01 = new Derived02(1); const Derived02c02 = new Derived02(); const Derived02c03 = new Derived02(1); +// https://github.com/Microsoft/TypeScript/issues/16211 +interface Base02 {} +interface Base02Constructor { new (a: T): Base02 & T; } +declare const Base02: Base02Constructor; +declare class Derived03 extends Base02 {} +const Derived03c00 = new Derived03(ab); +const Derived03c01 = Derived03c00.a; +type DerivedProps = keyof Derived03; + type t00 = { a: T; } const t00c00 = (x).a; const t00c01 = (>x).a; @@ -478,8 +487,7 @@ const t03c00 = (>x).a; const t03c01 = (>x).a; const t03c02 = (>x).a; const t03c03 = (>x).a; -const t03c04 = (>x).a; - +const t03c04 = (>x).a; //// [genericDefaults.js] // no inference @@ -834,6 +842,8 @@ var Derived02c00 = new Derived02(); var Derived02c01 = new Derived02(1); var Derived02c02 = new Derived02(); var Derived02c03 = new Derived02(1); +var Derived03c00 = new Derived03(ab); +var Derived03c01 = Derived03c00.a; var t00c00 = x.a; var t00c01 = x.a; var t01c00 = x.a; @@ -977,6 +987,17 @@ declare const Derived02c00: Derived02; declare const Derived02c01: Derived02; declare const Derived02c02: Derived02; declare const Derived02c03: Derived02; +interface Base02 { +} +interface Base02Constructor { + new (a: T): Base02 & T; +} +declare const Base02: Base02Constructor; +declare class Derived03 extends Base02 { +} +declare const Derived03c00: Derived03; +declare const Derived03c01: number; +declare type DerivedProps = keyof Derived03; declare type t00 = { a: T; }; diff --git a/tests/baselines/reference/genericDefaults.symbols b/tests/baselines/reference/genericDefaults.symbols index 2250e9ea95a..6c9e97b265e 100644 --- a/tests/baselines/reference/genericDefaults.symbols +++ b/tests/baselines/reference/genericDefaults.symbols @@ -2123,135 +2123,171 @@ const Derived02c03 = new Derived02(1); >Derived02c03 : Symbol(Derived02c03, Decl(genericDefaults.ts, 457, 5)) >Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 451, 46)) +// https://github.com/Microsoft/TypeScript/issues/16211 +interface Base02 {} +>Base02 : Symbol(Base02, Decl(genericDefaults.ts, 457, 46), Decl(genericDefaults.ts, 462, 13)) + +interface Base02Constructor { new (a: T): Base02 & T; } +>Base02Constructor : Symbol(Base02Constructor, Decl(genericDefaults.ts, 460, 19)) +>T : Symbol(T, Decl(genericDefaults.ts, 461, 35)) +>A : Symbol(A, Decl(genericDefaults.ts, 0, 0)) +>a : Symbol(a, Decl(genericDefaults.ts, 461, 42)) +>T : Symbol(T, Decl(genericDefaults.ts, 461, 35)) +>Base02 : Symbol(Base02, Decl(genericDefaults.ts, 457, 46), Decl(genericDefaults.ts, 462, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 461, 35)) + +declare const Base02: Base02Constructor; +>Base02 : Symbol(Base02, Decl(genericDefaults.ts, 457, 46), Decl(genericDefaults.ts, 462, 13)) +>Base02Constructor : Symbol(Base02Constructor, Decl(genericDefaults.ts, 460, 19)) + +declare class Derived03 extends Base02 {} +>Derived03 : Symbol(Derived03, Decl(genericDefaults.ts, 462, 40)) +>Base02 : Symbol(Base02, Decl(genericDefaults.ts, 457, 46), Decl(genericDefaults.ts, 462, 13)) + +const Derived03c00 = new Derived03(ab); +>Derived03c00 : Symbol(Derived03c00, Decl(genericDefaults.ts, 464, 5)) +>Derived03 : Symbol(Derived03, Decl(genericDefaults.ts, 462, 40)) +>ab : Symbol(ab, Decl(genericDefaults.ts, 11, 13)) + +const Derived03c01 = Derived03c00.a; +>Derived03c01 : Symbol(Derived03c01, Decl(genericDefaults.ts, 465, 5)) +>Derived03c00.a : Symbol(A.a, Decl(genericDefaults.ts, 0, 13)) +>Derived03c00 : Symbol(Derived03c00, Decl(genericDefaults.ts, 464, 5)) +>a : Symbol(A.a, Decl(genericDefaults.ts, 0, 13)) + +type DerivedProps = keyof Derived03; +>DerivedProps : Symbol(DerivedProps, Decl(genericDefaults.ts, 465, 36)) +>Derived03 : Symbol(Derived03, Decl(genericDefaults.ts, 462, 40)) + type t00 = { a: T; } ->t00 : Symbol(t00, Decl(genericDefaults.ts, 457, 46)) ->T : Symbol(T, Decl(genericDefaults.ts, 459, 9)) ->a : Symbol(a, Decl(genericDefaults.ts, 459, 24)) ->T : Symbol(T, Decl(genericDefaults.ts, 459, 9)) +>t00 : Symbol(t00, Decl(genericDefaults.ts, 466, 36)) +>T : Symbol(T, Decl(genericDefaults.ts, 468, 9)) +>a : Symbol(a, Decl(genericDefaults.ts, 468, 24)) +>T : Symbol(T, Decl(genericDefaults.ts, 468, 9)) const t00c00 = (x).a; ->t00c00 : Symbol(t00c00, Decl(genericDefaults.ts, 460, 5)) ->(x).a : Symbol(a, Decl(genericDefaults.ts, 459, 24)) ->t00 : Symbol(t00, Decl(genericDefaults.ts, 457, 46)) +>t00c00 : Symbol(t00c00, Decl(genericDefaults.ts, 469, 5)) +>(x).a : Symbol(a, Decl(genericDefaults.ts, 468, 24)) +>t00 : Symbol(t00, Decl(genericDefaults.ts, 466, 36)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 459, 24)) +>a : Symbol(a, Decl(genericDefaults.ts, 468, 24)) const t00c01 = (>x).a; ->t00c01 : Symbol(t00c01, Decl(genericDefaults.ts, 461, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 459, 24)) ->t00 : Symbol(t00, Decl(genericDefaults.ts, 457, 46)) +>t00c01 : Symbol(t00c01, Decl(genericDefaults.ts, 470, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 468, 24)) +>t00 : Symbol(t00, Decl(genericDefaults.ts, 466, 36)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 459, 24)) +>a : Symbol(a, Decl(genericDefaults.ts, 468, 24)) type t01 = { a: [T, U]; } ->t01 : Symbol(t01, Decl(genericDefaults.ts, 461, 34)) ->T : Symbol(T, Decl(genericDefaults.ts, 463, 9)) ->U : Symbol(U, Decl(genericDefaults.ts, 463, 11)) ->T : Symbol(T, Decl(genericDefaults.ts, 463, 9)) ->a : Symbol(a, Decl(genericDefaults.ts, 463, 22)) ->T : Symbol(T, Decl(genericDefaults.ts, 463, 9)) ->U : Symbol(U, Decl(genericDefaults.ts, 463, 11)) +>t01 : Symbol(t01, Decl(genericDefaults.ts, 470, 34)) +>T : Symbol(T, Decl(genericDefaults.ts, 472, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 472, 11)) +>T : Symbol(T, Decl(genericDefaults.ts, 472, 9)) +>a : Symbol(a, Decl(genericDefaults.ts, 472, 22)) +>T : Symbol(T, Decl(genericDefaults.ts, 472, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 472, 11)) const t01c00 = (>x).a; ->t01c00 : Symbol(t01c00, Decl(genericDefaults.ts, 464, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 463, 22)) ->t01 : Symbol(t01, Decl(genericDefaults.ts, 461, 34)) +>t01c00 : Symbol(t01c00, Decl(genericDefaults.ts, 473, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 472, 22)) +>t01 : Symbol(t01, Decl(genericDefaults.ts, 470, 34)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 463, 22)) +>a : Symbol(a, Decl(genericDefaults.ts, 472, 22)) const t01c01 = (>x).a; ->t01c01 : Symbol(t01c01, Decl(genericDefaults.ts, 465, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 463, 22)) ->t01 : Symbol(t01, Decl(genericDefaults.ts, 461, 34)) +>t01c01 : Symbol(t01c01, Decl(genericDefaults.ts, 474, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 472, 22)) +>t01 : Symbol(t01, Decl(genericDefaults.ts, 470, 34)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 463, 22)) +>a : Symbol(a, Decl(genericDefaults.ts, 472, 22)) type t02 = { a: [T, U]; } ->t02 : Symbol(t02, Decl(genericDefaults.ts, 465, 42)) ->T : Symbol(T, Decl(genericDefaults.ts, 467, 9)) ->U : Symbol(U, Decl(genericDefaults.ts, 467, 26)) ->T : Symbol(T, Decl(genericDefaults.ts, 467, 9)) ->a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) ->T : Symbol(T, Decl(genericDefaults.ts, 467, 9)) ->U : Symbol(U, Decl(genericDefaults.ts, 467, 26)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 474, 42)) +>T : Symbol(T, Decl(genericDefaults.ts, 476, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 476, 26)) +>T : Symbol(T, Decl(genericDefaults.ts, 476, 9)) +>a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) +>T : Symbol(T, Decl(genericDefaults.ts, 476, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 476, 26)) const t02c00 = (>x).a; ->t02c00 : Symbol(t02c00, Decl(genericDefaults.ts, 468, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) ->t02 : Symbol(t02, Decl(genericDefaults.ts, 465, 42)) +>t02c00 : Symbol(t02c00, Decl(genericDefaults.ts, 477, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 474, 42)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) +>a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) const t02c01 = (>x).a; ->t02c01 : Symbol(t02c01, Decl(genericDefaults.ts, 469, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) ->t02 : Symbol(t02, Decl(genericDefaults.ts, 465, 42)) +>t02c01 : Symbol(t02c01, Decl(genericDefaults.ts, 478, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 474, 42)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) +>a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) const t02c02 = (>x).a; ->t02c02 : Symbol(t02c02, Decl(genericDefaults.ts, 470, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) ->t02 : Symbol(t02, Decl(genericDefaults.ts, 465, 42)) +>t02c02 : Symbol(t02c02, Decl(genericDefaults.ts, 479, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 474, 42)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) +>a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) const t02c03 = (>x).a; ->t02c03 : Symbol(t02c03, Decl(genericDefaults.ts, 471, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) ->t02 : Symbol(t02, Decl(genericDefaults.ts, 465, 42)) +>t02c03 : Symbol(t02c03, Decl(genericDefaults.ts, 480, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 474, 42)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) +>a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) const t02c04 = (>x).a; ->t02c04 : Symbol(t02c04, Decl(genericDefaults.ts, 472, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) ->t02 : Symbol(t02, Decl(genericDefaults.ts, 465, 42)) +>t02c04 : Symbol(t02c04, Decl(genericDefaults.ts, 481, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 474, 42)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 467, 37)) +>a : Symbol(a, Decl(genericDefaults.ts, 476, 37)) type t03 = { a: [T, U]; } ->t03 : Symbol(t03, Decl(genericDefaults.ts, 472, 37)) ->T : Symbol(T, Decl(genericDefaults.ts, 474, 9)) ->U : Symbol(U, Decl(genericDefaults.ts, 474, 26)) ->T : Symbol(T, Decl(genericDefaults.ts, 474, 9)) ->T : Symbol(T, Decl(genericDefaults.ts, 474, 9)) ->a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) ->T : Symbol(T, Decl(genericDefaults.ts, 474, 9)) ->U : Symbol(U, Decl(genericDefaults.ts, 474, 26)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 481, 37)) +>T : Symbol(T, Decl(genericDefaults.ts, 483, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 483, 26)) +>T : Symbol(T, Decl(genericDefaults.ts, 483, 9)) +>T : Symbol(T, Decl(genericDefaults.ts, 483, 9)) +>a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) +>T : Symbol(T, Decl(genericDefaults.ts, 483, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 483, 26)) const t03c00 = (>x).a; ->t03c00 : Symbol(t03c00, Decl(genericDefaults.ts, 475, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) ->t03 : Symbol(t03, Decl(genericDefaults.ts, 472, 37)) +>t03c00 : Symbol(t03c00, Decl(genericDefaults.ts, 484, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 481, 37)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) +>a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) const t03c01 = (>x).a; ->t03c01 : Symbol(t03c01, Decl(genericDefaults.ts, 476, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) ->t03 : Symbol(t03, Decl(genericDefaults.ts, 472, 37)) +>t03c01 : Symbol(t03c01, Decl(genericDefaults.ts, 485, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 481, 37)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) +>a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) const t03c02 = (>x).a; ->t03c02 : Symbol(t03c02, Decl(genericDefaults.ts, 477, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) ->t03 : Symbol(t03, Decl(genericDefaults.ts, 472, 37)) +>t03c02 : Symbol(t03c02, Decl(genericDefaults.ts, 486, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 481, 37)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) +>a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) const t03c03 = (>x).a; ->t03c03 : Symbol(t03c03, Decl(genericDefaults.ts, 478, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) ->t03 : Symbol(t03, Decl(genericDefaults.ts, 472, 37)) +>t03c03 : Symbol(t03c03, Decl(genericDefaults.ts, 487, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 481, 37)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) +>a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) const t03c04 = (>x).a; ->t03c04 : Symbol(t03c04, Decl(genericDefaults.ts, 479, 5)) ->(>x).a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) ->t03 : Symbol(t03, Decl(genericDefaults.ts, 472, 37)) +>t03c04 : Symbol(t03c04, Decl(genericDefaults.ts, 488, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 481, 37)) >x : Symbol(x, Decl(genericDefaults.ts, 13, 13)) ->a : Symbol(a, Decl(genericDefaults.ts, 474, 47)) +>a : Symbol(a, Decl(genericDefaults.ts, 483, 47)) diff --git a/tests/baselines/reference/genericDefaults.types b/tests/baselines/reference/genericDefaults.types index ef97847cc73..739588badb9 100644 --- a/tests/baselines/reference/genericDefaults.types +++ b/tests/baselines/reference/genericDefaults.types @@ -2446,6 +2446,43 @@ const Derived02c03 = new Derived02(1); >Derived02 : typeof Derived02 >1 : 1 +// https://github.com/Microsoft/TypeScript/issues/16211 +interface Base02 {} +>Base02 : Base02 + +interface Base02Constructor { new (a: T): Base02 & T; } +>Base02Constructor : Base02Constructor +>T : T +>A : A +>a : T +>T : T +>Base02 : Base02 +>T : T + +declare const Base02: Base02Constructor; +>Base02 : Base02Constructor +>Base02Constructor : Base02Constructor + +declare class Derived03 extends Base02 {} +>Derived03 : Derived03 +>Base02 : Base02 & A + +const Derived03c00 = new Derived03(ab); +>Derived03c00 : Derived03 +>new Derived03(ab) : Derived03 +>Derived03 : typeof Derived03 +>ab : AB + +const Derived03c01 = Derived03c00.a; +>Derived03c01 : number +>Derived03c00.a : number +>Derived03c00 : Derived03 +>a : number + +type DerivedProps = keyof Derived03; +>DerivedProps : "a" +>Derived03 : Derived03 + type t00 = { a: T; } >t00 : t00 >T : T diff --git a/tests/baselines/reference/genericFunctionCallSignatureReturnTypeMismatch.errors.txt b/tests/baselines/reference/genericFunctionCallSignatureReturnTypeMismatch.errors.txt index a1051e0b020..a0c5cbb4378 100644 --- a/tests/baselines/reference/genericFunctionCallSignatureReturnTypeMismatch.errors.txt +++ b/tests/baselines/reference/genericFunctionCallSignatureReturnTypeMismatch.errors.txt @@ -1,13 +1,18 @@ +tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts(6,1): error TS2322: Type '() => S[]' is not assignable to type '(x: T) => T'. + Type '{}[]' is not assignable to type 'T'. tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts(10,1): error TS2304: Cannot find name 'console'. -==== tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts (1 errors) ==== +==== tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts (2 errors) ==== interface Array {} var f : { (x:T): T; } var g : { () : S[]; }; f = g; + ~ +!!! error TS2322: Type '() => S[]' is not assignable to type '(x: T) => T'. +!!! error TS2322: Type '{}[]' is not assignable to type 'T'. var s = f("str").toUpperCase(); diff --git a/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types b/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types index 3a3afebb9ac..2c1a8177e0b 100644 --- a/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types +++ b/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types @@ -9,13 +9,13 @@ function f(p: (x: T) => void) { }; f(x => f(y => x = y)); >f(x => f(y => x = y)) : void >f : (p: (x: T) => void) => void ->x => f(y => x = y) : (x: any) => void ->x : any +>x => f(y => x = y) : (x: T) => void +>x : T >f(y => x = y) : void >f : (p: (x: T) => void) => void ->y => x = y : (y: any) => any ->y : any ->x = y : any ->x : any ->y : any +>y => x = y : (y: T) => T +>y : T +>x = y : T +>x : T +>y : T diff --git a/tests/baselines/reference/genericImplements.errors.txt b/tests/baselines/reference/genericImplements.errors.txt new file mode 100644 index 00000000000..7add57989ce --- /dev/null +++ b/tests/baselines/reference/genericImplements.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/genericImplements.ts(8,7): error TS2420: Class 'X' incorrectly implements interface 'I'. + Types of property 'f' are incompatible. + Type '() => T' is not assignable to type '() => T'. + Type 'B' is not assignable to type 'T'. + + +==== tests/cases/compiler/genericImplements.ts (1 errors) ==== + class A { a; }; + class B { b; }; + interface I { + f(): T; + } // { f: () => { a; } } + + // OK + class X implements I { + ~ +!!! error TS2420: Class 'X' incorrectly implements interface 'I'. +!!! error TS2420: Types of property 'f' are incompatible. +!!! error TS2420: Type '() => T' is not assignable to type '() => T'. +!!! error TS2420: Type 'B' is not assignable to type 'T'. + f(): T { return undefined; } + } // { f: () => { b; } } + + // OK + class Y implements I { + f(): T { return undefined; } + } // { f: () => { a; } } + + // OK + class Z implements I { + f(): T { return undefined; } + } // { f: () => T } \ No newline at end of file diff --git a/tests/baselines/reference/genericRestArgs.errors.txt b/tests/baselines/reference/genericRestArgs.errors.txt index 2297277fe8d..3c75cf392a5 100644 --- a/tests/baselines/reference/genericRestArgs.errors.txt +++ b/tests/baselines/reference/genericRestArgs.errors.txt @@ -1,17 +1,14 @@ -tests/cases/compiler/genericRestArgs.ts(2,12): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate '""'. +tests/cases/compiler/genericRestArgs.ts(2,26): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'. tests/cases/compiler/genericRestArgs.ts(5,34): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'. -tests/cases/compiler/genericRestArgs.ts(10,12): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate '""'. +tests/cases/compiler/genericRestArgs.ts(10,29): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'. tests/cases/compiler/genericRestArgs.ts(12,30): error TS2345: Argument of type '1' is not assignable to parameter of type 'any[]'. ==== tests/cases/compiler/genericRestArgs.ts (4 errors) ==== function makeArrayG(...items: T[]): T[] { return items; } var a1Ga = makeArrayG(1, ""); // no error - ~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate '""'. + ~~ +!!! error TS2345: Argument of type '""' is not assignable to parameter of type 'number'. var a1Gb = makeArrayG(1, ""); var a1Gc = makeArrayG(1, ""); var a1Gd = makeArrayG(1, ""); // error @@ -22,9 +19,8 @@ tests/cases/compiler/genericRestArgs.ts(12,30): error TS2345: Argument of type ' return [item1, item2, item3]; } var a2Ga = makeArrayGOpt(1, ""); - ~~~~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '1' is not a valid type argument because it is not a supertype of candidate '""'. + ~~ +!!! error TS2345: Argument of type '""' is not assignable to parameter of type 'number'. var a2Gb = makeArrayG(1, ""); var a2Gc = makeArrayG(1, ""); // error ~ diff --git a/tests/baselines/reference/genericSpecializations1.errors.txt b/tests/baselines/reference/genericSpecializations1.errors.txt new file mode 100644 index 00000000000..dd7e540661e --- /dev/null +++ b/tests/baselines/reference/genericSpecializations1.errors.txt @@ -0,0 +1,40 @@ +tests/cases/compiler/genericSpecializations1.ts(5,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. + Types of property 'foo' are incompatible. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/compiler/genericSpecializations1.ts(9,7): error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo'. + Types of property 'foo' are incompatible. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. + + +==== tests/cases/compiler/genericSpecializations1.ts (2 errors) ==== + interface IFoo { + foo(x: T): T; // no error on implementors because IFoo's T is different from foo's T + } + + class IntFooBad implements IFoo { + ~~~~~~~~~ +!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. +!!! error TS2420: Types of property 'foo' are incompatible. +!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2420: Type 'T' is not assignable to type 'string'. + foo(x: string): string { return null; } + } + + class StringFoo2 implements IFoo { + ~~~~~~~~~~ +!!! error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo'. +!!! error TS2420: Types of property 'foo' are incompatible. +!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2420: Type 'T' is not assignable to type 'string'. + foo(x: string): string { return null; } + } + + class StringFoo3 implements IFoo { + foo(x: T): T { return null; } + } \ No newline at end of file diff --git a/tests/baselines/reference/genericSpecializations2.errors.txt b/tests/baselines/reference/genericSpecializations2.errors.txt index 9d58731b6fb..e570adb7912 100644 --- a/tests/baselines/reference/genericSpecializations2.errors.txt +++ b/tests/baselines/reference/genericSpecializations2.errors.txt @@ -1,8 +1,18 @@ +tests/cases/compiler/genericSpecializations2.ts(7,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. + Types of property 'foo' are incompatible. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations2.ts(8,9): error TS2368: Type parameter name cannot be 'string'. +tests/cases/compiler/genericSpecializations2.ts(11,7): error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo'. + Types of property 'foo' are incompatible. + Type '(x: string) => string' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parameter name cannot be 'string'. -==== tests/cases/compiler/genericSpecializations2.ts (2 errors) ==== +==== tests/cases/compiler/genericSpecializations2.ts (4 errors) ==== class IFoo { foo(x: T): T { // no error on implementors because IFoo's T is different from foo's T return null; @@ -10,12 +20,24 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame } class IntFooBad implements IFoo { + ~~~~~~~~~ +!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo'. +!!! error TS2420: Types of property 'foo' are incompatible. +!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } ~~~~~~ !!! error TS2368: Type parameter name cannot be 'string'. } class StringFoo2 implements IFoo { + ~~~~~~~~~~ +!!! error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo'. +!!! error TS2420: Types of property 'foo' are incompatible. +!!! error TS2420: Type '(x: string) => string' is not assignable to type '(x: T) => T'. +!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2420: Type 'T' is not assignable to type 'string'. foo(x: string): string { return null; } ~~~~~~ !!! error TS2368: Type parameter name cannot be 'string'. diff --git a/tests/baselines/reference/genericTypeArgumentInference1.errors.txt b/tests/baselines/reference/genericTypeArgumentInference1.errors.txt new file mode 100644 index 00000000000..7054967a475 --- /dev/null +++ b/tests/baselines/reference/genericTypeArgumentInference1.errors.txt @@ -0,0 +1,26 @@ +tests/cases/compiler/genericTypeArgumentInference1.ts(12,39): error TS2345: Argument of type '(value: T) => T' is not assignable to parameter of type 'Iterator'. + Type 'string | number | boolean' is not assignable to type 'boolean'. + Type 'string' is not assignable to type 'boolean'. + + +==== tests/cases/compiler/genericTypeArgumentInference1.ts (1 errors) ==== + module Underscore { + export interface Iterator { + (value: T, index: any, list: any): U; + } + export interface Static { + all(list: T[], iterator?: Iterator, context?: any): T; + identity(value: T): T; + } + } + declare var _: Underscore.Static; + + var r = _.all([true, 1, null, 'yes'], _.identity); + ~~~~~~~~~~ +!!! error TS2345: Argument of type '(value: T) => T' is not assignable to parameter of type 'Iterator'. +!!! error TS2345: Type 'string | number | boolean' is not assignable to type 'boolean'. +!!! error TS2345: Type 'string' is not assignable to type 'boolean'. + var r2 = _.all([true], _.identity); + var r3 = _.all([], _.identity); + var r4 = _.all([true], _.identity); + \ No newline at end of file diff --git a/tests/baselines/reference/genericTypeAssertions3.types b/tests/baselines/reference/genericTypeAssertions3.types index 9f7facc8d47..2c1eb6b793b 100644 --- a/tests/baselines/reference/genericTypeAssertions3.types +++ b/tests/baselines/reference/genericTypeAssertions3.types @@ -6,9 +6,9 @@ var r = < (x: T) => T > ((x) => { return null; }); // bug was 'could not find >x : T >T : T >T : T ->((x) => { return null; }) : (x: any) => any ->(x) => { return null; } : (x: any) => any ->x : any +>((x) => { return null; }) : (x: T) => any +>(x) => { return null; } : (x: T) => any +>x : T >null : null var s = < (x: T) => T > ((x: any) => { return null; }); // no error diff --git a/tests/baselines/reference/implicitAnyGenericTypeInference.errors.txt b/tests/baselines/reference/implicitAnyGenericTypeInference.errors.txt deleted file mode 100644 index 0c64c3e6125..00000000000 --- a/tests/baselines/reference/implicitAnyGenericTypeInference.errors.txt +++ /dev/null @@ -1,16 +0,0 @@ -tests/cases/compiler/implicitAnyGenericTypeInference.ts(6,19): error TS7006: Parameter 'x' implicitly has an 'any' type. -tests/cases/compiler/implicitAnyGenericTypeInference.ts(6,22): error TS7006: Parameter 'y' implicitly has an 'any' type. - - -==== tests/cases/compiler/implicitAnyGenericTypeInference.ts (2 errors) ==== - interface Comparer { - compareTo(x: T, y: U): U; - } - - var c: Comparer; - c = { compareTo: (x, y) => { return y; } }; - ~ -!!! error TS7006: Parameter 'x' implicitly has an 'any' type. - ~ -!!! error TS7006: Parameter 'y' implicitly has an 'any' type. - var r = c.compareTo(1, ''); \ No newline at end of file diff --git a/tests/baselines/reference/implicitAnyGenericTypeInference.symbols b/tests/baselines/reference/implicitAnyGenericTypeInference.symbols new file mode 100644 index 00000000000..e56b68a7134 --- /dev/null +++ b/tests/baselines/reference/implicitAnyGenericTypeInference.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/implicitAnyGenericTypeInference.ts === +interface Comparer { +>Comparer : Symbol(Comparer, Decl(implicitAnyGenericTypeInference.ts, 0, 0)) +>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 0, 19)) + + compareTo(x: T, y: U): U; +>compareTo : Symbol(Comparer.compareTo, Decl(implicitAnyGenericTypeInference.ts, 0, 23)) +>U : Symbol(U, Decl(implicitAnyGenericTypeInference.ts, 1, 14)) +>x : Symbol(x, Decl(implicitAnyGenericTypeInference.ts, 1, 17)) +>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 0, 19)) +>y : Symbol(y, Decl(implicitAnyGenericTypeInference.ts, 1, 22)) +>U : Symbol(U, Decl(implicitAnyGenericTypeInference.ts, 1, 14)) +>U : Symbol(U, Decl(implicitAnyGenericTypeInference.ts, 1, 14)) +} + +var c: Comparer; +>c : Symbol(c, Decl(implicitAnyGenericTypeInference.ts, 4, 3)) +>Comparer : Symbol(Comparer, Decl(implicitAnyGenericTypeInference.ts, 0, 0)) + +c = { compareTo: (x, y) => { return y; } }; +>c : Symbol(c, Decl(implicitAnyGenericTypeInference.ts, 4, 3)) +>compareTo : Symbol(compareTo, Decl(implicitAnyGenericTypeInference.ts, 5, 5)) +>x : Symbol(x, Decl(implicitAnyGenericTypeInference.ts, 5, 18)) +>y : Symbol(y, Decl(implicitAnyGenericTypeInference.ts, 5, 20)) +>y : Symbol(y, Decl(implicitAnyGenericTypeInference.ts, 5, 20)) + +var r = c.compareTo(1, ''); +>r : Symbol(r, Decl(implicitAnyGenericTypeInference.ts, 6, 3)) +>c.compareTo : Symbol(Comparer.compareTo, Decl(implicitAnyGenericTypeInference.ts, 0, 23)) +>c : Symbol(c, Decl(implicitAnyGenericTypeInference.ts, 4, 3)) +>compareTo : Symbol(Comparer.compareTo, Decl(implicitAnyGenericTypeInference.ts, 0, 23)) + diff --git a/tests/baselines/reference/implicitAnyGenericTypeInference.types b/tests/baselines/reference/implicitAnyGenericTypeInference.types new file mode 100644 index 00000000000..6ec751130d8 --- /dev/null +++ b/tests/baselines/reference/implicitAnyGenericTypeInference.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/implicitAnyGenericTypeInference.ts === +interface Comparer { +>Comparer : Comparer +>T : T + + compareTo(x: T, y: U): U; +>compareTo : (x: T, y: U) => U +>U : U +>x : T +>T : T +>y : U +>U : U +>U : U +} + +var c: Comparer; +>c : Comparer +>Comparer : Comparer + +c = { compareTo: (x, y) => { return y; } }; +>c = { compareTo: (x, y) => { return y; } } : { compareTo: (x: any, y: U) => U; } +>c : Comparer +>{ compareTo: (x, y) => { return y; } } : { compareTo: (x: any, y: U) => U; } +>compareTo : (x: any, y: U) => U +>(x, y) => { return y; } : (x: any, y: U) => U +>x : any +>y : U +>y : U + +var r = c.compareTo(1, ''); +>r : string +>c.compareTo(1, '') : "" +>c.compareTo : (x: any, y: U) => U +>c : Comparer +>compareTo : (x: any, y: U) => U +>1 : 1 +>'' : "" + diff --git a/tests/baselines/reference/importCallExpression1ESNext.symbols b/tests/baselines/reference/importCallExpression1ESNext.symbols index 28b5ba13e99..564943aca54 100644 --- a/tests/baselines/reference/importCallExpression1ESNext.symbols +++ b/tests/baselines/reference/importCallExpression1ESNext.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpression2ESNext.symbols b/tests/baselines/reference/importCallExpression2ESNext.symbols index 2002398aeb9..9c0a8ebbbb4 100644 --- a/tests/baselines/reference/importCallExpression2ESNext.symbols +++ b/tests/baselines/reference/importCallExpression2ESNext.symbols @@ -30,4 +30,5 @@ function foo(x: Promise) { foo(import("./0")); >foo : Symbol(foo, Decl(2.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) diff --git a/tests/baselines/reference/importCallExpression3ESNext.symbols b/tests/baselines/reference/importCallExpression3ESNext.symbols index 5ca85d6e693..a1f2ffce44a 100644 --- a/tests/baselines/reference/importCallExpression3ESNext.symbols +++ b/tests/baselines/reference/importCallExpression3ESNext.symbols @@ -13,6 +13,7 @@ async function foo() { class C extends (await import("./0")).B {} >C : Symbol(C, Decl(2.ts, 0, 22)) >(await import("./0")).B : Symbol(B, Decl(0.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) >B : Symbol(B, Decl(0.ts, 0, 0)) var c = new C(); diff --git a/tests/baselines/reference/importCallExpression4ESNext.symbols b/tests/baselines/reference/importCallExpression4ESNext.symbols index 34a1dcf4d7b..b02646d5e3d 100644 --- a/tests/baselines/reference/importCallExpression4ESNext.symbols +++ b/tests/baselines/reference/importCallExpression4ESNext.symbols @@ -22,6 +22,7 @@ class C { private myModule = import("./0"); >myModule : Symbol(C.myModule, Decl(2.ts, 1, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) method() { >method : Symbol(C.method, Decl(2.ts, 2, 37)) @@ -49,6 +50,7 @@ class C { let one = await import("./1"); >one : Symbol(one, Decl(2.ts, 8, 15)) +>"./1" : Symbol("tests/cases/conformance/dynamicImport/1", Decl(1.ts, 0, 0)) console.log(one.backup()); >console : Symbol(console, Decl(2.ts, 0, 11)) diff --git a/tests/baselines/reference/importCallExpressionDeclarationEmit3.symbols b/tests/baselines/reference/importCallExpressionDeclarationEmit3.symbols index 1491e05db55..d3b10cbb320 100644 --- a/tests/baselines/reference/importCallExpressionDeclarationEmit3.symbols +++ b/tests/baselines/reference/importCallExpressionDeclarationEmit3.symbols @@ -10,6 +10,7 @@ import * as Zero from "./0"; >Zero : Symbol(Zero, Decl(1.ts, 1, 6)) import("./0"); +>"./0" : Symbol(Zero, Decl(0.ts, 0, 0)) export var p0: Promise = import(getPath()); >p0 : Symbol(p0, Decl(1.ts, 4, 10)) @@ -21,8 +22,10 @@ export var p1: Promise = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 5, 10)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) >Zero : Symbol(Zero, Decl(1.ts, 1, 6)) +>"./0" : Symbol(Zero, Decl(0.ts, 0, 0)) export var p2: Promise = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 6, 10)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) +>"./0" : Symbol(Zero, Decl(0.ts, 0, 0)) diff --git a/tests/baselines/reference/importCallExpressionES5AMD.symbols b/tests/baselines/reference/importCallExpressionES5AMD.symbols index 333251da662..a1a506e7005 100644 --- a/tests/baselines/reference/importCallExpressionES5AMD.symbols +++ b/tests/baselines/reference/importCallExpressionES5AMD.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpressionES5CJS.symbols b/tests/baselines/reference/importCallExpressionES5CJS.symbols index 333251da662..a1a506e7005 100644 --- a/tests/baselines/reference/importCallExpressionES5CJS.symbols +++ b/tests/baselines/reference/importCallExpressionES5CJS.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpressionES5System.symbols b/tests/baselines/reference/importCallExpressionES5System.symbols index 333251da662..a1a506e7005 100644 --- a/tests/baselines/reference/importCallExpressionES5System.symbols +++ b/tests/baselines/reference/importCallExpressionES5System.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpressionES5UMD.symbols b/tests/baselines/reference/importCallExpressionES5UMD.symbols index 333251da662..a1a506e7005 100644 --- a/tests/baselines/reference/importCallExpressionES5UMD.symbols +++ b/tests/baselines/reference/importCallExpressionES5UMD.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpressionInAMD1.symbols b/tests/baselines/reference/importCallExpressionInAMD1.symbols index 333251da662..a1a506e7005 100644 --- a/tests/baselines/reference/importCallExpressionInAMD1.symbols +++ b/tests/baselines/reference/importCallExpressionInAMD1.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpressionInAMD2.symbols b/tests/baselines/reference/importCallExpressionInAMD2.symbols index 16fc79c774f..b4809afbf50 100644 --- a/tests/baselines/reference/importCallExpressionInAMD2.symbols +++ b/tests/baselines/reference/importCallExpressionInAMD2.symbols @@ -31,4 +31,5 @@ function foo(x: Promise) { foo(import("./0")); >foo : Symbol(foo, Decl(2.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) diff --git a/tests/baselines/reference/importCallExpressionInAMD3.symbols b/tests/baselines/reference/importCallExpressionInAMD3.symbols index 5ca85d6e693..a1f2ffce44a 100644 --- a/tests/baselines/reference/importCallExpressionInAMD3.symbols +++ b/tests/baselines/reference/importCallExpressionInAMD3.symbols @@ -13,6 +13,7 @@ async function foo() { class C extends (await import("./0")).B {} >C : Symbol(C, Decl(2.ts, 0, 22)) >(await import("./0")).B : Symbol(B, Decl(0.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) >B : Symbol(B, Decl(0.ts, 0, 0)) var c = new C(); diff --git a/tests/baselines/reference/importCallExpressionInAMD4.symbols b/tests/baselines/reference/importCallExpressionInAMD4.symbols index 34a1dcf4d7b..b02646d5e3d 100644 --- a/tests/baselines/reference/importCallExpressionInAMD4.symbols +++ b/tests/baselines/reference/importCallExpressionInAMD4.symbols @@ -22,6 +22,7 @@ class C { private myModule = import("./0"); >myModule : Symbol(C.myModule, Decl(2.ts, 1, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) method() { >method : Symbol(C.method, Decl(2.ts, 2, 37)) @@ -49,6 +50,7 @@ class C { let one = await import("./1"); >one : Symbol(one, Decl(2.ts, 8, 15)) +>"./1" : Symbol("tests/cases/conformance/dynamicImport/1", Decl(1.ts, 0, 0)) console.log(one.backup()); >console : Symbol(console, Decl(2.ts, 0, 11)) diff --git a/tests/baselines/reference/importCallExpressionInCJS1.symbols b/tests/baselines/reference/importCallExpressionInCJS1.symbols index 333251da662..a1a506e7005 100644 --- a/tests/baselines/reference/importCallExpressionInCJS1.symbols +++ b/tests/baselines/reference/importCallExpressionInCJS1.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpressionInCJS2.symbols b/tests/baselines/reference/importCallExpressionInCJS2.symbols index 24f7a5cdb48..c60760c6184 100644 --- a/tests/baselines/reference/importCallExpressionInCJS2.symbols +++ b/tests/baselines/reference/importCallExpressionInCJS2.symbols @@ -21,6 +21,7 @@ async function compute(promise: Promise) { j = await import("./1"); >j : Symbol(j, Decl(2.ts, 1, 7)) +>"./1" : Symbol("tests/cases/conformance/dynamicImport/1", Decl(1.ts, 0, 0)) return j.backup(); >j : Symbol(j, Decl(2.ts, 1, 7)) @@ -31,4 +32,5 @@ async function compute(promise: Promise) { compute(import("./0")); >compute : Symbol(compute, Decl(2.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) diff --git a/tests/baselines/reference/importCallExpressionInCJS3.symbols b/tests/baselines/reference/importCallExpressionInCJS3.symbols index 16fc79c774f..b4809afbf50 100644 --- a/tests/baselines/reference/importCallExpressionInCJS3.symbols +++ b/tests/baselines/reference/importCallExpressionInCJS3.symbols @@ -31,4 +31,5 @@ function foo(x: Promise) { foo(import("./0")); >foo : Symbol(foo, Decl(2.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) diff --git a/tests/baselines/reference/importCallExpressionInCJS4.symbols b/tests/baselines/reference/importCallExpressionInCJS4.symbols index 5ca85d6e693..a1f2ffce44a 100644 --- a/tests/baselines/reference/importCallExpressionInCJS4.symbols +++ b/tests/baselines/reference/importCallExpressionInCJS4.symbols @@ -13,6 +13,7 @@ async function foo() { class C extends (await import("./0")).B {} >C : Symbol(C, Decl(2.ts, 0, 22)) >(await import("./0")).B : Symbol(B, Decl(0.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) >B : Symbol(B, Decl(0.ts, 0, 0)) var c = new C(); diff --git a/tests/baselines/reference/importCallExpressionInCJS5.symbols b/tests/baselines/reference/importCallExpressionInCJS5.symbols index 34a1dcf4d7b..b02646d5e3d 100644 --- a/tests/baselines/reference/importCallExpressionInCJS5.symbols +++ b/tests/baselines/reference/importCallExpressionInCJS5.symbols @@ -22,6 +22,7 @@ class C { private myModule = import("./0"); >myModule : Symbol(C.myModule, Decl(2.ts, 1, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) method() { >method : Symbol(C.method, Decl(2.ts, 2, 37)) @@ -49,6 +50,7 @@ class C { let one = await import("./1"); >one : Symbol(one, Decl(2.ts, 8, 15)) +>"./1" : Symbol("tests/cases/conformance/dynamicImport/1", Decl(1.ts, 0, 0)) console.log(one.backup()); >console : Symbol(console, Decl(2.ts, 0, 11)) diff --git a/tests/baselines/reference/importCallExpressionInScriptContext1.symbols b/tests/baselines/reference/importCallExpressionInScriptContext1.symbols index 513612056a8..d8657a10c31 100644 --- a/tests/baselines/reference/importCallExpressionInScriptContext1.symbols +++ b/tests/baselines/reference/importCallExpressionInScriptContext1.symbols @@ -5,6 +5,7 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 0, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) function arguments() { } // this is allow as the file doesn't have implicit "use strict" >arguments : Symbol(arguments, Decl(1.ts, 0, 23)) diff --git a/tests/baselines/reference/importCallExpressionInSystem1.symbols b/tests/baselines/reference/importCallExpressionInSystem1.symbols index 333251da662..a1a506e7005 100644 --- a/tests/baselines/reference/importCallExpressionInSystem1.symbols +++ b/tests/baselines/reference/importCallExpressionInSystem1.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpressionInSystem2.symbols b/tests/baselines/reference/importCallExpressionInSystem2.symbols index 16fc79c774f..b4809afbf50 100644 --- a/tests/baselines/reference/importCallExpressionInSystem2.symbols +++ b/tests/baselines/reference/importCallExpressionInSystem2.symbols @@ -31,4 +31,5 @@ function foo(x: Promise) { foo(import("./0")); >foo : Symbol(foo, Decl(2.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) diff --git a/tests/baselines/reference/importCallExpressionInSystem3.symbols b/tests/baselines/reference/importCallExpressionInSystem3.symbols index 5ca85d6e693..a1f2ffce44a 100644 --- a/tests/baselines/reference/importCallExpressionInSystem3.symbols +++ b/tests/baselines/reference/importCallExpressionInSystem3.symbols @@ -13,6 +13,7 @@ async function foo() { class C extends (await import("./0")).B {} >C : Symbol(C, Decl(2.ts, 0, 22)) >(await import("./0")).B : Symbol(B, Decl(0.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) >B : Symbol(B, Decl(0.ts, 0, 0)) var c = new C(); diff --git a/tests/baselines/reference/importCallExpressionInSystem4.symbols b/tests/baselines/reference/importCallExpressionInSystem4.symbols index 34a1dcf4d7b..b02646d5e3d 100644 --- a/tests/baselines/reference/importCallExpressionInSystem4.symbols +++ b/tests/baselines/reference/importCallExpressionInSystem4.symbols @@ -22,6 +22,7 @@ class C { private myModule = import("./0"); >myModule : Symbol(C.myModule, Decl(2.ts, 1, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) method() { >method : Symbol(C.method, Decl(2.ts, 2, 37)) @@ -49,6 +50,7 @@ class C { let one = await import("./1"); >one : Symbol(one, Decl(2.ts, 8, 15)) +>"./1" : Symbol("tests/cases/conformance/dynamicImport/1", Decl(1.ts, 0, 0)) console.log(one.backup()); >console : Symbol(console, Decl(2.ts, 0, 11)) diff --git a/tests/baselines/reference/importCallExpressionInUMD1.symbols b/tests/baselines/reference/importCallExpressionInUMD1.symbols index 333251da662..a1a506e7005 100644 --- a/tests/baselines/reference/importCallExpressionInUMD1.symbols +++ b/tests/baselines/reference/importCallExpressionInUMD1.symbols @@ -4,8 +4,11 @@ export function foo() { return "foo"; } === tests/cases/conformance/dynamicImport/1.ts === import("./0"); +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) + var p1 = import("./0"); >p1 : Symbol(p1, Decl(1.ts, 1, 3)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) p1.then(zero => { >p1.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) @@ -25,4 +28,5 @@ function foo() { const p2 = import("./0"); >p2 : Symbol(p2, Decl(1.ts, 7, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) } diff --git a/tests/baselines/reference/importCallExpressionInUMD2.symbols b/tests/baselines/reference/importCallExpressionInUMD2.symbols index 16fc79c774f..b4809afbf50 100644 --- a/tests/baselines/reference/importCallExpressionInUMD2.symbols +++ b/tests/baselines/reference/importCallExpressionInUMD2.symbols @@ -31,4 +31,5 @@ function foo(x: Promise) { foo(import("./0")); >foo : Symbol(foo, Decl(2.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) diff --git a/tests/baselines/reference/importCallExpressionInUMD3.symbols b/tests/baselines/reference/importCallExpressionInUMD3.symbols index 5ca85d6e693..a1f2ffce44a 100644 --- a/tests/baselines/reference/importCallExpressionInUMD3.symbols +++ b/tests/baselines/reference/importCallExpressionInUMD3.symbols @@ -13,6 +13,7 @@ async function foo() { class C extends (await import("./0")).B {} >C : Symbol(C, Decl(2.ts, 0, 22)) >(await import("./0")).B : Symbol(B, Decl(0.ts, 0, 0)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) >B : Symbol(B, Decl(0.ts, 0, 0)) var c = new C(); diff --git a/tests/baselines/reference/importCallExpressionInUMD4.symbols b/tests/baselines/reference/importCallExpressionInUMD4.symbols index 34a1dcf4d7b..b02646d5e3d 100644 --- a/tests/baselines/reference/importCallExpressionInUMD4.symbols +++ b/tests/baselines/reference/importCallExpressionInUMD4.symbols @@ -22,6 +22,7 @@ class C { private myModule = import("./0"); >myModule : Symbol(C.myModule, Decl(2.ts, 1, 9)) +>"./0" : Symbol("tests/cases/conformance/dynamicImport/0", Decl(0.ts, 0, 0)) method() { >method : Symbol(C.method, Decl(2.ts, 2, 37)) @@ -49,6 +50,7 @@ class C { let one = await import("./1"); >one : Symbol(one, Decl(2.ts, 8, 15)) +>"./1" : Symbol("tests/cases/conformance/dynamicImport/1", Decl(1.ts, 0, 0)) console.log(one.backup()); >console : Symbol(console, Decl(2.ts, 0, 11)) diff --git a/tests/baselines/reference/importCallExpressionNoModuleKindSpecified.errors.txt b/tests/baselines/reference/importCallExpressionNoModuleKindSpecified.errors.txt new file mode 100644 index 00000000000..cf665dda049 --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNoModuleKindSpecified.errors.txt @@ -0,0 +1,37 @@ +error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/dynamicImport/2.ts(3,24): error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/dynamicImport/2.ts(7,12): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/dynamicImport/2.ts(9,29): error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + + +!!! error TS2468: Cannot find global value 'Promise'. +==== tests/cases/conformance/dynamicImport/0.ts (0 errors) ==== + export class B { + print() { return "I am B"} + } + + export function foo() { return "foo" } + +==== tests/cases/conformance/dynamicImport/1.ts (0 errors) ==== + export function backup() { return "backup"; } + +==== tests/cases/conformance/dynamicImport/2.ts (3 errors) ==== + declare var console: any; + class C { + private myModule = import("./0"); + ~~~~~~~~~~~~~ +!!! error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + method() { + this.myModule.then(Zero => { + console.log(Zero.foo()); + }, async err => { + ~~~~~~~~~~~~~~ +!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + console.log(err); + let one = await import("./1"); + ~~~~~~~~~~~~~ +!!! error TS2712: A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + console.log(one.backup()); + }); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/importCallExpressionNoModuleKindSpecified.js b/tests/baselines/reference/importCallExpressionNoModuleKindSpecified.js new file mode 100644 index 00000000000..487d4e03a6c --- /dev/null +++ b/tests/baselines/reference/importCallExpressionNoModuleKindSpecified.js @@ -0,0 +1,105 @@ +//// [tests/cases/conformance/dynamicImport/importCallExpressionNoModuleKindSpecified.ts] //// + +//// [0.ts] +export class B { + print() { return "I am B"} +} + +export function foo() { return "foo" } + +//// [1.ts] +export function backup() { return "backup"; } + +//// [2.ts] +declare var console: any; +class C { + private myModule = import("./0"); + method() { + this.myModule.then(Zero => { + console.log(Zero.foo()); + }, async err => { + console.log(err); + let one = await import("./1"); + console.log(one.backup()); + }); + } +} + +//// [0.js] +"use strict"; +exports.__esModule = true; +var B = (function () { + function B() { + } + B.prototype.print = function () { return "I am B"; }; + return B; +}()); +exports.B = B; +function foo() { return "foo"; } +exports.foo = foo; +//// [1.js] +"use strict"; +exports.__esModule = true; +function backup() { return "backup"; } +exports.backup = backup; +//// [2.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var C = (function () { + function C() { + this.myModule = Promise.resolve().then(function () { return require("./0"); }); + } + C.prototype.method = function () { + var _this = this; + this.myModule.then(function (Zero) { + console.log(Zero.foo()); + }, function (err) { return __awaiter(_this, void 0, void 0, function () { + var one; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + console.log(err); + return [4 /*yield*/, Promise.resolve().then(function () { return require("./1"); })]; + case 1: + one = _a.sent(); + console.log(one.backup()); + return [2 /*return*/]; + } + }); + }); }); + }; + return C; +}()); diff --git a/tests/baselines/reference/importHelpersAmd.js b/tests/baselines/reference/importHelpersAmd.js index b756355921d..3d74b2277fb 100644 --- a/tests/baselines/reference/importHelpersAmd.js +++ b/tests/baselines/reference/importHelpersAmd.js @@ -5,16 +5,19 @@ export class A { } //// [b.ts] import { A } from "./a"; +export * from "./a"; export class B extends A { } //// [tslib.d.ts] export declare function __extends(d: Function, b: Function): void; export declare function __assign(t: any, ...sources: any[]): any; +export declare function __rest(t: any, propertyNames: string[]): any; export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; export declare function __param(paramIndex: number, decorator: Function): Function; export declare function __metadata(metadataKey: any, metadataValue: any): Function; export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any; - +export declare function __generator(thisArg: any, body: Function): any; +export declare function __exportStar(m: any, exports: any): void; //// [a.js] define(["require", "exports"], function (require, exports) { @@ -28,9 +31,10 @@ define(["require", "exports"], function (require, exports) { exports.A = A; }); //// [b.js] -define(["require", "exports", "tslib", "./a"], function (require, exports, tslib_1, a_1) { +define(["require", "exports", "tslib", "./a", "./a"], function (require, exports, tslib_1, a_1, a_2) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); + tslib_1.__exportStar(a_2, exports); var B = (function (_super) { tslib_1.__extends(B, _super); function B() { diff --git a/tests/baselines/reference/importHelpersAmd.symbols b/tests/baselines/reference/importHelpersAmd.symbols index 47528a8bba6..68506b4c353 100644 --- a/tests/baselines/reference/importHelpersAmd.symbols +++ b/tests/baselines/reference/importHelpersAmd.symbols @@ -6,8 +6,9 @@ export class A { } import { A } from "./a"; >A : Symbol(A, Decl(b.ts, 0, 8)) +export * from "./a"; export class B extends A { } ->B : Symbol(B, Decl(b.ts, 0, 24)) +>B : Symbol(B, Decl(b.ts, 1, 20)) >A : Symbol(A, Decl(b.ts, 0, 8)) === tests/cases/compiler/tslib.d.ts === @@ -23,6 +24,11 @@ export declare function __assign(t: any, ...sources: any[]): any; >t : Symbol(t, Decl(tslib.d.ts, --, --)) >sources : Symbol(sources, Decl(tslib.d.ts, --, --)) +export declare function __rest(t: any, propertyNames: string[]): any; +>__rest : Symbol(__rest, Decl(tslib.d.ts, --, --)) +>t : Symbol(t, Decl(tslib.d.ts, --, --)) +>propertyNames : Symbol(propertyNames, Decl(tslib.d.ts, --, --)) + export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; >__decorate : Symbol(__decorate, Decl(tslib.d.ts, --, --)) >decorators : Symbol(decorators, Decl(tslib.d.ts, --, --)) @@ -53,3 +59,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge >generator : Symbol(generator, Decl(tslib.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +export declare function __generator(thisArg: any, body: Function): any; +>__generator : Symbol(__generator, Decl(tslib.d.ts, --, --)) +>thisArg : Symbol(thisArg, Decl(tslib.d.ts, --, --)) +>body : Symbol(body, Decl(tslib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +export declare function __exportStar(m: any, exports: any): void; +>__exportStar : Symbol(__exportStar, Decl(tslib.d.ts, --, --)) +>m : Symbol(m, Decl(tslib.d.ts, --, --)) +>exports : Symbol(exports, Decl(tslib.d.ts, --, --)) + diff --git a/tests/baselines/reference/importHelpersAmd.types b/tests/baselines/reference/importHelpersAmd.types index 9ff756ffaab..23456ae2333 100644 --- a/tests/baselines/reference/importHelpersAmd.types +++ b/tests/baselines/reference/importHelpersAmd.types @@ -6,6 +6,7 @@ export class A { } import { A } from "./a"; >A : typeof A +export * from "./a"; export class B extends A { } >B : B >A : A @@ -23,6 +24,11 @@ export declare function __assign(t: any, ...sources: any[]): any; >t : any >sources : any[] +export declare function __rest(t: any, propertyNames: string[]): any; +>__rest : (t: any, propertyNames: string[]) => any +>t : any +>propertyNames : string[] + export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; >__decorate : (decorators: Function[], target: any, key?: string | symbol, desc?: any) => any >decorators : Function[] @@ -53,3 +59,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge >generator : Function >Function : Function +export declare function __generator(thisArg: any, body: Function): any; +>__generator : (thisArg: any, body: Function) => any +>thisArg : any +>body : Function +>Function : Function + +export declare function __exportStar(m: any, exports: any): void; +>__exportStar : (m: any, exports: any) => void +>m : any +>exports : any + diff --git a/tests/baselines/reference/importHelpersInAmbientContext.js b/tests/baselines/reference/importHelpersInAmbientContext.js index c1c00705951..c15bff36782 100644 --- a/tests/baselines/reference/importHelpersInAmbientContext.js +++ b/tests/baselines/reference/importHelpersInAmbientContext.js @@ -48,11 +48,13 @@ declare namespace N { //// [tslib.d.ts] export declare function __extends(d: Function, b: Function): void; export declare function __assign(t: any, ...sources: any[]): any; +export declare function __rest(t: any, propertyNames: string[]): any; export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; export declare function __param(paramIndex: number, decorator: Function): Function; export declare function __metadata(metadataKey: any, metadataValue: any): Function; export declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any; - +export declare function __generator(thisArg: any, body: Function): any; +export declare function __exportStar(m: any, exports: any): void; //// [b.js] "use strict"; diff --git a/tests/baselines/reference/importHelpersInAmbientContext.symbols b/tests/baselines/reference/importHelpersInAmbientContext.symbols index 172eea3037f..9dd7d30390f 100644 --- a/tests/baselines/reference/importHelpersInAmbientContext.symbols +++ b/tests/baselines/reference/importHelpersInAmbientContext.symbols @@ -98,6 +98,11 @@ export declare function __assign(t: any, ...sources: any[]): any; >t : Symbol(t, Decl(tslib.d.ts, --, --)) >sources : Symbol(sources, Decl(tslib.d.ts, --, --)) +export declare function __rest(t: any, propertyNames: string[]): any; +>__rest : Symbol(__rest, Decl(tslib.d.ts, --, --)) +>t : Symbol(t, Decl(tslib.d.ts, --, --)) +>propertyNames : Symbol(propertyNames, Decl(tslib.d.ts, --, --)) + export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; >__decorate : Symbol(__decorate, Decl(tslib.d.ts, --, --)) >decorators : Symbol(decorators, Decl(tslib.d.ts, --, --)) @@ -128,3 +133,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge >generator : Symbol(generator, Decl(tslib.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +export declare function __generator(thisArg: any, body: Function): any; +>__generator : Symbol(__generator, Decl(tslib.d.ts, --, --)) +>thisArg : Symbol(thisArg, Decl(tslib.d.ts, --, --)) +>body : Symbol(body, Decl(tslib.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +export declare function __exportStar(m: any, exports: any): void; +>__exportStar : Symbol(__exportStar, Decl(tslib.d.ts, --, --)) +>m : Symbol(m, Decl(tslib.d.ts, --, --)) +>exports : Symbol(exports, Decl(tslib.d.ts, --, --)) + diff --git a/tests/baselines/reference/importHelpersInAmbientContext.types b/tests/baselines/reference/importHelpersInAmbientContext.types index 5f01f5b1617..9ae97effd8a 100644 --- a/tests/baselines/reference/importHelpersInAmbientContext.types +++ b/tests/baselines/reference/importHelpersInAmbientContext.types @@ -98,6 +98,11 @@ export declare function __assign(t: any, ...sources: any[]): any; >t : any >sources : any[] +export declare function __rest(t: any, propertyNames: string[]): any; +>__rest : (t: any, propertyNames: string[]) => any +>t : any +>propertyNames : string[] + export declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any; >__decorate : (decorators: Function[], target: any, key?: string | symbol, desc?: any) => any >decorators : Function[] @@ -128,3 +133,14 @@ export declare function __awaiter(thisArg: any, _arguments: any, P: Function, ge >generator : Function >Function : Function +export declare function __generator(thisArg: any, body: Function): any; +>__generator : (thisArg: any, body: Function) => any +>thisArg : any +>body : Function +>Function : Function + +export declare function __exportStar(m: any, exports: any): void; +>__exportStar : (m: any, exports: any) => void +>m : any +>exports : any + diff --git a/tests/baselines/reference/importHelpersNoHelpers.errors.txt b/tests/baselines/reference/importHelpersNoHelpers.errors.txt index a0c089a9ddc..4034fbc649b 100644 --- a/tests/baselines/reference/importHelpersNoHelpers.errors.txt +++ b/tests/baselines/reference/importHelpersNoHelpers.errors.txt @@ -1,12 +1,16 @@ -tests/cases/compiler/external.ts(2,16): error TS2343: This syntax requires an imported helper named '__extends', but module 'tslib' has no exported member '__extends'. -tests/cases/compiler/external.ts(6,1): error TS2343: This syntax requires an imported helper named '__decorate', but module 'tslib' has no exported member '__decorate'. -tests/cases/compiler/external.ts(6,1): error TS2343: This syntax requires an imported helper named '__metadata', but module 'tslib' has no exported member '__metadata'. -tests/cases/compiler/external.ts(8,12): error TS2343: This syntax requires an imported helper named '__param', but module 'tslib' has no exported member '__param'. -tests/cases/compiler/external.ts(13,13): error TS2343: This syntax requires an imported helper named '__assign', but module 'tslib' has no exported member '__assign'. -tests/cases/compiler/external.ts(14,12): error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'. +tests/cases/compiler/external.ts(1,1): error TS2343: This syntax requires an imported helper named '__exportStar', but module 'tslib' has no exported member '__exportStar'. +tests/cases/compiler/external.ts(3,16): error TS2343: This syntax requires an imported helper named '__extends', but module 'tslib' has no exported member '__extends'. +tests/cases/compiler/external.ts(7,1): error TS2343: This syntax requires an imported helper named '__decorate', but module 'tslib' has no exported member '__decorate'. +tests/cases/compiler/external.ts(7,1): error TS2343: This syntax requires an imported helper named '__metadata', but module 'tslib' has no exported member '__metadata'. +tests/cases/compiler/external.ts(9,12): error TS2343: This syntax requires an imported helper named '__param', but module 'tslib' has no exported member '__param'. +tests/cases/compiler/external.ts(14,13): error TS2343: This syntax requires an imported helper named '__assign', but module 'tslib' has no exported member '__assign'. +tests/cases/compiler/external.ts(15,12): error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'. -==== tests/cases/compiler/external.ts (6 errors) ==== +==== tests/cases/compiler/external.ts (7 errors) ==== + export * from "./other"; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2343: This syntax requires an imported helper named '__exportStar', but module 'tslib' has no exported member '__exportStar'. export class A { } export class B extends A { } ~~~~~~~~~ @@ -34,6 +38,9 @@ tests/cases/compiler/external.ts(14,12): error TS2343: This syntax requires an i ~ !!! error TS2343: This syntax requires an imported helper named '__rest', but module 'tslib' has no exported member '__rest'. +==== tests/cases/compiler/other.ts (0 errors) ==== + export const x = 1; + ==== tests/cases/compiler/script.ts (0 errors) ==== class A { } class B extends A { } diff --git a/tests/baselines/reference/importHelpersNoHelpers.js b/tests/baselines/reference/importHelpersNoHelpers.js index 9e20fc13543..ec1b21d797c 100644 --- a/tests/baselines/reference/importHelpersNoHelpers.js +++ b/tests/baselines/reference/importHelpersNoHelpers.js @@ -1,6 +1,7 @@ //// [tests/cases/compiler/importHelpersNoHelpers.ts] //// //// [external.ts] +export * from "./other"; export class A { } export class B extends A { } @@ -16,6 +17,9 @@ const o = { a: 1 }; const y = { ...o }; const { ...x } = y; +//// [other.ts] +export const x = 1; + //// [script.ts] class A { } class B extends A { } @@ -32,10 +36,15 @@ class C { export {} +//// [other.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.x = 1; //// [external.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); +tslib_1.__exportStar(require("./other"), exports); var A = (function () { function A() { } diff --git a/tests/baselines/reference/importHelpersSystem.js b/tests/baselines/reference/importHelpersSystem.js index b7c10ee3c34..fbd0f5e589f 100644 --- a/tests/baselines/reference/importHelpersSystem.js +++ b/tests/baselines/reference/importHelpersSystem.js @@ -5,6 +5,7 @@ export class A { } //// [b.ts] import { A } from "./a"; +export * from "./a"; export class B extends A { } //// [tslib.d.ts] @@ -38,6 +39,16 @@ System.register(["tslib", "./a"], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; var tslib_1, a_1, B; + var exportedNames_1 = { + "B": true + }; + function exportStar_1(m) { + var exports = {}; + for (var n in m) { + if (n !== "default" && !exportedNames_1.hasOwnProperty(n)) exports[n] = m[n]; + } + exports_1(exports); + } return { setters: [ function (tslib_1_1) { @@ -45,6 +56,7 @@ System.register(["tslib", "./a"], function (exports_1, context_1) { }, function (a_1_1) { a_1 = a_1_1; + exportStar_1(a_1_1); } ], execute: function () { diff --git a/tests/baselines/reference/importHelpersSystem.symbols b/tests/baselines/reference/importHelpersSystem.symbols index 47528a8bba6..d7d588a67ef 100644 --- a/tests/baselines/reference/importHelpersSystem.symbols +++ b/tests/baselines/reference/importHelpersSystem.symbols @@ -6,8 +6,9 @@ export class A { } import { A } from "./a"; >A : Symbol(A, Decl(b.ts, 0, 8)) +export * from "./a"; export class B extends A { } ->B : Symbol(B, Decl(b.ts, 0, 24)) +>B : Symbol(B, Decl(b.ts, 1, 20)) >A : Symbol(A, Decl(b.ts, 0, 8)) === tests/cases/compiler/tslib.d.ts === diff --git a/tests/baselines/reference/importHelpersSystem.types b/tests/baselines/reference/importHelpersSystem.types index 9ff756ffaab..de9ef3e9446 100644 --- a/tests/baselines/reference/importHelpersSystem.types +++ b/tests/baselines/reference/importHelpersSystem.types @@ -6,6 +6,7 @@ export class A { } import { A } from "./a"; >A : typeof A +export * from "./a"; export class B extends A { } >B : B >A : A diff --git a/tests/baselines/reference/incrementOnNullAssertion.js b/tests/baselines/reference/incrementOnNullAssertion.js new file mode 100644 index 00000000000..1f56fa00f56 --- /dev/null +++ b/tests/baselines/reference/incrementOnNullAssertion.js @@ -0,0 +1,28 @@ +//// [incrementOnNullAssertion.ts] +interface Dictionary { + [myFavouriteType: string]: T | undefined +} +const x = 'bar' +let foo: Dictionary = {} +if (foo[x] === undefined) { + foo[x] = 1 +} +else { + let nu = foo[x] + let n = foo[x] + foo[x]!++ +} + + +//// [incrementOnNullAssertion.js] +"use strict"; +var x = 'bar'; +var foo = {}; +if (foo[x] === undefined) { + foo[x] = 1; +} +else { + var nu = foo[x]; + var n = foo[x]; + foo[x]++; +} diff --git a/tests/baselines/reference/incrementOnNullAssertion.symbols b/tests/baselines/reference/incrementOnNullAssertion.symbols new file mode 100644 index 00000000000..07f37e4aaa7 --- /dev/null +++ b/tests/baselines/reference/incrementOnNullAssertion.symbols @@ -0,0 +1,41 @@ +=== tests/cases/compiler/incrementOnNullAssertion.ts === +interface Dictionary { +>Dictionary : Symbol(Dictionary, Decl(incrementOnNullAssertion.ts, 0, 0)) +>T : Symbol(T, Decl(incrementOnNullAssertion.ts, 0, 21)) + + [myFavouriteType: string]: T | undefined +>myFavouriteType : Symbol(myFavouriteType, Decl(incrementOnNullAssertion.ts, 1, 5)) +>T : Symbol(T, Decl(incrementOnNullAssertion.ts, 0, 21)) +} +const x = 'bar' +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) + +let foo: Dictionary = {} +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>Dictionary : Symbol(Dictionary, Decl(incrementOnNullAssertion.ts, 0, 0)) + +if (foo[x] === undefined) { +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) +>undefined : Symbol(undefined) + + foo[x] = 1 +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) +} +else { + let nu = foo[x] +>nu : Symbol(nu, Decl(incrementOnNullAssertion.ts, 9, 7)) +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) + + let n = foo[x] +>n : Symbol(n, Decl(incrementOnNullAssertion.ts, 10, 7)) +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) + + foo[x]!++ +>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3)) +>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5)) +} + diff --git a/tests/baselines/reference/incrementOnNullAssertion.types b/tests/baselines/reference/incrementOnNullAssertion.types new file mode 100644 index 00000000000..f6acdda65bc --- /dev/null +++ b/tests/baselines/reference/incrementOnNullAssertion.types @@ -0,0 +1,53 @@ +=== tests/cases/compiler/incrementOnNullAssertion.ts === +interface Dictionary { +>Dictionary : Dictionary +>T : T + + [myFavouriteType: string]: T | undefined +>myFavouriteType : string +>T : T +} +const x = 'bar' +>x : "bar" +>'bar' : "bar" + +let foo: Dictionary = {} +>foo : Dictionary +>Dictionary : Dictionary +>{} : {} + +if (foo[x] === undefined) { +>foo[x] === undefined : boolean +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" +>undefined : undefined + + foo[x] = 1 +>foo[x] = 1 : 1 +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" +>1 : 1 +} +else { + let nu = foo[x] +>nu : number | undefined +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" + + let n = foo[x] +>n : number | undefined +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" + + foo[x]!++ +>foo[x]!++ : number +>foo[x]! : number +>foo[x] : number | undefined +>foo : Dictionary +>x : "bar" +} + diff --git a/tests/baselines/reference/isolatedModulesReExportType.errors.txt b/tests/baselines/reference/isolatedModulesReExportType.errors.txt index 10c07cde084..dc035a84c2f 100644 --- a/tests/baselines/reference/isolatedModulesReExportType.errors.txt +++ b/tests/baselines/reference/isolatedModulesReExportType.errors.txt @@ -35,4 +35,14 @@ declare type T = number; export = T; +==== /node_modules/foo/bar.d.ts (0 errors) ==== + export type T = number; + +==== /node_modules/foo/index.d.ts (0 errors) ==== + export { T } from "./bar"; // In a declaration file, so not an error. + +==== /node_modules/baz/index.d.ts (0 errors) ==== + declare module "baz" { + export { T } from "foo"; // Also allowed. + } \ No newline at end of file diff --git a/tests/baselines/reference/isolatedModulesReExportType.js b/tests/baselines/reference/isolatedModulesReExportType.js index 545e5a81a8a..5924dd249e7 100644 --- a/tests/baselines/reference/isolatedModulesReExportType.js +++ b/tests/baselines/reference/isolatedModulesReExportType.js @@ -9,7 +9,17 @@ export class C {} //// [exportEqualsT.ts] declare type T = number; export = T; - + +//// [bar.d.ts] +export type T = number; + +//// [index.d.ts] +export { T } from "./bar"; // In a declaration file, so not an error. + +//// [index.d.ts] +declare module "baz" { + export { T } from "foo"; // Also allowed. +} //// [user.ts] // Error, can't re-export something that's only a type. diff --git a/tests/baselines/reference/iterableArrayPattern28.errors.txt b/tests/baselines/reference/iterableArrayPattern28.errors.txt index 986dfe1d9a2..ac744111b45 100644 --- a/tests/baselines/reference/iterableArrayPattern28.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern28.errors.txt @@ -1,6 +1,14 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(1,33): error TS2501: A rest element cannot contain a binding pattern. -tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,28): error TS2453: The type argument for type parameter 'V' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'boolean'. +tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'Iterable<[string, number]>'. + Types of property '[Symbol.iterator]' are incompatible. + Type '() => IterableIterator<[string, number] | [string, boolean]>' is not assignable to type '() => Iterator<[string, number]>'. + Type 'IterableIterator<[string, number] | [string, boolean]>' is not assignable to type 'Iterator<[string, number]>'. + Types of property 'next' are incompatible. + Type '(value?: any) => IteratorResult<[string, number] | [string, boolean]>' is not assignable to type '(value?: any) => IteratorResult<[string, number]>'. + Type 'IteratorResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorResult<[string, number]>'. + Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. + Type '[string, boolean]' is not assignable to type '[string, number]'. + Type 'boolean' is not assignable to type 'number'. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (2 errors) ==== @@ -8,6 +16,14 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,28): error ~~~~~~~~~~~~~~~~~~~~ !!! error TS2501: A rest element cannot contain a binding pattern. takeFirstTwoEntries(...new Map([["", 0], ["hello", true]])); - ~~~ -!!! error TS2453: The type argument for type parameter 'V' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'boolean'. \ No newline at end of file + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'Iterable<[string, number]>'. +!!! error TS2345: Types of property '[Symbol.iterator]' are incompatible. +!!! error TS2345: Type '() => IterableIterator<[string, number] | [string, boolean]>' is not assignable to type '() => Iterator<[string, number]>'. +!!! error TS2345: Type 'IterableIterator<[string, number] | [string, boolean]>' is not assignable to type 'Iterator<[string, number]>'. +!!! error TS2345: Types of property 'next' are incompatible. +!!! error TS2345: Type '(value?: any) => IteratorResult<[string, number] | [string, boolean]>' is not assignable to type '(value?: any) => IteratorResult<[string, number]>'. +!!! error TS2345: Type 'IteratorResult<[string, number] | [string, boolean]>' is not assignable to type 'IteratorResult<[string, number]>'. +!!! error TS2345: Type '[string, number] | [string, boolean]' is not assignable to type '[string, number]'. +!!! error TS2345: Type '[string, boolean]' is not assignable to type '[string, number]'. +!!! error TS2345: Type 'boolean' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall7.errors.txt b/tests/baselines/reference/iteratorSpreadInCall7.errors.txt index 30096c90db6..5494d1e7070 100644 --- a/tests/baselines/reference/iteratorSpreadInCall7.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall7.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts(28,1): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts(28,28): error TS2345: Argument of type 'string' is not assignable to parameter of type 'symbol'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts (1 errors) ==== @@ -31,6 +30,5 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall7.ts(28,1): error TS2453: } foo(...new SymbolIterator, ...new StringIterator); - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. \ No newline at end of file + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'symbol'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall8.errors.txt b/tests/baselines/reference/iteratorSpreadInCall8.errors.txt index 5fd0b43ce5a..73dc6d5185e 100644 --- a/tests/baselines/reference/iteratorSpreadInCall8.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall8.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts(31,5): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts(31,32): error TS2345: Argument of type 'string' is not assignable to parameter of type 'symbol'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts (1 errors) ==== @@ -34,6 +33,5 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall8.ts(31,5): error TS2453: } new Foo(...new SymbolIterator, ...new StringIterator); - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. \ No newline at end of file + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'symbol'. \ No newline at end of file diff --git a/tests/baselines/reference/iteratorSpreadInCall9.errors.txt b/tests/baselines/reference/iteratorSpreadInCall9.errors.txt index 59854bd36ad..773eb2a9fc8 100644 --- a/tests/baselines/reference/iteratorSpreadInCall9.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInCall9.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts(31,5): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts(31,32): error TS2345: Argument of type 'string' is not assignable to parameter of type 'symbol'. ==== tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts (1 errors) ==== @@ -34,7 +33,6 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall9.ts(31,5): error TS2453: } new Foo(...new SymbolIterator, ...[...new StringIterator]); - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'symbol' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'symbol'. \ No newline at end of file diff --git a/tests/baselines/reference/jsSelfReferencingArgumentsFunction.symbols b/tests/baselines/reference/jsSelfReferencingArgumentsFunction.symbols new file mode 100644 index 00000000000..e4fe336575c --- /dev/null +++ b/tests/baselines/reference/jsSelfReferencingArgumentsFunction.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/foo.js === +// Test #16139 +function Foo() { +>Foo : Symbol(Foo, Decl(foo.js, 0, 0)) + + arguments; +>arguments : Symbol(arguments) + + return new Foo(); +>Foo : Symbol(Foo, Decl(foo.js, 0, 0)) +} + diff --git a/tests/baselines/reference/jsSelfReferencingArgumentsFunction.types b/tests/baselines/reference/jsSelfReferencingArgumentsFunction.types new file mode 100644 index 00000000000..cab51cbafc1 --- /dev/null +++ b/tests/baselines/reference/jsSelfReferencingArgumentsFunction.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/foo.js === +// Test #16139 +function Foo() { +>Foo : (...args: any[]) => any + + arguments; +>arguments : IArguments + + return new Foo(); +>new Foo() : any +>Foo : (...args: any[]) => any +} + diff --git a/tests/baselines/reference/jsdocInTypeScript.errors.txt b/tests/baselines/reference/jsdocInTypeScript.errors.txt index 621aa4677b4..ec3b7eab4b4 100644 --- a/tests/baselines/reference/jsdocInTypeScript.errors.txt +++ b/tests/baselines/reference/jsdocInTypeScript.errors.txt @@ -3,9 +3,10 @@ tests/cases/compiler/jsdocInTypeScript.ts(23,33): error TS2362: The left-hand si tests/cases/compiler/jsdocInTypeScript.ts(25,3): error TS2345: Argument of type '1' is not assignable to parameter of type 'boolean'. tests/cases/compiler/jsdocInTypeScript.ts(25,15): error TS2339: Property 'length' does not exist on type 'number'. tests/cases/compiler/jsdocInTypeScript.ts(30,3): error TS2339: Property 'x' does not exist on type '{}'. +tests/cases/compiler/jsdocInTypeScript.ts(42,12): error TS2503: Cannot find namespace 'N'. -==== tests/cases/compiler/jsdocInTypeScript.ts (5 errors) ==== +==== tests/cases/compiler/jsdocInTypeScript.ts (6 errors) ==== // JSDoc typedef tags are not bound TypeScript files. /** @typedef {function} T */ declare const x: T; @@ -43,7 +44,21 @@ tests/cases/compiler/jsdocInTypeScript.ts(30,3): error TS2339: Property 'x' does // @type has no effect either. /** @type {{ x?: number }} */ const z = {}; - z.x = 1; + z.x = 1; // Error ~ !!! error TS2339: Property 'x' does not exist on type '{}'. + + // @template tag should not interfere with constraint or default. + /** @template T */ + interface I {} + + /** @template T */ + function tem(t: T): I { return {}; } + + let i: I; // Should succeed thanks to type parameter default + + /** @typedef {string} N.Str */ + import M = N; // Error: @typedef does not create namespaces in TypeScript code. + ~ +!!! error TS2503: Cannot find namespace 'N'. \ No newline at end of file diff --git a/tests/baselines/reference/jsdocInTypeScript.js b/tests/baselines/reference/jsdocInTypeScript.js index 29782e92592..3e653f0859a 100644 --- a/tests/baselines/reference/jsdocInTypeScript.js +++ b/tests/baselines/reference/jsdocInTypeScript.js @@ -28,7 +28,19 @@ f(1); f(true).length; // @type has no effect either. /** @type {{ x?: number }} */ const z = {}; -z.x = 1; +z.x = 1; // Error + +// @template tag should not interfere with constraint or default. +/** @template T */ +interface I {} + +/** @template T */ +function tem(t: T): I { return {}; } + +let i: I; // Should succeed thanks to type parameter default + +/** @typedef {string} N.Str */ +import M = N; // Error: @typedef does not create namespaces in TypeScript code. //// [jsdocInTypeScript.js] @@ -50,4 +62,9 @@ f(true).length; // @type has no effect either. /** @type {{ x?: number }} */ var z = {}; -z.x = 1; +z.x = 1; // Error +/** @template T */ +function tem(t) { return {}; } +var i; // Should succeed thanks to type parameter default +/** @typedef {string} N.Str */ +var M = N; // Error: @typedef does not create namespaces in TypeScript code. diff --git a/tests/baselines/reference/jsdocTemplateTag.symbols b/tests/baselines/reference/jsdocTemplateTag.symbols new file mode 100644 index 00000000000..699e93339ed --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag.symbols @@ -0,0 +1,36 @@ +=== tests/cases/conformance/jsdoc/jsdocTemplateTag.ts === +/** + * @param {T} a + * @template T + */ +function f(a: T) { +>f : Symbol(f, Decl(jsdocTemplateTag.ts, 0, 0)) +>T : Symbol(T, Decl(jsdocTemplateTag.ts, 4, 11)) +>a : Symbol(a, Decl(jsdocTemplateTag.ts, 4, 14)) +>T : Symbol(T, Decl(jsdocTemplateTag.ts, 4, 11)) + + return () => a +>a : Symbol(a, Decl(jsdocTemplateTag.ts, 4, 14)) +} +let n = f(1)() +>n : Symbol(n, Decl(jsdocTemplateTag.ts, 7, 3)) +>f : Symbol(f, Decl(jsdocTemplateTag.ts, 0, 0)) + +/** + * @param {T} a + * @template T + * @returns {function(): T} + */ +function g(a: T) { +>g : Symbol(g, Decl(jsdocTemplateTag.ts, 7, 14)) +>T : Symbol(T, Decl(jsdocTemplateTag.ts, 14, 11)) +>a : Symbol(a, Decl(jsdocTemplateTag.ts, 14, 14)) +>T : Symbol(T, Decl(jsdocTemplateTag.ts, 14, 11)) + + return () => a +>a : Symbol(a, Decl(jsdocTemplateTag.ts, 14, 14)) +} +let s = g('hi')() +>s : Symbol(s, Decl(jsdocTemplateTag.ts, 17, 3)) +>g : Symbol(g, Decl(jsdocTemplateTag.ts, 7, 14)) + diff --git a/tests/baselines/reference/jsdocTemplateTag.types b/tests/baselines/reference/jsdocTemplateTag.types new file mode 100644 index 00000000000..72b0529d97e --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/jsdoc/jsdocTemplateTag.ts === +/** + * @param {T} a + * @template T + */ +function f(a: T) { +>f : (a: T) => () => T +>T : T +>a : T +>T : T + + return () => a +>() => a : () => T +>a : T +} +let n = f(1)() +>n : number +>f(1)() : number +>f(1) : () => number +>f : (a: T) => () => T +>1 : 1 + +/** + * @param {T} a + * @template T + * @returns {function(): T} + */ +function g(a: T) { +>g : (a: T) => () => T +>T : T +>a : T +>T : T + + return () => a +>() => a : () => T +>a : T +} +let s = g('hi')() +>s : string +>g('hi')() : string +>g('hi') : () => string +>g : (a: T) => () => T +>'hi' : "hi" + diff --git a/tests/baselines/reference/jsdocTypeDefAtStartOfFile.symbols b/tests/baselines/reference/jsdocTypeDefAtStartOfFile.symbols new file mode 100644 index 00000000000..6aaeda1b4b5 --- /dev/null +++ b/tests/baselines/reference/jsdocTypeDefAtStartOfFile.symbols @@ -0,0 +1,12 @@ +=== tests/cases/conformance/jsdoc/dtsEquivalent.js === +/** @typedef {{[k: string]: any}} AnyEffect */ +No type information for this code./** @typedef {number} Third */ +No type information for this code.=== tests/cases/conformance/jsdoc/index.js === +/** @type {AnyEffect} */ +let b; +>b : Symbol(b, Decl(index.js, 1, 3)) + +/** @type {Third} */ +let c; +>c : Symbol(c, Decl(index.js, 3, 3)) + diff --git a/tests/baselines/reference/jsdocTypeDefAtStartOfFile.types b/tests/baselines/reference/jsdocTypeDefAtStartOfFile.types new file mode 100644 index 00000000000..46248a441a1 --- /dev/null +++ b/tests/baselines/reference/jsdocTypeDefAtStartOfFile.types @@ -0,0 +1,12 @@ +=== tests/cases/conformance/jsdoc/dtsEquivalent.js === +/** @typedef {{[k: string]: any}} AnyEffect */ +No type information for this code./** @typedef {number} Third */ +No type information for this code.=== tests/cases/conformance/jsdoc/index.js === +/** @type {AnyEffect} */ +let b; +>b : { [k: string]: any; } + +/** @type {Third} */ +let c; +>c : number + diff --git a/tests/baselines/reference/mismatchedGenericArguments1.errors.txt b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt new file mode 100644 index 00000000000..13618c926ef --- /dev/null +++ b/tests/baselines/reference/mismatchedGenericArguments1.errors.txt @@ -0,0 +1,40 @@ +tests/cases/compiler/mismatchedGenericArguments1.ts(4,7): error TS2420: Class 'C' incorrectly implements interface 'IFoo'. + Types of property 'foo' are incompatible. + Type '(x: string) => number' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. +tests/cases/compiler/mismatchedGenericArguments1.ts(10,7): error TS2420: Class 'C2' incorrectly implements interface 'IFoo'. + Types of property 'foo' are incompatible. + Type '(x: string) => number' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'string'. + + +==== tests/cases/compiler/mismatchedGenericArguments1.ts (2 errors) ==== + interface IFoo { + foo(x: T): T; + } + class C implements IFoo { + ~ +!!! error TS2420: Class 'C' incorrectly implements interface 'IFoo'. +!!! error TS2420: Types of property 'foo' are incompatible. +!!! error TS2420: Type '(x: string) => number' is not assignable to type '(x: T) => T'. +!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2420: Type 'T' is not assignable to type 'string'. + foo(x: string): number { + return null; + } + } + + class C2 implements IFoo { + ~~ +!!! error TS2420: Class 'C2' incorrectly implements interface 'IFoo'. +!!! error TS2420: Types of property 'foo' are incompatible. +!!! error TS2420: Type '(x: string) => number' is not assignable to type '(x: T) => T'. +!!! error TS2420: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2420: Type 'T' is not assignable to type 'string'. + foo(x: string): number { + return null; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/neverUnionIntersection.js b/tests/baselines/reference/neverUnionIntersection.js new file mode 100644 index 00000000000..1e84e4b003f --- /dev/null +++ b/tests/baselines/reference/neverUnionIntersection.js @@ -0,0 +1,17 @@ +//// [neverUnionIntersection.ts] +type T01 = string | never; +type T02 = string & never; +type T03 = string | number | never; +type T04 = string & number & never; +type T05 = any | never; +type T06 = any & never; +type T07 = undefined | never; +type T08 = undefined & never; +type T09 = null | never; +type T10 = null & never; +type T11 = { a: string } | never; +type T12 = { a: string } & never; + + +//// [neverUnionIntersection.js] +"use strict"; diff --git a/tests/baselines/reference/neverUnionIntersection.symbols b/tests/baselines/reference/neverUnionIntersection.symbols new file mode 100644 index 00000000000..0f56c1b3157 --- /dev/null +++ b/tests/baselines/reference/neverUnionIntersection.symbols @@ -0,0 +1,39 @@ +=== tests/cases/conformance/types/never/neverUnionIntersection.ts === +type T01 = string | never; +>T01 : Symbol(T01, Decl(neverUnionIntersection.ts, 0, 0)) + +type T02 = string & never; +>T02 : Symbol(T02, Decl(neverUnionIntersection.ts, 0, 26)) + +type T03 = string | number | never; +>T03 : Symbol(T03, Decl(neverUnionIntersection.ts, 1, 26)) + +type T04 = string & number & never; +>T04 : Symbol(T04, Decl(neverUnionIntersection.ts, 2, 35)) + +type T05 = any | never; +>T05 : Symbol(T05, Decl(neverUnionIntersection.ts, 3, 35)) + +type T06 = any & never; +>T06 : Symbol(T06, Decl(neverUnionIntersection.ts, 4, 23)) + +type T07 = undefined | never; +>T07 : Symbol(T07, Decl(neverUnionIntersection.ts, 5, 23)) + +type T08 = undefined & never; +>T08 : Symbol(T08, Decl(neverUnionIntersection.ts, 6, 29)) + +type T09 = null | never; +>T09 : Symbol(T09, Decl(neverUnionIntersection.ts, 7, 29)) + +type T10 = null & never; +>T10 : Symbol(T10, Decl(neverUnionIntersection.ts, 8, 24)) + +type T11 = { a: string } | never; +>T11 : Symbol(T11, Decl(neverUnionIntersection.ts, 9, 24)) +>a : Symbol(a, Decl(neverUnionIntersection.ts, 10, 12)) + +type T12 = { a: string } & never; +>T12 : Symbol(T12, Decl(neverUnionIntersection.ts, 10, 33)) +>a : Symbol(a, Decl(neverUnionIntersection.ts, 11, 12)) + diff --git a/tests/baselines/reference/neverUnionIntersection.types b/tests/baselines/reference/neverUnionIntersection.types new file mode 100644 index 00000000000..4f578052e9c --- /dev/null +++ b/tests/baselines/reference/neverUnionIntersection.types @@ -0,0 +1,41 @@ +=== tests/cases/conformance/types/never/neverUnionIntersection.ts === +type T01 = string | never; +>T01 : string + +type T02 = string & never; +>T02 : never + +type T03 = string | number | never; +>T03 : T03 + +type T04 = string & number & never; +>T04 : never + +type T05 = any | never; +>T05 : any + +type T06 = any & never; +>T06 : never + +type T07 = undefined | never; +>T07 : undefined + +type T08 = undefined & never; +>T08 : never + +type T09 = null | never; +>T09 : null +>null : null + +type T10 = null & never; +>T10 : never +>null : null + +type T11 = { a: string } | never; +>T11 : { a: string; } +>a : string + +type T12 = { a: string } & never; +>T12 : never +>a : string + diff --git a/tests/baselines/reference/noStrictGenericChecks.js b/tests/baselines/reference/noStrictGenericChecks.js new file mode 100644 index 00000000000..485fdc6bd3b --- /dev/null +++ b/tests/baselines/reference/noStrictGenericChecks.js @@ -0,0 +1,15 @@ +//// [noStrictGenericChecks.ts] +type A = (x: T, y: U) => [T, U]; +type B = (x: S, y: S) => [S, S]; + +function f(a: A, b: B) { + a = b; // Error disabled here + b = a; // Ok +} + + +//// [noStrictGenericChecks.js] +function f(a, b) { + a = b; // Error disabled here + b = a; // Ok +} diff --git a/tests/baselines/reference/noStrictGenericChecks.symbols b/tests/baselines/reference/noStrictGenericChecks.symbols new file mode 100644 index 00000000000..5244cc44f2e --- /dev/null +++ b/tests/baselines/reference/noStrictGenericChecks.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/noStrictGenericChecks.ts === +type A = (x: T, y: U) => [T, U]; +>A : Symbol(A, Decl(noStrictGenericChecks.ts, 0, 0)) +>T : Symbol(T, Decl(noStrictGenericChecks.ts, 0, 10)) +>U : Symbol(U, Decl(noStrictGenericChecks.ts, 0, 12)) +>x : Symbol(x, Decl(noStrictGenericChecks.ts, 0, 16)) +>T : Symbol(T, Decl(noStrictGenericChecks.ts, 0, 10)) +>y : Symbol(y, Decl(noStrictGenericChecks.ts, 0, 21)) +>U : Symbol(U, Decl(noStrictGenericChecks.ts, 0, 12)) +>T : Symbol(T, Decl(noStrictGenericChecks.ts, 0, 10)) +>U : Symbol(U, Decl(noStrictGenericChecks.ts, 0, 12)) + +type B = (x: S, y: S) => [S, S]; +>B : Symbol(B, Decl(noStrictGenericChecks.ts, 0, 38)) +>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10)) +>x : Symbol(x, Decl(noStrictGenericChecks.ts, 1, 13)) +>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10)) +>y : Symbol(y, Decl(noStrictGenericChecks.ts, 1, 18)) +>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10)) +>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10)) +>S : Symbol(S, Decl(noStrictGenericChecks.ts, 1, 10)) + +function f(a: A, b: B) { +>f : Symbol(f, Decl(noStrictGenericChecks.ts, 1, 35)) +>a : Symbol(a, Decl(noStrictGenericChecks.ts, 3, 11)) +>A : Symbol(A, Decl(noStrictGenericChecks.ts, 0, 0)) +>b : Symbol(b, Decl(noStrictGenericChecks.ts, 3, 16)) +>B : Symbol(B, Decl(noStrictGenericChecks.ts, 0, 38)) + + a = b; // Error disabled here +>a : Symbol(a, Decl(noStrictGenericChecks.ts, 3, 11)) +>b : Symbol(b, Decl(noStrictGenericChecks.ts, 3, 16)) + + b = a; // Ok +>b : Symbol(b, Decl(noStrictGenericChecks.ts, 3, 16)) +>a : Symbol(a, Decl(noStrictGenericChecks.ts, 3, 11)) +} + diff --git a/tests/baselines/reference/noStrictGenericChecks.types b/tests/baselines/reference/noStrictGenericChecks.types new file mode 100644 index 00000000000..0509c22859a --- /dev/null +++ b/tests/baselines/reference/noStrictGenericChecks.types @@ -0,0 +1,40 @@ +=== tests/cases/compiler/noStrictGenericChecks.ts === +type A = (x: T, y: U) => [T, U]; +>A : A +>T : T +>U : U +>x : T +>T : T +>y : U +>U : U +>T : T +>U : U + +type B = (x: S, y: S) => [S, S]; +>B : B +>S : S +>x : S +>S : S +>y : S +>S : S +>S : S +>S : S + +function f(a: A, b: B) { +>f : (a: A, b: B) => void +>a : A +>A : A +>b : B +>B : B + + a = b; // Error disabled here +>a = b : B +>a : A +>b : B + + b = a; // Ok +>b = a : A +>b : B +>a : A +} + diff --git a/tests/baselines/reference/objectLiteralFunctionArgContextualTyping2.errors.txt b/tests/baselines/reference/objectLiteralFunctionArgContextualTyping2.errors.txt index b967b227809..0117d2c0c8c 100644 --- a/tests/baselines/reference/objectLiteralFunctionArgContextualTyping2.errors.txt +++ b/tests/baselines/reference/objectLiteralFunctionArgContextualTyping2.errors.txt @@ -4,12 +4,12 @@ tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(9,4): error TS Property 'doStuff' is missing in type '{ value: string; }'. tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(10,17): error TS2345: Argument of type '{ value: string; what: number; }' is not assignable to parameter of type 'I2'. Object literal may only specify known properties, and 'what' does not exist in type 'I2'. -tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(11,4): error TS2345: Argument of type '{ toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. - Property 'value' is missing in type '{ toString: (s: any) => any; }'. -tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(12,4): error TS2345: Argument of type '{ toString: (s: string) => string; }' is not assignable to parameter of type 'I2'. - Property 'value' is missing in type '{ toString: (s: string) => string; }'. -tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,4): error TS2345: Argument of type '{ value: string; toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. - Property 'doStuff' is missing in type '{ value: string; toString: (s: any) => any; }'. +tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(11,6): error TS2345: Argument of type '{ toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. + Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. +tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(12,6): error TS2345: Argument of type '{ toString: (s: string) => string; }' is not assignable to parameter of type 'I2'. + Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. +tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,17): error TS2345: Argument of type '{ value: string; toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. + Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. ==== tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts (6 errors) ==== @@ -33,14 +33,14 @@ tests/cases/compiler/objectLiteralFunctionArgContextualTyping2.ts(13,4): error T !!! error TS2345: Argument of type '{ value: string; what: number; }' is not assignable to parameter of type 'I2'. !!! error TS2345: Object literal may only specify known properties, and 'what' does not exist in type 'I2'. f2({ toString: (s) => s }) - ~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '{ toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. -!!! error TS2345: Property 'value' is missing in type '{ toString: (s: any) => any; }'. +!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. f2({ toString: (s: string) => s }) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '{ toString: (s: string) => string; }' is not assignable to parameter of type 'I2'. -!!! error TS2345: Property 'value' is missing in type '{ toString: (s: string) => string; }'. +!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. f2({ value: '', toString: (s) => s.uhhh }) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '{ value: string; toString: (s: any) => any; }' is not assignable to parameter of type 'I2'. -!!! error TS2345: Property 'doStuff' is missing in type '{ value: string; toString: (s: any) => any; }'. \ No newline at end of file +!!! error TS2345: Object literal may only specify known properties, and 'toString' does not exist in type 'I2'. \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index d9106d651a3..a9381a0dcb1 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -17,9 +17,15 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(52,9): error TS2339 tests/cases/conformance/types/spread/objectSpreadNegative.ts(57,11): error TS2339: Property 'a' does not exist on type '{}'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS2698: Spread types may only be created from object types. tests/cases/conformance/types/spread/objectSpreadNegative.ts(64,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(78,37): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. + Object literal may only specify known properties, and 'extra' does not exist in type 'A'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(81,7): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. + Object literal may only specify known properties, and 'extra' does not exist in type 'A'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(83,7): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. + Object literal may only specify known properties, and 'extra' does not exist in type 'A'. -==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (16 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (19 errors) ==== let o = { a: 1, b: 'no' } /// private propagates @@ -128,4 +134,23 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(64,14): error TS269 f({ a: 1 }, { a: 'mismatch' }) let overwriteId: { id: string, a: number, c: number, d: string } = f({ a: 1, id: true }, { c: 1, d: 'no' }) + + // excess property checks + type A = { a: string, b: string }; + type Extra = { a: string, b: string, extra: string }; + const extra1: A = { a: "a", b: "b", extra: "extra" }; + ~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. +!!! error TS2322: Object literal may only specify known properties, and 'extra' does not exist in type 'A'. + const extra2 = { a: "a", b: "b", extra: "extra" }; + const a1: A = { ...extra1 }; // error spans should be here + const a2: A = { ...extra2 }; // not on the symbol declarations above + ~~ +!!! error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. +!!! error TS2322: Object literal may only specify known properties, and 'extra' does not exist in type 'A'. + const extra3: Extra = { a: "a", b: "b", extra: "extra" }; + const a3: A = { ...extra3 }; // same here + ~~ +!!! error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. +!!! error TS2322: Object literal may only specify known properties, and 'extra' does not exist in type 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index fd834b6ef9c..0cc93692b59 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -72,6 +72,16 @@ let overlapConflict: { id:string, a: string } = f({ a: 1 }, { a: 'mismatch' }) let overwriteId: { id: string, a: number, c: number, d: string } = f({ a: 1, id: true }, { c: 1, d: 'no' }) + +// excess property checks +type A = { a: string, b: string }; +type Extra = { a: string, b: string, extra: string }; +const extra1: A = { a: "a", b: "b", extra: "extra" }; +const extra2 = { a: "a", b: "b", extra: "extra" }; +const a1: A = { ...extra1 }; // error spans should be here +const a2: A = { ...extra2 }; // not on the symbol declarations above +const extra3: Extra = { a: "a", b: "b", extra: "extra" }; +const a3: A = { ...extra3 }; // same here //// [objectSpreadNegative.js] @@ -152,3 +162,9 @@ var exclusive = f({ a: 1, b: 'yes' }, { c: 'no', d: false }); var overlap = f({ a: 1 }, { a: 2, b: 'extra' }); var overlapConflict = f({ a: 1 }, { a: 'mismatch' }); var overwriteId = f({ a: 1, id: true }, { c: 1, d: 'no' }); +var extra1 = { a: "a", b: "b", extra: "extra" }; +var extra2 = { a: "a", b: "b", extra: "extra" }; +var a1 = __assign({}, extra1); // error spans should be here +var a2 = __assign({}, extra2); // not on the symbol declarations above +var extra3 = { a: "a", b: "b", extra: "extra" }; +var a3 = __assign({}, extra3); // same here diff --git a/tests/baselines/reference/objectSpreadStrictNull.errors.txt b/tests/baselines/reference/objectSpreadStrictNull.errors.txt index f3c5cc7de25..791b5419eb1 100644 --- a/tests/baselines/reference/objectSpreadStrictNull.errors.txt +++ b/tests/baselines/reference/objectSpreadStrictNull.errors.txt @@ -1,11 +1,3 @@ -tests/cases/conformance/types/spread/objectSpreadStrictNull.ts(9,9): error TS2322: Type '{ sn: string | number | undefined; }' is not assignable to type '{ sn: string | number; }'. - Types of property 'sn' are incompatible. - Type 'string | number | undefined' is not assignable to type 'string | number'. - Type 'undefined' is not assignable to type 'string | number'. -tests/cases/conformance/types/spread/objectSpreadStrictNull.ts(10,9): error TS2322: Type '{ sn: string | number | undefined; }' is not assignable to type '{ sn: string | number; }'. - Types of property 'sn' are incompatible. - Type 'string | number | undefined' is not assignable to type 'string | number'. - Type 'undefined' is not assignable to type 'string | number'. tests/cases/conformance/types/spread/objectSpreadStrictNull.ts(14,9): error TS2322: Type '{ sn: number | undefined; }' is not assignable to type '{ sn: string | number; }'. Types of property 'sn' are incompatible. Type 'number | undefined' is not assignable to type 'string | number'. @@ -21,9 +13,13 @@ tests/cases/conformance/types/spread/objectSpreadStrictNull.ts(18,9): error TS23 tests/cases/conformance/types/spread/objectSpreadStrictNull.ts(28,7): error TS2322: Type '{ title: undefined; yearReleased: number; }' is not assignable to type 'Movie'. Types of property 'title' are incompatible. Type 'undefined' is not assignable to type 'string'. +tests/cases/conformance/types/spread/objectSpreadStrictNull.ts(42,5): error TS2322: Type '{ foo: number | undefined; bar: string | undefined; }' is not assignable to type 'Fields'. + Types of property 'foo' are incompatible. + Type 'number | undefined' is not assignable to type 'number'. + Type 'undefined' is not assignable to type 'number'. -==== tests/cases/conformance/types/spread/objectSpreadStrictNull.ts (6 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadStrictNull.ts (5 errors) ==== function f( definiteBoolean: { sn: boolean }, definiteString: { sn: string }, @@ -33,17 +29,7 @@ tests/cases/conformance/types/spread/objectSpreadStrictNull.ts(28,7): error TS23 undefinedNumber: { sn: number | undefined }) { // optional let optionalUnionStops: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; - ~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ sn: string | number | undefined; }' is not assignable to type '{ sn: string | number; }'. -!!! error TS2322: Types of property 'sn' are incompatible. -!!! error TS2322: Type 'string | number | undefined' is not assignable to type 'string | number'. -!!! error TS2322: Type 'undefined' is not assignable to type 'string | number'. let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; - ~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2322: Type '{ sn: string | number | undefined; }' is not assignable to type '{ sn: string | number; }'. -!!! error TS2322: Types of property 'sn' are incompatible. -!!! error TS2322: Type 'string | number | undefined' is not assignable to type 'string | number'. -!!! error TS2322: Type 'undefined' is not assignable to type 'string | number'. let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; // undefined @@ -81,4 +67,24 @@ tests/cases/conformance/types/spread/objectSpreadStrictNull.ts(28,7): error TS23 !!! error TS2322: Type '{ title: undefined; yearReleased: number; }' is not assignable to type 'Movie'. !!! error TS2322: Types of property 'title' are incompatible. !!! error TS2322: Type 'undefined' is not assignable to type 'string'. + + interface Fields { + foo: number; + bar: string; + } + interface NearlyPartialFields { + foo: number | undefined; + bar: string | undefined; + } + function g(fields: Fields, partialFields: Partial, nearlyPartialFields: NearlyPartialFields) { + // ok, undefined is stripped from optional properties when spread + fields = { ...fields, ...partialFields }; + // error: not optional, undefined remains + fields = { ...fields, ...nearlyPartialFields }; + ~~~~~~ +!!! error TS2322: Type '{ foo: number | undefined; bar: string | undefined; }' is not assignable to type 'Fields'. +!!! error TS2322: Types of property 'foo' are incompatible. +!!! error TS2322: Type 'number | undefined' is not assignable to type 'number'. +!!! error TS2322: Type 'undefined' is not assignable to type 'number'. + } \ No newline at end of file diff --git a/tests/baselines/reference/objectSpreadStrictNull.js b/tests/baselines/reference/objectSpreadStrictNull.js index a21b5e2467c..521d83f37af 100644 --- a/tests/baselines/reference/objectSpreadStrictNull.js +++ b/tests/baselines/reference/objectSpreadStrictNull.js @@ -27,6 +27,21 @@ type Movie = { const m = { title: "The Matrix", yearReleased: 1999 }; // should error here because title: undefined is not assignable to string const x: Movie = { ...m, title: undefined }; + +interface Fields { + foo: number; + bar: string; +} +interface NearlyPartialFields { + foo: number | undefined; + bar: string | undefined; +} +function g(fields: Fields, partialFields: Partial, nearlyPartialFields: NearlyPartialFields) { + // ok, undefined is stripped from optional properties when spread + fields = { ...fields, ...partialFields }; + // error: not optional, undefined remains + fields = { ...fields, ...nearlyPartialFields }; +} //// [objectSpreadStrictNull.js] @@ -52,3 +67,9 @@ function f(definiteBoolean, definiteString, optionalString, optionalNumber, unde var m = { title: "The Matrix", yearReleased: 1999 }; // should error here because title: undefined is not assignable to string var x = __assign({}, m, { title: undefined }); +function g(fields, partialFields, nearlyPartialFields) { + // ok, undefined is stripped from optional properties when spread + fields = __assign({}, fields, partialFields); + // error: not optional, undefined remains + fields = __assign({}, fields, nearlyPartialFields); +} diff --git a/tests/baselines/reference/optionalMethods.js b/tests/baselines/reference/optionalMethods.js index d219466c562..2abcd209277 100644 --- a/tests/baselines/reference/optionalMethods.js +++ b/tests/baselines/reference/optionalMethods.js @@ -131,12 +131,12 @@ interface Foo { } declare function test1(x: Foo): void; declare class Bar { - d: number; + d: number | undefined; e: number; a: number; b?: number; c?: number | undefined; - constructor(d?: number, e?: number); + constructor(d?: number | undefined, e?: number); f(): number; g?(): number; h?(): number; diff --git a/tests/baselines/reference/parser15.4.4.14-9-2.errors.txt b/tests/baselines/reference/parser15.4.4.14-9-2.errors.txt index 2c721724b3e..925bb07d9f9 100644 --- a/tests/baselines/reference/parser15.4.4.14-9-2.errors.txt +++ b/tests/baselines/reference/parser15.4.4.14-9-2.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/parser/ecmascript5/parser15.4.4.14-9-2.ts(16,15): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'false'. +tests/cases/conformance/parser/ecmascript5/parser15.4.4.14-9-2.ts(16,42): error TS2345: Argument of type '"0"' is not assignable to parameter of type 'boolean'. tests/cases/conformance/parser/ecmascript5/parser15.4.4.14-9-2.ts(25,1): error TS2304: Cannot find name 'runTestCase'. @@ -20,9 +19,8 @@ tests/cases/conformance/parser/ecmascript5/parser15.4.4.14-9-2.ts(25,1): error T var one = 1; var _float = -(4/3); var a = new Array(false,undefined,null,"0",obj,-1.3333333333333, "str",-0,true,+0, one, 1,0, false, _float, -(4/3)); - ~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'false'. + ~~~ +!!! error TS2345: Argument of type '"0"' is not assignable to parameter of type 'boolean'. if (a.indexOf(-(4/3)) === 14 && // a[14]=_float===-(4/3) a.indexOf(0) === 7 && // a[7] = +0, 0===+0 a.indexOf(-0) === 7 && // a[7] = +0, -0===+0 diff --git a/tests/baselines/reference/printerApi/printsNodeCorrectly.functionTypes.js b/tests/baselines/reference/printerApi/printsNodeCorrectly.functionTypes.js new file mode 100644 index 00000000000..5bfda3ba7c9 --- /dev/null +++ b/tests/baselines/reference/printerApi/printsNodeCorrectly.functionTypes.js @@ -0,0 +1 @@ +[args => any, (args) => any, (...args) => any, (args?) => any, (args: any) => any, ({}) => any] \ No newline at end of file diff --git a/tests/baselines/reference/promisePermutations.errors.txt b/tests/baselines/reference/promisePermutations.errors.txt index 8b46f18666f..a876345ffa1 100644 --- a/tests/baselines/reference/promisePermutations.errors.txt +++ b/tests/baselines/reference/promisePermutations.errors.txt @@ -36,18 +36,18 @@ tests/cases/compiler/promisePermutations.ts(120,19): error TS2345: Argument of t tests/cases/compiler/promisePermutations.ts(121,19): error TS2345: Argument of type '(x: T, cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: number) => Promise'. tests/cases/compiler/promisePermutations.ts(122,19): error TS2345: Argument of type '(x: T, cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: number) => IPromise'. tests/cases/compiler/promisePermutations.ts(126,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => IPromise' is not assignable to parameter of type '(value: number) => IPromise'. -tests/cases/compiler/promisePermutations.ts(129,11): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. +tests/cases/compiler/promisePermutations.ts(129,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/promisePermutations.ts(132,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => IPromise' is not assignable to parameter of type '(value: number) => IPromise'. tests/cases/compiler/promisePermutations.ts(133,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => Promise' is not assignable to parameter of type '(value: number) => Promise'. tests/cases/compiler/promisePermutations.ts(134,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => Promise' is not assignable to parameter of type '(value: number) => IPromise'. -tests/cases/compiler/promisePermutations.ts(137,11): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -tests/cases/compiler/promisePermutations.ts(144,12): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -tests/cases/compiler/promisePermutations.ts(152,12): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'Promise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. +tests/cases/compiler/promisePermutations.ts(137,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. +tests/cases/compiler/promisePermutations.ts(144,35): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. +tests/cases/compiler/promisePermutations.ts(152,36): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. + Type 'IPromise' is not assignable to type 'Promise'. Types of property 'then' are incompatible. Type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. Types of parameters 'success' and 'onfulfilled' are incompatible. @@ -260,10 +260,10 @@ tests/cases/compiler/promisePermutations.ts(160,21): error TS2345: Argument of t var r9b = r9.then(sIPromise, sIPromise, sIPromise); // ok var r9c = r9.then(nIPromise, nIPromise, nIPromise); // ok var r9d = r9.then(testFunction, sIPromise, nIPromise); // ok - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -!!! error TS2453: Type 'string' is not assignable to type 'number'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var r9e = r9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s9: Promise; var s9a = s9.then(testFunction9, testFunction9, testFunction9); // error @@ -278,9 +278,9 @@ tests/cases/compiler/promisePermutations.ts(160,21): error TS2345: Argument of t var s9d = s9.then(sPromise, sPromise, sPromise); // ok var s9e = s9.then(nPromise, nPromise, nPromise); // ok var s9f = s9.then(testFunction, sIPromise, nIPromise); // error - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var s9g = s9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var r10 = testFunction10(x => x); @@ -288,9 +288,9 @@ tests/cases/compiler/promisePermutations.ts(160,21): error TS2345: Argument of t var r10b = r10.then(sIPromise, sIPromise, sIPromise); // ok var r10c = r10.then(nIPromise, nIPromise, nIPromise); // ok var r10d = r10.then(testFunction, sIPromise, nIPromise); // ok - ~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); var s10a = s10.then(testFunction10, testFunction10, testFunction10); // ok @@ -299,14 +299,14 @@ tests/cases/compiler/promisePermutations.ts(160,21): error TS2345: Argument of t var s10d = s10.then(sPromise, sPromise, sPromise); // ok var s10e = s10.then(nIPromise, nPromise, nIPromise); // ok var s10f = s10.then(testFunctionP, sIPromise, nIPromise); // error - ~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'Promise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -!!! error TS2453: Types of property 'then' are incompatible. -!!! error TS2453: Type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. -!!! error TS2453: Types of parameters 'success' and 'onfulfilled' are incompatible. -!!! error TS2453: Types of parameters 'value' and 'value' are incompatible. -!!! error TS2453: Type 'string' is not assignable to type 'number'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'Promise'. +!!! error TS2345: Types of property 'then' are incompatible. +!!! error TS2345: Type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. +!!! error TS2345: Types of parameters 'success' and 'onfulfilled' are incompatible. +!!! error TS2345: Types of parameters 'value' and 'value' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var s10g = s10.then(testFunctionP, nIPromise, sIPromise).then(sPromise, sIPromise, sIPromise); // ok var r11: IPromise; diff --git a/tests/baselines/reference/promisePermutations2.errors.txt b/tests/baselines/reference/promisePermutations2.errors.txt index 32df80e20f1..871ee2ae2c3 100644 --- a/tests/baselines/reference/promisePermutations2.errors.txt +++ b/tests/baselines/reference/promisePermutations2.errors.txt @@ -36,18 +36,18 @@ tests/cases/compiler/promisePermutations2.ts(119,19): error TS2345: Argument of tests/cases/compiler/promisePermutations2.ts(120,19): error TS2345: Argument of type '(x: T, cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: number) => Promise'. tests/cases/compiler/promisePermutations2.ts(121,19): error TS2345: Argument of type '(x: T, cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: number) => IPromise'. tests/cases/compiler/promisePermutations2.ts(125,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => IPromise' is not assignable to parameter of type '(value: number) => IPromise'. -tests/cases/compiler/promisePermutations2.ts(128,11): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. +tests/cases/compiler/promisePermutations2.ts(128,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/promisePermutations2.ts(131,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => IPromise' is not assignable to parameter of type '(value: number) => IPromise'. tests/cases/compiler/promisePermutations2.ts(132,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => Promise' is not assignable to parameter of type '(value: number) => Promise'. tests/cases/compiler/promisePermutations2.ts(133,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => Promise' is not assignable to parameter of type '(value: number) => IPromise'. -tests/cases/compiler/promisePermutations2.ts(136,11): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -tests/cases/compiler/promisePermutations2.ts(143,12): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -tests/cases/compiler/promisePermutations2.ts(151,12): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'Promise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. +tests/cases/compiler/promisePermutations2.ts(136,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. +tests/cases/compiler/promisePermutations2.ts(143,35): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. +tests/cases/compiler/promisePermutations2.ts(151,36): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. + Type 'IPromise' is not assignable to type 'Promise'. Types of property 'then' are incompatible. Type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. Types of parameters 'success' and 'onfulfilled' are incompatible. @@ -259,10 +259,10 @@ tests/cases/compiler/promisePermutations2.ts(159,21): error TS2345: Argument of var r9b = r9.then(sIPromise, sIPromise, sIPromise); // ok var r9c = r9.then(nIPromise, nIPromise, nIPromise); // ok var r9d = r9.then(testFunction, sIPromise, nIPromise); // error - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -!!! error TS2453: Type 'string' is not assignable to type 'number'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var r9e = r9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s9: Promise; var s9a = s9.then(testFunction9, testFunction9, testFunction9); // error @@ -277,9 +277,9 @@ tests/cases/compiler/promisePermutations2.ts(159,21): error TS2345: Argument of var s9d = s9.then(sPromise, sPromise, sPromise); // ok var s9e = s9.then(nPromise, nPromise, nPromise); // ok var s9f = s9.then(testFunction, sIPromise, nIPromise); // error - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var s9g = s9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var r10 = testFunction10(x => x); @@ -287,9 +287,9 @@ tests/cases/compiler/promisePermutations2.ts(159,21): error TS2345: Argument of var r10b = r10.then(sIPromise, sIPromise, sIPromise); // ok var r10c = r10.then(nIPromise, nIPromise, nIPromise); // ok var r10d = r10.then(testFunction, sIPromise, nIPromise); // error - ~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); var s10a = s10.then(testFunction10, testFunction10, testFunction10); // ok @@ -298,14 +298,14 @@ tests/cases/compiler/promisePermutations2.ts(159,21): error TS2345: Argument of var s10d = s10.then(sPromise, sPromise, sPromise); // ok var s10e = s10.then(nIPromise, nPromise, nIPromise); // ok var s10f = s10.then(testFunctionP, sIPromise, nIPromise); // error - ~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'Promise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -!!! error TS2453: Types of property 'then' are incompatible. -!!! error TS2453: Type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. -!!! error TS2453: Types of parameters 'success' and 'onfulfilled' are incompatible. -!!! error TS2453: Types of parameters 'value' and 'value' are incompatible. -!!! error TS2453: Type 'string' is not assignable to type 'number'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'Promise'. +!!! error TS2345: Types of property 'then' are incompatible. +!!! error TS2345: Type '{ (success?: (value: string) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; }' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. +!!! error TS2345: Types of parameters 'success' and 'onfulfilled' are incompatible. +!!! error TS2345: Types of parameters 'value' and 'value' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var s10g = s10.then(testFunctionP, nIPromise, sIPromise).then(sPromise, sIPromise, sIPromise); // ok var r11: IPromise; diff --git a/tests/baselines/reference/promisePermutations3.errors.txt b/tests/baselines/reference/promisePermutations3.errors.txt index 3d9fc1b2d26..9d09559c5d3 100644 --- a/tests/baselines/reference/promisePermutations3.errors.txt +++ b/tests/baselines/reference/promisePermutations3.errors.txt @@ -39,18 +39,18 @@ tests/cases/compiler/promisePermutations3.ts(119,19): error TS2345: Argument of tests/cases/compiler/promisePermutations3.ts(120,19): error TS2345: Argument of type '(x: T, cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: number) => Promise'. tests/cases/compiler/promisePermutations3.ts(121,19): error TS2345: Argument of type '(x: T, cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: number) => IPromise'. tests/cases/compiler/promisePermutations3.ts(125,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => IPromise' is not assignable to parameter of type '(value: number) => IPromise'. -tests/cases/compiler/promisePermutations3.ts(128,11): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. +tests/cases/compiler/promisePermutations3.ts(128,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/promisePermutations3.ts(131,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => IPromise' is not assignable to parameter of type '(value: number) => IPromise'. tests/cases/compiler/promisePermutations3.ts(132,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => Promise' is not assignable to parameter of type '(value: number) => Promise'. tests/cases/compiler/promisePermutations3.ts(133,19): error TS2345: Argument of type '(x: T, cb: (a: U) => U) => Promise' is not assignable to parameter of type '(value: number) => IPromise'. -tests/cases/compiler/promisePermutations3.ts(136,11): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -tests/cases/compiler/promisePermutations3.ts(143,12): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -tests/cases/compiler/promisePermutations3.ts(151,12): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'Promise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. +tests/cases/compiler/promisePermutations3.ts(136,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. +tests/cases/compiler/promisePermutations3.ts(143,35): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. +tests/cases/compiler/promisePermutations3.ts(151,36): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. + Type 'IPromise' is not assignable to type 'Promise'. Types of property 'then' are incompatible. Type '(success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. Types of parameters 'success' and 'onfulfilled' are incompatible. @@ -271,10 +271,10 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of var r9b = r9.then(sIPromise, sIPromise, sIPromise); // ok var r9c = r9.then(nIPromise, nIPromise, nIPromise); // ok var r9d = r9.then(testFunction, sIPromise, nIPromise); // error - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -!!! error TS2453: Type 'string' is not assignable to type 'number'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var r9e = r9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s9: Promise; var s9a = s9.then(testFunction9, testFunction9, testFunction9); // error @@ -289,9 +289,9 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of var s9d = s9.then(sPromise, sPromise, sPromise); // ok var s9e = s9.then(nPromise, nPromise, nPromise); // ok var s9f = s9.then(testFunction, sIPromise, nIPromise); // error - ~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var s9g = s9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var r10 = testFunction10(x => x); @@ -299,9 +299,9 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of var r10b = r10.then(sIPromise, sIPromise, sIPromise); // ok var r10c = r10.then(nIPromise, nIPromise, nIPromise); // ok var r10d = r10.then(testFunction, sIPromise, nIPromise); // error - ~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'IPromise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); var s10a = s10.then(testFunction10, testFunction10, testFunction10); // ok @@ -310,14 +310,14 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of var s10d = s10.then(sPromise, sPromise, sPromise); // ok var s10e = s10.then(nIPromise, nPromise, nIPromise); // ok var s10f = s10.then(testFunctionP, sIPromise, nIPromise); // error - ~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'Promise' is not a valid type argument because it is not a supertype of candidate 'IPromise'. -!!! error TS2453: Types of property 'then' are incompatible. -!!! error TS2453: Type '(success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. -!!! error TS2453: Types of parameters 'success' and 'onfulfilled' are incompatible. -!!! error TS2453: Types of parameters 'value' and 'value' are incompatible. -!!! error TS2453: Type 'string' is not assignable to type 'number'. + ~~~~~~~~~ +!!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'Promise'. +!!! error TS2345: Types of property 'then' are incompatible. +!!! error TS2345: Type '(success?: (value: string) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise' is not assignable to type '{ (onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: number) => Promise, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => Promise, error?: (error: any) => U, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => Promise, progress?: (progress: any) => void): Promise; (success?: (value: number) => U, error?: (error: any) => U, progress?: (progress: any) => void): Promise; }'. +!!! error TS2345: Types of parameters 'success' and 'onfulfilled' are incompatible. +!!! error TS2345: Types of parameters 'value' and 'value' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var s10g = s10.then(testFunctionP, nIPromise, sIPromise).then(sPromise, sIPromise, sIPromise); // ok var r11: IPromise; diff --git a/tests/baselines/reference/promiseTypeInference.errors.txt b/tests/baselines/reference/promiseTypeInference.errors.txt new file mode 100644 index 00000000000..fab56c73375 --- /dev/null +++ b/tests/baselines/reference/promiseTypeInference.errors.txt @@ -0,0 +1,31 @@ +tests/cases/compiler/promiseTypeInference.ts(10,34): error TS2345: Argument of type '(s: string) => IPromise' is not assignable to parameter of type '(value: string) => number | PromiseLike'. + Type 'IPromise' is not assignable to type 'number | PromiseLike'. + Type 'IPromise' is not assignable to type 'PromiseLike'. + Types of property 'then' are incompatible. + Type '(success?: (value: number) => IPromise) => IPromise' is not assignable to type '(onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. + Types of parameters 'success' and 'onfulfilled' are incompatible. + Type 'TResult1 | PromiseLike' is not assignable to type 'IPromise'. + Type 'TResult1' is not assignable to type 'IPromise'. + + +==== tests/cases/compiler/promiseTypeInference.ts (1 errors) ==== + declare class Promise { + then(success?: (value: T) => Promise): Promise; + } + interface IPromise { + then(success?: (value: T) => IPromise): IPromise; + } + declare function load(name: string): Promise; + declare function convert(s: string): IPromise; + + var $$x = load("something").then(s => convert(s)); + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(s: string) => IPromise' is not assignable to parameter of type '(value: string) => number | PromiseLike'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'number | PromiseLike'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'PromiseLike'. +!!! error TS2345: Types of property 'then' are incompatible. +!!! error TS2345: Type '(success?: (value: number) => IPromise) => IPromise' is not assignable to type '(onfulfilled?: (value: number) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => PromiseLike'. +!!! error TS2345: Types of parameters 'success' and 'onfulfilled' are incompatible. +!!! error TS2345: Type 'TResult1 | PromiseLike' is not assignable to type 'IPromise'. +!!! error TS2345: Type 'TResult1' is not assignable to type 'IPromise'. + \ No newline at end of file diff --git a/tests/baselines/reference/returnInfiniteIntersection.js b/tests/baselines/reference/returnInfiniteIntersection.js new file mode 100644 index 00000000000..db77d21f32d --- /dev/null +++ b/tests/baselines/reference/returnInfiniteIntersection.js @@ -0,0 +1,15 @@ +//// [returnInfiniteIntersection.ts] +function recursive() { + let x = (subkey: T) => recursive(); + return x as typeof x & { p }; +} + +let result = recursive()(1) + + +//// [returnInfiniteIntersection.js] +function recursive() { + var x = function (subkey) { return recursive(); }; + return x; +} +var result = recursive()(1); diff --git a/tests/baselines/reference/returnInfiniteIntersection.symbols b/tests/baselines/reference/returnInfiniteIntersection.symbols new file mode 100644 index 00000000000..125861ac78d --- /dev/null +++ b/tests/baselines/reference/returnInfiniteIntersection.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/returnInfiniteIntersection.ts === +function recursive() { +>recursive : Symbol(recursive, Decl(returnInfiniteIntersection.ts, 0, 0)) + + let x = (subkey: T) => recursive(); +>x : Symbol(x, Decl(returnInfiniteIntersection.ts, 1, 7)) +>T : Symbol(T, Decl(returnInfiniteIntersection.ts, 1, 13)) +>subkey : Symbol(subkey, Decl(returnInfiniteIntersection.ts, 1, 16)) +>T : Symbol(T, Decl(returnInfiniteIntersection.ts, 1, 13)) +>recursive : Symbol(recursive, Decl(returnInfiniteIntersection.ts, 0, 0)) + + return x as typeof x & { p }; +>x : Symbol(x, Decl(returnInfiniteIntersection.ts, 1, 7)) +>x : Symbol(x, Decl(returnInfiniteIntersection.ts, 1, 7)) +>p : Symbol(p, Decl(returnInfiniteIntersection.ts, 2, 28)) +} + +let result = recursive()(1) +>result : Symbol(result, Decl(returnInfiniteIntersection.ts, 5, 3)) +>recursive : Symbol(recursive, Decl(returnInfiniteIntersection.ts, 0, 0)) + diff --git a/tests/baselines/reference/returnInfiniteIntersection.types b/tests/baselines/reference/returnInfiniteIntersection.types new file mode 100644 index 00000000000..e7ca48a69d1 --- /dev/null +++ b/tests/baselines/reference/returnInfiniteIntersection.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/returnInfiniteIntersection.ts === +function recursive() { +>recursive : () => ((subkey: T) => any & { p: any; }) & { p: any; } + + let x = (subkey: T) => recursive(); +>x : (subkey: T) => any & { p: any; } +>(subkey: T) => recursive() : (subkey: T) => any & { p: any; } +>T : T +>subkey : T +>T : T +>recursive() : ((subkey: T) => any & { p: any; }) & { p: any; } +>recursive : () => ((subkey: T) => any & { p: any; }) & { p: any; } + + return x as typeof x & { p }; +>x as typeof x & { p } : ((subkey: T) => any & { p: any; }) & { p: any; } +>x : (subkey: T) => any & { p: any; } +>x : (subkey: T) => any & { p: any; } +>p : any +} + +let result = recursive()(1) +>result : ((subkey: T) => any & { p: any; }) & { p: any; } +>recursive()(1) : ((subkey: T) => any & { p: any; }) & { p: any; } +>recursive() : ((subkey: T) => any & { p: any; }) & { p: any; } +>recursive : () => ((subkey: T) => any & { p: any; }) & { p: any; } +>1 : 1 + diff --git a/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.js b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.js new file mode 100644 index 00000000000..24a27fb919a --- /dev/null +++ b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.js @@ -0,0 +1,14 @@ +//// [sourceMapValidationVarInDownLevelGenerator.ts] +function * f() { + var x = 1, y; +} + +//// [sourceMapValidationVarInDownLevelGenerator.js] +function f() { + var x, y; + return __generator(this, function (_a) { + x = 1; + return [2 /*return*/]; + }); +} +//# sourceMappingURL=sourceMapValidationVarInDownLevelGenerator.js.map \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.js.map b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.js.map new file mode 100644 index 00000000000..293f445a6fd --- /dev/null +++ b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.js.map @@ -0,0 +1,2 @@ +//// [sourceMapValidationVarInDownLevelGenerator.js.map] +{"version":3,"file":"sourceMapValidationVarInDownLevelGenerator.js","sourceRoot":"","sources":["sourceMapValidationVarInDownLevelGenerator.ts"],"names":[],"mappings":"AAAA;;;QACQ,CAAC,GAAG,CAAC,CAAI;;;CAChB"} \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.sourcemap.txt b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.sourcemap.txt new file mode 100644 index 00000000000..8fe7af32307 --- /dev/null +++ b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.sourcemap.txt @@ -0,0 +1,47 @@ +=================================================================== +JsFile: sourceMapValidationVarInDownLevelGenerator.js +mapUrl: sourceMapValidationVarInDownLevelGenerator.js.map +sourceRoot: +sources: sourceMapValidationVarInDownLevelGenerator.ts +=================================================================== +------------------------------------------------------------------- +emittedFile:tests/cases/compiler/sourceMapValidationVarInDownLevelGenerator.js +sourceFile:sourceMapValidationVarInDownLevelGenerator.ts +------------------------------------------------------------------- +>>>function f() { +1 > +2 >^^^^^^^^^^^^^^-> +1 > +1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0) +--- +>>> var x, y; +>>> return __generator(this, function (_a) { +>>> x = 1; +1->^^^^^^^^ +2 > ^ +3 > ^^^ +4 > ^ +5 > ^ +6 > ^^^^^^^^^^^^^^^^^-> +1->function * f() { + > var +2 > x +3 > = +4 > 1 +5 > , y; +1->Emitted(4, 9) Source(2, 9) + SourceIndex(0) +2 >Emitted(4, 10) Source(2, 10) + SourceIndex(0) +3 >Emitted(4, 13) Source(2, 13) + SourceIndex(0) +4 >Emitted(4, 14) Source(2, 14) + SourceIndex(0) +5 >Emitted(4, 15) Source(2, 18) + SourceIndex(0) +--- +>>> return [2 /*return*/]; +>>> }); +>>>} +1->^ +2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1-> + >} +1->Emitted(7, 2) Source(3, 2) + SourceIndex(0) +--- +>>>//# sourceMappingURL=sourceMapValidationVarInDownLevelGenerator.js.map \ No newline at end of file diff --git a/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.symbols b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.symbols new file mode 100644 index 00000000000..99c9c4d714a --- /dev/null +++ b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/sourceMapValidationVarInDownLevelGenerator.ts === +function * f() { +>f : Symbol(f, Decl(sourceMapValidationVarInDownLevelGenerator.ts, 0, 0)) + + var x = 1, y; +>x : Symbol(x, Decl(sourceMapValidationVarInDownLevelGenerator.ts, 1, 7)) +>y : Symbol(y, Decl(sourceMapValidationVarInDownLevelGenerator.ts, 1, 14)) +} diff --git a/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.types b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.types new file mode 100644 index 00000000000..cac2f03d8e4 --- /dev/null +++ b/tests/baselines/reference/sourceMapValidationVarInDownLevelGenerator.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/sourceMapValidationVarInDownLevelGenerator.ts === +function * f() { +>f : () => IterableIterator + + var x = 1, y; +>x : number +>1 : 1 +>y : any +} diff --git a/tests/baselines/reference/spreadUnion.symbols b/tests/baselines/reference/spreadUnion.symbols index 40a63d56d49..bef8f5522d7 100644 --- a/tests/baselines/reference/spreadUnion.symbols +++ b/tests/baselines/reference/spreadUnion.symbols @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadUnion.ts === +=== tests/cases/conformance/types/spread/spreadUnion.ts === var union: { a: number } | { b: string }; >union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) >a : Symbol(a, Decl(spreadUnion.ts, 0, 12)) diff --git a/tests/baselines/reference/spreadUnion.types b/tests/baselines/reference/spreadUnion.types index 9e5ac1cffd5..fb1ef5f2018 100644 --- a/tests/baselines/reference/spreadUnion.types +++ b/tests/baselines/reference/spreadUnion.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadUnion.ts === +=== tests/cases/conformance/types/spread/spreadUnion.ts === var union: { a: number } | { b: string }; >union : { a: number; } | { b: string; } >a : number diff --git a/tests/baselines/reference/spreadUnion2.js b/tests/baselines/reference/spreadUnion2.js index b98046463c3..6e49770617a 100644 --- a/tests/baselines/reference/spreadUnion2.js +++ b/tests/baselines/reference/spreadUnion2.js @@ -3,25 +3,25 @@ declare const undefinedUnion: { a: number } | undefined; declare const nullUnion: { b: number } | null; declare const nullAndUndefinedUnion: null | undefined; -var o1: { a: number }; +var o1: {} | { a: number }; var o1 = { ...undefinedUnion }; -var o2: { b: number }; +var o2: {} | { b: number }; var o2 = { ...nullUnion }; -var o3: { a: number, b: number }; +var o3: {} | { b: number } | { a: number } | { a: number, b: number }; var o3 = { ...undefinedUnion, ...nullUnion }; var o3 = { ...nullUnion, ...undefinedUnion }; -var o4: { a: number }; +var o4: {} | { a: number }; var o4 = { ...undefinedUnion, ...undefinedUnion }; -var o5: { b: number }; +var o5: {} | { b: number }; var o5 = { ...nullUnion, ...nullUnion }; -var o6: { }; var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; -var o6 = { ...nullAndUndefinedUnion }; +var o7 = { ...nullAndUndefinedUnion }; + //// [spreadUnion2.js] var __assign = (this && this.__assign) || Object.assign || function(t) { @@ -43,6 +43,5 @@ var o4; var o4 = __assign({}, undefinedUnion, undefinedUnion); var o5; var o5 = __assign({}, nullUnion, nullUnion); -var o6; var o6 = __assign({}, nullAndUndefinedUnion, nullAndUndefinedUnion); -var o6 = __assign({}, nullAndUndefinedUnion); +var o7 = __assign({}, nullAndUndefinedUnion); diff --git a/tests/baselines/reference/spreadUnion2.symbols b/tests/baselines/reference/spreadUnion2.symbols index 05703fc32bd..c4d1f19b6d9 100644 --- a/tests/baselines/reference/spreadUnion2.symbols +++ b/tests/baselines/reference/spreadUnion2.symbols @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadUnion2.ts === +=== tests/cases/conformance/types/spread/spreadUnion2.ts === declare const undefinedUnion: { a: number } | undefined; >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) >a : Symbol(a, Decl(spreadUnion2.ts, 0, 31)) @@ -10,26 +10,28 @@ declare const nullUnion: { b: number } | null; declare const nullAndUndefinedUnion: null | undefined; >nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) -var o1: { a: number }; +var o1: {} | { a: number }; >o1 : Symbol(o1, Decl(spreadUnion2.ts, 4, 3), Decl(spreadUnion2.ts, 5, 3)) ->a : Symbol(a, Decl(spreadUnion2.ts, 4, 9)) +>a : Symbol(a, Decl(spreadUnion2.ts, 4, 14)) var o1 = { ...undefinedUnion }; >o1 : Symbol(o1, Decl(spreadUnion2.ts, 4, 3), Decl(spreadUnion2.ts, 5, 3)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) -var o2: { b: number }; +var o2: {} | { b: number }; >o2 : Symbol(o2, Decl(spreadUnion2.ts, 7, 3), Decl(spreadUnion2.ts, 8, 3)) ->b : Symbol(b, Decl(spreadUnion2.ts, 7, 9)) +>b : Symbol(b, Decl(spreadUnion2.ts, 7, 14)) var o2 = { ...nullUnion }; >o2 : Symbol(o2, Decl(spreadUnion2.ts, 7, 3), Decl(spreadUnion2.ts, 8, 3)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) -var o3: { a: number, b: number }; +var o3: {} | { b: number } | { a: number } | { a: number, b: number }; >o3 : Symbol(o3, Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3)) ->a : Symbol(a, Decl(spreadUnion2.ts, 10, 9)) ->b : Symbol(b, Decl(spreadUnion2.ts, 10, 20)) +>b : Symbol(b, Decl(spreadUnion2.ts, 10, 14)) +>a : Symbol(a, Decl(spreadUnion2.ts, 10, 30)) +>a : Symbol(a, Decl(spreadUnion2.ts, 10, 46)) +>b : Symbol(b, Decl(spreadUnion2.ts, 10, 57)) var o3 = { ...undefinedUnion, ...nullUnion }; >o3 : Symbol(o3, Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3)) @@ -41,33 +43,30 @@ var o3 = { ...nullUnion, ...undefinedUnion }; >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) -var o4: { a: number }; +var o4: {} | { a: number }; >o4 : Symbol(o4, Decl(spreadUnion2.ts, 14, 3), Decl(spreadUnion2.ts, 15, 3)) ->a : Symbol(a, Decl(spreadUnion2.ts, 14, 9)) +>a : Symbol(a, Decl(spreadUnion2.ts, 14, 14)) var o4 = { ...undefinedUnion, ...undefinedUnion }; >o4 : Symbol(o4, Decl(spreadUnion2.ts, 14, 3), Decl(spreadUnion2.ts, 15, 3)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) -var o5: { b: number }; +var o5: {} | { b: number }; >o5 : Symbol(o5, Decl(spreadUnion2.ts, 17, 3), Decl(spreadUnion2.ts, 18, 3)) ->b : Symbol(b, Decl(spreadUnion2.ts, 17, 9)) +>b : Symbol(b, Decl(spreadUnion2.ts, 17, 14)) var o5 = { ...nullUnion, ...nullUnion }; >o5 : Symbol(o5, Decl(spreadUnion2.ts, 17, 3), Decl(spreadUnion2.ts, 18, 3)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) -var o6: { }; ->o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3), Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3)) - var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; ->o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3), Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3)) +>o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3)) >nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) >nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) -var o6 = { ...nullAndUndefinedUnion }; ->o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3), Decl(spreadUnion2.ts, 21, 3), Decl(spreadUnion2.ts, 22, 3)) +var o7 = { ...nullAndUndefinedUnion }; +>o7 : Symbol(o7, Decl(spreadUnion2.ts, 21, 3)) >nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) diff --git a/tests/baselines/reference/spreadUnion2.types b/tests/baselines/reference/spreadUnion2.types index 97fbb9838c7..ea3364f296b 100644 --- a/tests/baselines/reference/spreadUnion2.types +++ b/tests/baselines/reference/spreadUnion2.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadUnion2.ts === +=== tests/cases/conformance/types/spread/spreadUnion2.ts === declare const undefinedUnion: { a: number } | undefined; >undefinedUnion : { a: number; } | undefined >a : number @@ -12,72 +12,71 @@ declare const nullAndUndefinedUnion: null | undefined; >nullAndUndefinedUnion : null | undefined >null : null -var o1: { a: number }; ->o1 : { a: number; } +var o1: {} | { a: number }; +>o1 : {} | { a: number; } >a : number var o1 = { ...undefinedUnion }; ->o1 : { a: number; } ->{ ...undefinedUnion } : { a: number; } +>o1 : {} | { a: number; } +>{ ...undefinedUnion } : {} | { a: number; } >undefinedUnion : { a: number; } | undefined -var o2: { b: number }; ->o2 : { b: number; } +var o2: {} | { b: number }; +>o2 : {} | { b: number; } >b : number var o2 = { ...nullUnion }; ->o2 : { b: number; } ->{ ...nullUnion } : { b: number; } +>o2 : {} | { b: number; } +>{ ...nullUnion } : {} | { b: number; } >nullUnion : { b: number; } | null -var o3: { a: number, b: number }; ->o3 : { a: number; b: number; } +var o3: {} | { b: number } | { a: number } | { a: number, b: number }; +>o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } +>b : number +>a : number >a : number >b : number var o3 = { ...undefinedUnion, ...nullUnion }; ->o3 : { a: number; b: number; } ->{ ...undefinedUnion, ...nullUnion } : { b: number; a: number; } +>o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } +>{ ...undefinedUnion, ...nullUnion } : {} | { b: number; } | { a: number; } | { b: number; a: number; } >undefinedUnion : { a: number; } | undefined >nullUnion : { b: number; } | null var o3 = { ...nullUnion, ...undefinedUnion }; ->o3 : { a: number; b: number; } ->{ ...nullUnion, ...undefinedUnion } : { a: number; b: number; } +>o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } +>{ ...nullUnion, ...undefinedUnion } : {} | { a: number; } | { b: number; } | { a: number; b: number; } >nullUnion : { b: number; } | null >undefinedUnion : { a: number; } | undefined -var o4: { a: number }; ->o4 : { a: number; } +var o4: {} | { a: number }; +>o4 : {} | { a: number; } >a : number var o4 = { ...undefinedUnion, ...undefinedUnion }; ->o4 : { a: number; } ->{ ...undefinedUnion, ...undefinedUnion } : { a: number; } +>o4 : {} | { a: number; } +>{ ...undefinedUnion, ...undefinedUnion } : {} | { a: number; } | { a: number; } | { a: number; } >undefinedUnion : { a: number; } | undefined >undefinedUnion : { a: number; } | undefined -var o5: { b: number }; ->o5 : { b: number; } +var o5: {} | { b: number }; +>o5 : {} | { b: number; } >b : number var o5 = { ...nullUnion, ...nullUnion }; ->o5 : { b: number; } ->{ ...nullUnion, ...nullUnion } : { b: number; } +>o5 : {} | { b: number; } +>{ ...nullUnion, ...nullUnion } : {} | { b: number; } | { b: number; } | { b: number; } >nullUnion : { b: number; } | null >nullUnion : { b: number; } | null -var o6: { }; ->o6 : {} - var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; ->o6 : {} ->{ ...nullAndUndefinedUnion, ...nullAndUndefinedUnion } : {} +>o6 : {} | {} | {} | {} +>{ ...nullAndUndefinedUnion, ...nullAndUndefinedUnion } : {} | {} | {} | {} >nullAndUndefinedUnion : null | undefined >nullAndUndefinedUnion : null | undefined -var o6 = { ...nullAndUndefinedUnion }; ->o6 : {} ->{ ...nullAndUndefinedUnion } : {} +var o7 = { ...nullAndUndefinedUnion }; +>o7 : {} | {} +>{ ...nullAndUndefinedUnion } : {} | {} >nullAndUndefinedUnion : null | undefined diff --git a/tests/baselines/reference/spreadUnion3.errors.txt b/tests/baselines/reference/spreadUnion3.errors.txt new file mode 100644 index 00000000000..5f5b620685c --- /dev/null +++ b/tests/baselines/reference/spreadUnion3.errors.txt @@ -0,0 +1,31 @@ +tests/cases/conformance/types/spread/spreadUnion3.ts(2,5): error TS2322: Type '{ y: number; } | { y: string; }' is not assignable to type '{ y: string; }'. + Type '{ y: number; }' is not assignable to type '{ y: string; }'. + Types of property 'y' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/spread/spreadUnion3.ts(9,23): error TS2339: Property 'a' does not exist on type '{} | {} | { a: number; }'. + Property 'a' does not exist on type '{}'. + + +==== tests/cases/conformance/types/spread/spreadUnion3.ts (2 errors) ==== + function f(x: { y: string } | undefined): { y: string } { + return { y: 123, ...x } // y: string | number + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ y: number; } | { y: string; }' is not assignable to type '{ y: string; }'. +!!! error TS2322: Type '{ y: number; }' is not assignable to type '{ y: string; }'. +!!! error TS2322: Types of property 'y' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + } + f(undefined) + + + function g(t?: { a: number } | null): void { + let b = { ...t }; + let c: number = b.a; // might not have 'a' + ~ +!!! error TS2339: Property 'a' does not exist on type '{} | {} | { a: number; }'. +!!! error TS2339: Property 'a' does not exist on type '{}'. + } + g() + g(undefined) + g(null) + \ No newline at end of file diff --git a/tests/baselines/reference/spreadUnion3.js b/tests/baselines/reference/spreadUnion3.js new file mode 100644 index 00000000000..2aaf9efeb78 --- /dev/null +++ b/tests/baselines/reference/spreadUnion3.js @@ -0,0 +1,36 @@ +//// [spreadUnion3.ts] +function f(x: { y: string } | undefined): { y: string } { + return { y: 123, ...x } // y: string | number +} +f(undefined) + + +function g(t?: { a: number } | null): void { + let b = { ...t }; + let c: number = b.a; // might not have 'a' +} +g() +g(undefined) +g(null) + + +//// [spreadUnion3.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +function f(x) { + return __assign({ y: 123 }, x); // y: string | number +} +f(undefined); +function g(t) { + var b = __assign({}, t); + var c = b.a; // might not have 'a' +} +g(); +g(undefined); +g(null); diff --git a/tests/baselines/reference/subtypingWithCallSignatures2.types b/tests/baselines/reference/subtypingWithCallSignatures2.types index 86c65702b98..029262380d8 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures2.types +++ b/tests/baselines/reference/subtypingWithCallSignatures2.types @@ -325,20 +325,20 @@ var r1arg2 = (x: number) => [1]; >1 : 1 var r1 = foo1(r1arg1); // any, return types are not subtype of first overload ->r1 : any ->foo1(r1arg1) : any +>r1 : (x: number) => number[] +>foo1(r1arg1) : (x: number) => number[] >foo1 : { (a: (x: number) => number[]): (x: number) => number[]; (a: any): any; } >r1arg1 : (x: T) => T[] var r1a = [r1arg2, r1arg1]; // generic signature, subtype in both directions ->r1a : ((x: T) => T[])[] ->[r1arg2, r1arg1] : ((x: T) => T[])[] +>r1a : ((x: number) => number[])[] +>[r1arg2, r1arg1] : ((x: number) => number[])[] >r1arg2 : (x: number) => number[] >r1arg1 : (x: T) => T[] var r1b = [r1arg1, r1arg2]; // generic signature, subtype in both directions ->r1b : ((x: T) => T[])[] ->[r1arg1, r1arg2] : ((x: T) => T[])[] +>r1b : ((x: number) => number[])[] +>[r1arg1, r1arg2] : ((x: number) => number[])[] >r1arg1 : (x: T) => T[] >r1arg2 : (x: number) => number[] @@ -365,14 +365,14 @@ var r2 = foo2(r2arg1); >r2arg1 : (x: T) => string[] var r2a = [r2arg1, r2arg2]; ->r2a : ((x: T) => string[])[] ->[r2arg1, r2arg2] : ((x: T) => string[])[] +>r2a : ((x: number) => string[])[] +>[r2arg1, r2arg2] : ((x: number) => string[])[] >r2arg1 : (x: T) => string[] >r2arg2 : (x: number) => string[] var r2b = [r2arg2, r2arg1]; ->r2b : ((x: T) => string[])[] ->[r2arg2, r2arg1] : ((x: T) => string[])[] +>r2b : ((x: number) => string[])[] +>[r2arg2, r2arg1] : ((x: number) => string[])[] >r2arg2 : (x: number) => string[] >r2arg1 : (x: T) => string[] @@ -396,14 +396,14 @@ var r3 = foo3(r3arg1); >r3arg1 : (x: T) => T var r3a = [r3arg1, r3arg2]; ->r3a : ((x: T) => T)[] ->[r3arg1, r3arg2] : ((x: T) => T)[] +>r3a : ((x: number) => void)[] +>[r3arg1, r3arg2] : ((x: number) => void)[] >r3arg1 : (x: T) => T >r3arg2 : (x: number) => void var r3b = [r3arg2, r3arg1]; ->r3b : ((x: T) => T)[] ->[r3arg2, r3arg1] : ((x: T) => T)[] +>r3b : ((x: number) => void)[] +>[r3arg2, r3arg1] : ((x: number) => void)[] >r3arg2 : (x: number) => void >r3arg1 : (x: T) => T @@ -426,20 +426,20 @@ var r4arg2 = (x: string, y: number) => ''; >'' : "" var r4 = foo4(r4arg1); // any ->r4 : any ->foo4(r4arg1) : any +>r4 : (x: string, y: number) => string +>foo4(r4arg1) : (x: string, y: number) => string >foo4 : { (a: (x: string, y: number) => string): (x: string, y: number) => string; (a: any): any; } >r4arg1 : (x: T, y: U) => T var r4a = [r4arg1, r4arg2]; ->r4a : ((x: T, y: U) => T)[] ->[r4arg1, r4arg2] : ((x: T, y: U) => T)[] +>r4a : ((x: string, y: number) => string)[] +>[r4arg1, r4arg2] : ((x: string, y: number) => string)[] >r4arg1 : (x: T, y: U) => T >r4arg2 : (x: string, y: number) => string var r4b = [r4arg2, r4arg1]; ->r4b : ((x: T, y: U) => T)[] ->[r4arg2, r4arg1] : ((x: T, y: U) => T)[] +>r4b : ((x: string, y: number) => string)[] +>[r4arg2, r4arg1] : ((x: string, y: number) => string)[] >r4arg2 : (x: string, y: number) => string >r4arg1 : (x: T, y: U) => T @@ -464,20 +464,20 @@ var r5arg2 = (x: (arg: string) => number) => ''; >'' : "" var r5 = foo5(r5arg1); // any ->r5 : any ->foo5(r5arg1) : any +>r5 : (x: (arg: string) => number) => string +>foo5(r5arg1) : (x: (arg: string) => number) => string >foo5 : { (a: (x: (arg: string) => number) => string): (x: (arg: string) => number) => string; (a: any): any; } >r5arg1 : (x: (arg: T) => U) => T var r5a = [r5arg1, r5arg2]; ->r5a : ((x: (arg: T) => U) => T)[] ->[r5arg1, r5arg2] : ((x: (arg: T) => U) => T)[] +>r5a : ((x: (arg: string) => number) => string)[] +>[r5arg1, r5arg2] : ((x: (arg: string) => number) => string)[] >r5arg1 : (x: (arg: T) => U) => T >r5arg2 : (x: (arg: string) => number) => string var r5b = [r5arg2, r5arg1]; ->r5b : ((x: (arg: T) => U) => T)[] ->[r5arg2, r5arg1] : ((x: (arg: T) => U) => T)[] +>r5b : ((x: (arg: string) => number) => string)[] +>[r5arg2, r5arg1] : ((x: (arg: string) => number) => string)[] >r5arg2 : (x: (arg: string) => number) => string >r5arg1 : (x: (arg: T) => U) => T @@ -508,20 +508,20 @@ var r6arg2 = (x: (arg: Base) => Derived) => null; >null : null var r6 = foo6(r6arg1); // any ->r6 : any ->foo6(r6arg1) : any +>r6 : (x: (arg: Base) => Derived) => Base +>foo6(r6arg1) : (x: (arg: Base) => Derived) => Base >foo6 : { (a: (x: (arg: Base) => Derived) => Base): (x: (arg: Base) => Derived) => Base; (a: any): any; } >r6arg1 : (x: (arg: T) => U) => T var r6a = [r6arg1, r6arg2]; ->r6a : ((x: (arg: T) => U) => T)[] ->[r6arg1, r6arg2] : ((x: (arg: T) => U) => T)[] +>r6a : ((x: (arg: Base) => Derived) => Base)[] +>[r6arg1, r6arg2] : ((x: (arg: Base) => Derived) => Base)[] >r6arg1 : (x: (arg: T) => U) => T >r6arg2 : (x: (arg: Base) => Derived) => Base var r6b = [r6arg2, r6arg1]; ->r6b : ((x: (arg: T) => U) => T)[] ->[r6arg2, r6arg1] : ((x: (arg: T) => U) => T)[] +>r6b : ((x: (arg: Base) => Derived) => Base)[] +>[r6arg2, r6arg1] : ((x: (arg: Base) => Derived) => Base)[] >r6arg2 : (x: (arg: Base) => Derived) => Base >r6arg1 : (x: (arg: T) => U) => T @@ -558,20 +558,20 @@ var r7arg2 = (x: (arg: Base) => Derived) => (r: Base) => null; >null : null var r7 = foo7(r7arg1); // any ->r7 : any ->foo7(r7arg1) : any +>r7 : (x: (arg: Base) => Derived) => (r: Base) => Derived +>foo7(r7arg1) : (x: (arg: Base) => Derived) => (r: Base) => Derived >foo7 : { (a: (x: (arg: Base) => Derived) => (r: Base) => Derived): (x: (arg: Base) => Derived) => (r: Base) => Derived; (a: any): any; } >r7arg1 : (x: (arg: T) => U) => (r: T) => U var r7a = [r7arg1, r7arg2]; ->r7a : ((x: (arg: T) => U) => (r: T) => U)[] ->[r7arg1, r7arg2] : ((x: (arg: T) => U) => (r: T) => U)[] +>r7a : ((x: (arg: Base) => Derived) => (r: Base) => Derived)[] +>[r7arg1, r7arg2] : ((x: (arg: Base) => Derived) => (r: Base) => Derived)[] >r7arg1 : (x: (arg: T) => U) => (r: T) => U >r7arg2 : (x: (arg: Base) => Derived) => (r: Base) => Derived var r7b = [r7arg2, r7arg1]; ->r7b : ((x: (arg: T) => U) => (r: T) => U)[] ->[r7arg2, r7arg1] : ((x: (arg: T) => U) => (r: T) => U)[] +>r7b : ((x: (arg: Base) => Derived) => (r: Base) => Derived)[] +>[r7arg2, r7arg1] : ((x: (arg: Base) => Derived) => (r: Base) => Derived)[] >r7arg2 : (x: (arg: Base) => Derived) => (r: Base) => Derived >r7arg1 : (x: (arg: T) => U) => (r: T) => U @@ -616,20 +616,20 @@ var r8arg2 = (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base >null : null var r8 = foo8(r8arg1); // any ->r8 : any ->foo8(r8arg1) : any +>r8 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived +>foo8(r8arg1) : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived >foo8 : { (a: (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived): (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived; (a: any): any; } >r8arg1 : (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U var r8a = [r8arg1, r8arg2]; ->r8a : ((x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U)[] ->[r8arg1, r8arg2] : ((x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U)[] +>r8a : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[] +>[r8arg1, r8arg2] : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[] >r8arg1 : (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U >r8arg2 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived var r8b = [r8arg2, r8arg1]; ->r8b : ((x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U)[] ->[r8arg2, r8arg1] : ((x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U)[] +>r8b : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[] +>[r8arg2, r8arg1] : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[] >r8arg2 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived >r8arg1 : (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U @@ -675,20 +675,20 @@ var r9arg2 = (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base >null : null var r9 = foo9(r9arg1); // any ->r9 : any ->foo9(r9arg1) : any +>r9 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived +>foo9(r9arg1) : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived >foo9 : { (a: (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived): (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived; (a: any): any; } >r9arg1 : (x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U var r9a = [r9arg1, r9arg2]; ->r9a : (((x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U) | ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived))[] ->[r9arg1, r9arg2] : (((x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U) | ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived))[] +>r9a : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[] +>[r9arg1, r9arg2] : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[] >r9arg1 : (x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U >r9arg2 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived var r9b = [r9arg2, r9arg1]; ->r9b : (((x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U) | ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived))[] ->[r9arg2, r9arg1] : (((x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U) | ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived))[] +>r9b : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[] +>[r9arg2, r9arg1] : ((x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived)[] >r9arg2 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived >r9arg1 : (x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U @@ -713,20 +713,20 @@ var r10arg2 = (...x: Derived[]) => null; >null : null var r10 = foo10(r10arg1); // any ->r10 : any ->foo10(r10arg1) : any +>r10 : (...x: Derived[]) => Derived +>foo10(r10arg1) : (...x: Derived[]) => Derived >foo10 : { (a: (...x: Derived[]) => Derived): (...x: Derived[]) => Derived; (a: any): any; } >r10arg1 : (...x: T[]) => T var r10a = [r10arg1, r10arg2]; ->r10a : ((...x: T[]) => T)[] ->[r10arg1, r10arg2] : ((...x: T[]) => T)[] +>r10a : ((...x: Derived[]) => Derived)[] +>[r10arg1, r10arg2] : ((...x: Derived[]) => Derived)[] >r10arg1 : (...x: T[]) => T >r10arg2 : (...x: Derived[]) => Derived var r10b = [r10arg2, r10arg1]; ->r10b : ((...x: T[]) => T)[] ->[r10arg2, r10arg1] : ((...x: T[]) => T)[] +>r10b : ((...x: Derived[]) => Derived)[] +>[r10arg2, r10arg1] : ((...x: Derived[]) => Derived)[] >r10arg2 : (...x: Derived[]) => Derived >r10arg1 : (...x: T[]) => T @@ -754,20 +754,20 @@ var r11arg2 = (x: { foo: string }, y: { foo: string; bar: string }) => nul >null : null var r11 = foo11(r11arg1); // any ->r11 : any ->foo11(r11arg1) : any +>r11 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base +>foo11(r11arg1) : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >foo11 : { (a: (x: { foo: string; }, y: { foo: string; bar: string; }) => Base): (x: { foo: string; }, y: { foo: string; bar: string; }) => Base; (a: any): any; } >r11arg1 : (x: T, y: T) => T var r11a = [r11arg1, r11arg2]; ->r11a : ((x: T, y: T) => T)[] ->[r11arg1, r11arg2] : ((x: T, y: T) => T)[] +>r11a : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] +>[r11arg1, r11arg2] : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] >r11arg1 : (x: T, y: T) => T >r11arg2 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base var r11b = [r11arg2, r11arg1]; ->r11b : ((x: T, y: T) => T)[] ->[r11arg2, r11arg1] : ((x: T, y: T) => T)[] +>r11b : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] +>[r11arg2, r11arg1] : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] >r11arg2 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >r11arg1 : (x: T, y: T) => T @@ -808,14 +808,14 @@ var r12 = foo12(r12arg1); // any >r12arg1 : (x: Base[], y: T) => Derived[] var r12a = [r12arg1, r12arg2]; ->r12a : ((x: Base[], y: T) => Derived[])[] ->[r12arg1, r12arg2] : ((x: Base[], y: T) => Derived[])[] +>r12a : ((x: Base[], y: Derived2[]) => Derived[])[] +>[r12arg1, r12arg2] : ((x: Base[], y: Derived2[]) => Derived[])[] >r12arg1 : (x: Base[], y: T) => Derived[] >r12arg2 : (x: Base[], y: Derived2[]) => Derived[] var r12b = [r12arg2, r12arg1]; ->r12b : ((x: Base[], y: T) => Derived[])[] ->[r12arg2, r12arg1] : ((x: Base[], y: T) => Derived[])[] +>r12b : ((x: Base[], y: Derived2[]) => Derived[])[] +>[r12arg2, r12arg1] : ((x: Base[], y: Derived2[]) => Derived[])[] >r12arg2 : (x: Base[], y: Derived2[]) => Derived[] >r12arg1 : (x: Base[], y: T) => Derived[] @@ -847,20 +847,20 @@ var r13arg2 = (x: Array, y: Array) => >null; >null : null var r13 = foo13(r13arg1); // any ->r13 : any ->foo13(r13arg1) : any +>r13 : (x: Base[], y: Derived[]) => Derived[] +>foo13(r13arg1) : (x: Base[], y: Derived[]) => Derived[] >foo13 : { (a: (x: Base[], y: Derived[]) => Derived[]): (x: Base[], y: Derived[]) => Derived[]; (a: any): any; } >r13arg1 : (x: Base[], y: T) => T var r13a = [r13arg1, r13arg2]; ->r13a : ((x: Base[], y: T) => T)[] ->[r13arg1, r13arg2] : ((x: Base[], y: T) => T)[] +>r13a : ((x: Base[], y: Derived[]) => Derived[])[] +>[r13arg1, r13arg2] : ((x: Base[], y: Derived[]) => Derived[])[] >r13arg1 : (x: Base[], y: T) => T >r13arg2 : (x: Base[], y: Derived[]) => Derived[] var r13b = [r13arg2, r13arg1]; ->r13b : ((x: Base[], y: T) => T)[] ->[r13arg2, r13arg1] : ((x: Base[], y: T) => T)[] +>r13b : ((x: Base[], y: Derived[]) => Derived[])[] +>[r13arg2, r13arg1] : ((x: Base[], y: Derived[]) => Derived[])[] >r13arg2 : (x: Base[], y: Derived[]) => Derived[] >r13arg1 : (x: Base[], y: T) => T @@ -888,20 +888,20 @@ var r14arg2 = (x: { a: string; b: number }) => null; >null : null var r14 = foo14(r14arg1); // any ->r14 : any ->foo14(r14arg1) : any +>r14 : (x: { a: string; b: number; }) => Object +>foo14(r14arg1) : (x: { a: string; b: number; }) => Object >foo14 : { (a: (x: { a: string; b: number; }) => Object): (x: { a: string; b: number; }) => Object; (a: any): any; } >r14arg1 : (x: { a: T; b: T; }) => T var r14a = [r14arg1, r14arg2]; ->r14a : ((x: { a: T; b: T; }) => T)[] ->[r14arg1, r14arg2] : ((x: { a: T; b: T; }) => T)[] +>r14a : ((x: { a: string; b: number; }) => Object)[] +>[r14arg1, r14arg2] : ((x: { a: string; b: number; }) => Object)[] >r14arg1 : (x: { a: T; b: T; }) => T >r14arg2 : (x: { a: string; b: number; }) => Object var r14b = [r14arg2, r14arg1]; ->r14b : ((x: { a: T; b: T; }) => T)[] ->[r14arg2, r14arg1] : ((x: { a: T; b: T; }) => T)[] +>r14b : ((x: { a: string; b: number; }) => Object)[] +>[r14arg2, r14arg1] : ((x: { a: string; b: number; }) => Object)[] >r14arg2 : (x: { a: string; b: number; }) => Object >r14arg1 : (x: { a: T; b: T; }) => T diff --git a/tests/baselines/reference/subtypingWithCallSignatures3.types b/tests/baselines/reference/subtypingWithCallSignatures3.types index 6abc7567efb..99953d899f2 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures3.types +++ b/tests/baselines/reference/subtypingWithCallSignatures3.types @@ -206,8 +206,8 @@ module Errors { >a2 : any var r1 = foo2((x: T) => null); // any ->r1 : any ->foo2((x: T) => null) : any +>r1 : (x: number) => string[] +>foo2((x: T) => null) : (x: number) => string[] >foo2 : { (a2: (x: number) => string[]): (x: number) => string[]; (a2: any): any; } >(x: T) => null : (x: T) => U[] >T : T @@ -219,8 +219,8 @@ module Errors { >null : null var r1a = [(x: number) => [''], (x: T) => null]; ->r1a : ((x: T) => U[])[] ->[(x: number) => [''], (x: T) => null] : ((x: T) => U[])[] +>r1a : ((x: number) => string[])[] +>[(x: number) => [''], (x: T) => null] : ((x: number) => string[])[] >(x: number) => [''] : (x: number) => string[] >x : number >[''] : string[] @@ -235,8 +235,8 @@ module Errors { >null : null var r1b = [(x: T) => null, (x: number) => ['']]; ->r1b : ((x: T) => U[])[] ->[(x: T) => null, (x: number) => ['']] : ((x: T) => U[])[] +>r1b : ((x: number) => string[])[] +>[(x: T) => null, (x: number) => ['']] : ((x: number) => string[])[] >(x: T) => null : (x: T) => U[] >T : T >U : U @@ -285,20 +285,20 @@ module Errors { >null : null var r2 = foo7(r2arg); // any ->r2 : any ->foo7(r2arg) : any +>r2 : (x: (arg: Base) => Derived) => (r: Base) => Derived2 +>foo7(r2arg) : (x: (arg: Base) => Derived) => (r: Base) => Derived2 >foo7 : { (a2: (x: (arg: Base) => Derived) => (r: Base) => Derived2): (x: (arg: Base) => Derived) => (r: Base) => Derived2; (a2: any): any; } >r2arg : (x: (arg: T) => U) => (r: T) => V var r2a = [r2arg2, r2arg]; ->r2a : ((x: (arg: T) => U) => (r: T) => V)[] ->[r2arg2, r2arg] : ((x: (arg: T) => U) => (r: T) => V)[] +>r2a : ((x: (arg: Base) => Derived) => (r: Base) => Derived2)[] +>[r2arg2, r2arg] : ((x: (arg: Base) => Derived) => (r: Base) => Derived2)[] >r2arg2 : (x: (arg: Base) => Derived) => (r: Base) => Derived2 >r2arg : (x: (arg: T) => U) => (r: T) => V var r2b = [r2arg, r2arg2]; ->r2b : ((x: (arg: T) => U) => (r: T) => V)[] ->[r2arg, r2arg2] : ((x: (arg: T) => U) => (r: T) => V)[] +>r2b : ((x: (arg: Base) => Derived) => (r: Base) => Derived2)[] +>[r2arg, r2arg2] : ((x: (arg: Base) => Derived) => (r: Base) => Derived2)[] >r2arg : (x: (arg: T) => U) => (r: T) => V >r2arg2 : (x: (arg: Base) => Derived) => (r: Base) => Derived2 @@ -381,20 +381,20 @@ module Errors { >null : null var r4 = foo10(r4arg); // any ->r4 : any ->foo10(r4arg) : any +>r4 : (...x: Base[]) => Base +>foo10(r4arg) : (...x: Base[]) => Base >foo10 : { (a2: (...x: Base[]) => Base): (...x: Base[]) => Base; (a2: any): any; } >r4arg : (...x: T[]) => T var r4a = [r4arg2, r4arg]; ->r4a : ((...x: T[]) => T)[] ->[r4arg2, r4arg] : ((...x: T[]) => T)[] +>r4a : ((...x: Base[]) => Base)[] +>[r4arg2, r4arg] : ((...x: Base[]) => Base)[] >r4arg2 : (...x: Base[]) => Base >r4arg : (...x: T[]) => T var r4b = [r4arg, r4arg2]; ->r4b : ((...x: T[]) => T)[] ->[r4arg, r4arg2] : ((...x: T[]) => T)[] +>r4b : ((...x: Base[]) => Base)[] +>[r4arg, r4arg2] : ((...x: Base[]) => Base)[] >r4arg : (...x: T[]) => T >r4arg2 : (...x: Base[]) => Base @@ -424,20 +424,20 @@ module Errors { >null : null var r5 = foo11(r5arg); // any ->r5 : any ->foo11(r5arg) : any +>r5 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base +>foo11(r5arg) : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >foo11 : { (a2: (x: { foo: string; }, y: { foo: string; bar: string; }) => Base): (x: { foo: string; }, y: { foo: string; bar: string; }) => Base; (a2: any): any; } >r5arg : (x: T, y: T) => T var r5a = [r5arg2, r5arg]; ->r5a : ((x: T, y: T) => T)[] ->[r5arg2, r5arg] : ((x: T, y: T) => T)[] +>r5a : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] +>[r5arg2, r5arg] : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] >r5arg2 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >r5arg : (x: T, y: T) => T var r5b = [r5arg, r5arg2]; ->r5b : ((x: T, y: T) => T)[] ->[r5arg, r5arg2] : ((x: T, y: T) => T)[] +>r5b : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] +>[r5arg, r5arg2] : ((x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] >r5arg : (x: T, y: T) => T >r5arg2 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base @@ -478,14 +478,14 @@ module Errors { >r6arg : (x: Base[], y: Derived2[]) => Derived[] var r6a = [r6arg2, r6arg]; ->r6a : ((x: Base[], y: Base[]) => T)[] ->[r6arg2, r6arg] : ((x: Base[], y: Base[]) => T)[] +>r6a : ((x: Base[], y: Derived2[]) => Derived[])[] +>[r6arg2, r6arg] : ((x: Base[], y: Derived2[]) => Derived[])[] >r6arg2 : (x: Base[], y: Base[]) => T >r6arg : (x: Base[], y: Derived2[]) => Derived[] var r6b = [r6arg, r6arg2]; ->r6b : ((x: Base[], y: Base[]) => T)[] ->[r6arg, r6arg2] : ((x: Base[], y: Base[]) => T)[] +>r6b : ((x: Base[], y: Derived2[]) => Derived[])[] +>[r6arg, r6arg2] : ((x: Base[], y: Derived2[]) => Derived[])[] >r6arg : (x: Base[], y: Derived2[]) => Derived[] >r6arg2 : (x: Base[], y: Base[]) => T @@ -517,14 +517,14 @@ module Errors { >r7arg : (x: { a: T; b: T; }) => T var r7a = [r7arg2, r7arg]; ->r7a : ((x: { a: T; b: T; }) => T)[] ->[r7arg2, r7arg] : ((x: { a: T; b: T; }) => T)[] +>r7a : (((x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => number))[] +>[r7arg2, r7arg] : (((x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => number))[] >r7arg2 : (x: { a: string; b: number; }) => number >r7arg : (x: { a: T; b: T; }) => T var r7b = [r7arg, r7arg2]; ->r7b : ((x: { a: T; b: T; }) => T)[] ->[r7arg, r7arg2] : ((x: { a: T; b: T; }) => T)[] +>r7b : (((x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => number))[] +>[r7arg, r7arg2] : (((x: { a: T; b: T; }) => T) | ((x: { a: string; b: number; }) => number))[] >r7arg : (x: { a: T; b: T; }) => T >r7arg2 : (x: { a: string; b: number; }) => number @@ -541,20 +541,20 @@ module Errors { >1 : 1 var r7c = foo15(r7arg3); // (x: { a: string; b: number }) => number): number; ->r7c : (x: { a: string; b: number; }) => number ->foo15(r7arg3) : (x: { a: string; b: number; }) => number +>r7c : any +>foo15(r7arg3) : any >foo15 : { (a2: (x: { a: string; b: number; }) => number): (x: { a: string; b: number; }) => number; (a2: any): any; } >r7arg3 : (x: { a: T; b: T; }) => number var r7d = [r7arg2, r7arg3]; ->r7d : ((x: { a: string; b: number; }) => number)[] ->[r7arg2, r7arg3] : ((x: { a: string; b: number; }) => number)[] +>r7d : (((x: { a: string; b: number; }) => number) | ((x: { a: T; b: T; }) => number))[] +>[r7arg2, r7arg3] : (((x: { a: string; b: number; }) => number) | ((x: { a: T; b: T; }) => number))[] >r7arg2 : (x: { a: string; b: number; }) => number >r7arg3 : (x: { a: T; b: T; }) => number var r7e = [r7arg3, r7arg2]; ->r7e : ((x: { a: string; b: number; }) => number)[] ->[r7arg3, r7arg2] : ((x: { a: string; b: number; }) => number)[] +>r7e : (((x: { a: string; b: number; }) => number) | ((x: { a: T; b: T; }) => number))[] +>[r7arg3, r7arg2] : (((x: { a: string; b: number; }) => number) | ((x: { a: T; b: T; }) => number))[] >r7arg3 : (x: { a: T; b: T; }) => number >r7arg2 : (x: { a: string; b: number; }) => number @@ -620,8 +620,8 @@ module WithGenericSignaturesInBaseType { >'' : "" var r2 = foo2(r2arg2); // (x:T) => T[] since we can infer from generic signatures now ->r2 : (x: T) => T[] ->foo2(r2arg2) : (x: T) => T[] +>r2 : any +>foo2(r2arg2) : any >foo2 : { (a2: (x: T) => T[]): (x: T) => T[]; (a2: any): any; } >r2arg2 : (x: T) => string[] diff --git a/tests/baselines/reference/subtypingWithCallSignatures4.types b/tests/baselines/reference/subtypingWithCallSignatures4.types index 5926636289a..3751b9c73dd 100644 --- a/tests/baselines/reference/subtypingWithCallSignatures4.types +++ b/tests/baselines/reference/subtypingWithCallSignatures4.types @@ -317,14 +317,14 @@ var r3 = foo3(r3arg); >r3arg : (x: T) => T var r3a = [r3arg, r3arg2]; ->r3a : ((x: T) => T)[] ->[r3arg, r3arg2] : ((x: T) => T)[] +>r3a : ((x: T) => void)[] +>[r3arg, r3arg2] : ((x: T) => void)[] >r3arg : (x: T) => T >r3arg2 : (x: T) => void var r3b = [r3arg2, r3arg]; ->r3b : ((x: T) => T)[] ->[r3arg2, r3arg] : ((x: T) => T)[] +>r3b : ((x: T) => void)[] +>[r3arg2, r3arg] : ((x: T) => void)[] >r3arg2 : (x: T) => void >r3arg : (x: T) => T @@ -543,14 +543,14 @@ var r15 = foo15(r15arg); >r15arg : (x: { a: U; b: V; }) => U[] var r15a = [r15arg, r15arg2]; ->r15a : ((x: { a: U; b: V; }) => U[])[] ->[r15arg, r15arg2] : ((x: { a: U; b: V; }) => U[])[] +>r15a : ((x: { a: T; b: T; }) => T[])[] +>[r15arg, r15arg2] : ((x: { a: T; b: T; }) => T[])[] >r15arg : (x: { a: U; b: V; }) => U[] >r15arg2 : (x: { a: T; b: T; }) => T[] var r15b = [r15arg2, r15arg]; ->r15b : ((x: { a: U; b: V; }) => U[])[] ->[r15arg2, r15arg] : ((x: { a: U; b: V; }) => U[])[] +>r15b : ((x: { a: T; b: T; }) => T[])[] +>[r15arg2, r15arg] : ((x: { a: T; b: T; }) => T[])[] >r15arg2 : (x: { a: T; b: T; }) => T[] >r15arg : (x: { a: U; b: V; }) => U[] diff --git a/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt b/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt index da742fcd69c..b1719689606 100644 --- a/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt +++ b/tests/baselines/reference/subtypingWithCallSignaturesWithSpecializedSignatures.errors.txt @@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Types of property 'a' are incompatible. Type '(x: string) => string' is not assignable to type '{ (x: "a"): number; (x: string): number; }'. Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts(76,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type '(x: T) => string' is not assignable to type '(x: T) => T'. + Type 'string' is not assignable to type 'T'. -==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts (1 errors) ==== +==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithCallSignaturesWithSpecializedSignatures.ts (2 errors) ==== // same as subtypingWithCallSignatures but with additional specialized signatures that should not affect the results module CallSignature { @@ -86,6 +90,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW // S's interface I3 extends Base2 { + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type '(x: T) => string' is not assignable to type '(x: T) => T'. +!!! error TS2430: Type 'string' is not assignable to type 'T'. // N's a2: (x: T) => string; // error because base returns non-void; } diff --git a/tests/baselines/reference/subtypingWithConstructSignatures2.types b/tests/baselines/reference/subtypingWithConstructSignatures2.types index d723a367ecb..9bf8c58edb6 100644 --- a/tests/baselines/reference/subtypingWithConstructSignatures2.types +++ b/tests/baselines/reference/subtypingWithConstructSignatures2.types @@ -320,20 +320,20 @@ var r1arg2: new (x: number) => number[]; >x : number var r1 = foo1(r1arg1); // any, return types are not subtype of first overload ->r1 : any ->foo1(r1arg1) : any +>r1 : new (x: number) => number[] +>foo1(r1arg1) : new (x: number) => number[] >foo1 : { (a: new (x: number) => number[]): new (x: number) => number[]; (a: any): any; } >r1arg1 : new (x: T) => T[] var r1a = [r1arg2, r1arg1]; // generic signature, subtype in both directions ->r1a : (new (x: T) => T[])[] ->[r1arg2, r1arg1] : (new (x: T) => T[])[] +>r1a : (new (x: number) => number[])[] +>[r1arg2, r1arg1] : (new (x: number) => number[])[] >r1arg2 : new (x: number) => number[] >r1arg1 : new (x: T) => T[] var r1b = [r1arg1, r1arg2]; // generic signature, subtype in both directions ->r1b : (new (x: T) => T[])[] ->[r1arg1, r1arg2] : (new (x: T) => T[])[] +>r1b : (new (x: number) => number[])[] +>[r1arg1, r1arg2] : (new (x: number) => number[])[] >r1arg1 : new (x: T) => T[] >r1arg2 : new (x: number) => number[] @@ -354,14 +354,14 @@ var r2 = foo2(r2arg1); >r2arg1 : new (x: T) => string[] var r2a = [r2arg1, r2arg2]; ->r2a : (new (x: T) => string[])[] ->[r2arg1, r2arg2] : (new (x: T) => string[])[] +>r2a : (new (x: number) => string[])[] +>[r2arg1, r2arg2] : (new (x: number) => string[])[] >r2arg1 : new (x: T) => string[] >r2arg2 : new (x: number) => string[] var r2b = [r2arg2, r2arg1]; ->r2b : (new (x: T) => string[])[] ->[r2arg2, r2arg1] : (new (x: T) => string[])[] +>r2b : (new (x: number) => string[])[] +>[r2arg2, r2arg1] : (new (x: number) => string[])[] >r2arg2 : new (x: number) => string[] >r2arg1 : new (x: T) => string[] @@ -383,14 +383,14 @@ var r3 = foo3(r3arg1); >r3arg1 : new (x: T) => T var r3a = [r3arg1, r3arg2]; ->r3a : (new (x: T) => T)[] ->[r3arg1, r3arg2] : (new (x: T) => T)[] +>r3a : (new (x: number) => void)[] +>[r3arg1, r3arg2] : (new (x: number) => void)[] >r3arg1 : new (x: T) => T >r3arg2 : new (x: number) => void var r3b = [r3arg2, r3arg1]; ->r3b : (new (x: T) => T)[] ->[r3arg2, r3arg1] : (new (x: T) => T)[] +>r3b : (new (x: number) => void)[] +>[r3arg2, r3arg1] : (new (x: number) => void)[] >r3arg2 : new (x: number) => void >r3arg1 : new (x: T) => T @@ -410,20 +410,20 @@ var r4arg2: new (x: string, y: number) => string; >y : number var r4 = foo4(r4arg1); // any ->r4 : any ->foo4(r4arg1) : any +>r4 : new (x: string, y: number) => string +>foo4(r4arg1) : new (x: string, y: number) => string >foo4 : { (a: new (x: string, y: number) => string): new (x: string, y: number) => string; (a: any): any; } >r4arg1 : new (x: T, y: U) => T var r4a = [r4arg1, r4arg2]; ->r4a : (new (x: T, y: U) => T)[] ->[r4arg1, r4arg2] : (new (x: T, y: U) => T)[] +>r4a : (new (x: string, y: number) => string)[] +>[r4arg1, r4arg2] : (new (x: string, y: number) => string)[] >r4arg1 : new (x: T, y: U) => T >r4arg2 : new (x: string, y: number) => string var r4b = [r4arg2, r4arg1]; ->r4b : (new (x: T, y: U) => T)[] ->[r4arg2, r4arg1] : (new (x: T, y: U) => T)[] +>r4b : (new (x: string, y: number) => string)[] +>[r4arg2, r4arg1] : (new (x: string, y: number) => string)[] >r4arg2 : new (x: string, y: number) => string >r4arg1 : new (x: T, y: U) => T @@ -443,20 +443,20 @@ var r5arg2: new (x: new (arg: string) => number) => string; >arg : string var r5 = foo5(r5arg1); // any ->r5 : any ->foo5(r5arg1) : any +>r5 : new (x: new (arg: string) => number) => string +>foo5(r5arg1) : new (x: new (arg: string) => number) => string >foo5 : { (a: new (x: new (arg: string) => number) => string): new (x: new (arg: string) => number) => string; (a: any): any; } >r5arg1 : new (x: new (arg: T) => U) => T var r5a = [r5arg1, r5arg2]; ->r5a : (new (x: new (arg: T) => U) => T)[] ->[r5arg1, r5arg2] : (new (x: new (arg: T) => U) => T)[] +>r5a : (new (x: new (arg: string) => number) => string)[] +>[r5arg1, r5arg2] : (new (x: new (arg: string) => number) => string)[] >r5arg1 : new (x: new (arg: T) => U) => T >r5arg2 : new (x: new (arg: string) => number) => string var r5b = [r5arg2, r5arg1]; ->r5b : (new (x: new (arg: T) => U) => T)[] ->[r5arg2, r5arg1] : (new (x: new (arg: T) => U) => T)[] +>r5b : (new (x: new (arg: string) => number) => string)[] +>[r5arg2, r5arg1] : (new (x: new (arg: string) => number) => string)[] >r5arg2 : new (x: new (arg: string) => number) => string >r5arg1 : new (x: new (arg: T) => U) => T @@ -481,20 +481,20 @@ var r6arg2: new (x: new (arg: Base) => Derived) => Base; >Base : Base var r6 = foo6(r6arg1); // any ->r6 : any ->foo6(r6arg1) : any +>r6 : new (x: new (arg: Base) => Derived) => Base +>foo6(r6arg1) : new (x: new (arg: Base) => Derived) => Base >foo6 : { (a: new (x: new (arg: Base) => Derived) => Base): new (x: new (arg: Base) => Derived) => Base; (a: any): any; } >r6arg1 : new (x: new (arg: T) => U) => T var r6a = [r6arg1, r6arg2]; ->r6a : (new (x: new (arg: T) => U) => T)[] ->[r6arg1, r6arg2] : (new (x: new (arg: T) => U) => T)[] +>r6a : (new (x: new (arg: Base) => Derived) => Base)[] +>[r6arg1, r6arg2] : (new (x: new (arg: Base) => Derived) => Base)[] >r6arg1 : new (x: new (arg: T) => U) => T >r6arg2 : new (x: new (arg: Base) => Derived) => Base var r6b = [r6arg2, r6arg1]; ->r6b : (new (x: new (arg: T) => U) => T)[] ->[r6arg2, r6arg1] : (new (x: new (arg: T) => U) => T)[] +>r6b : (new (x: new (arg: Base) => Derived) => Base)[] +>[r6arg2, r6arg1] : (new (x: new (arg: Base) => Derived) => Base)[] >r6arg2 : new (x: new (arg: Base) => Derived) => Base >r6arg1 : new (x: new (arg: T) => U) => T @@ -523,20 +523,20 @@ var r7arg2: new (x: new (arg: Base) => Derived) => new (r: Base) => Derived; >Derived : Derived var r7 = foo7(r7arg1); // any ->r7 : any ->foo7(r7arg1) : any +>r7 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived +>foo7(r7arg1) : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived >foo7 : { (a: new (x: new (arg: Base) => Derived) => new (r: Base) => Derived): new (x: new (arg: Base) => Derived) => new (r: Base) => Derived; (a: any): any; } >r7arg1 : new (x: new (arg: T) => U) => new (r: T) => U var r7a = [r7arg1, r7arg2]; ->r7a : (new (x: new (arg: T) => U) => new (r: T) => U)[] ->[r7arg1, r7arg2] : (new (x: new (arg: T) => U) => new (r: T) => U)[] +>r7a : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived)[] +>[r7arg1, r7arg2] : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived)[] >r7arg1 : new (x: new (arg: T) => U) => new (r: T) => U >r7arg2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived var r7b = [r7arg2, r7arg1]; ->r7b : (new (x: new (arg: T) => U) => new (r: T) => U)[] ->[r7arg2, r7arg1] : (new (x: new (arg: T) => U) => new (r: T) => U)[] +>r7b : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived)[] +>[r7arg2, r7arg1] : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived)[] >r7arg2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived >r7arg1 : new (x: new (arg: T) => U) => new (r: T) => U @@ -573,20 +573,20 @@ var r8arg2: new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) >Derived : Derived var r8 = foo8(r8arg1); // any ->r8 : any ->foo8(r8arg1) : any +>r8 : new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived +>foo8(r8arg1) : new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived >foo8 : { (a: new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived): new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived; (a: any): any; } >r8arg1 : new (x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U var r8a = [r8arg1, r8arg2]; ->r8a : (new (x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U)[] ->[r8arg1, r8arg2] : (new (x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U)[] +>r8a : (new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived)[] +>[r8arg1, r8arg2] : (new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived)[] >r8arg1 : new (x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U >r8arg2 : new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived var r8b = [r8arg2, r8arg1]; ->r8b : (new (x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U)[] ->[r8arg2, r8arg1] : (new (x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U)[] +>r8b : (new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived)[] +>[r8arg2, r8arg1] : (new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived)[] >r8arg2 : new (x: new (arg: Base) => Derived, y: new (arg2: Base) => Derived) => new (r: Base) => Derived >r8arg1 : new (x: new (arg: T) => U, y: new (arg2: T) => U) => new (r: T) => U @@ -656,20 +656,20 @@ var r10arg2: new (...x: Derived[]) => Derived; >Derived : Derived var r10 = foo10(r10arg1); // any ->r10 : any ->foo10(r10arg1) : any +>r10 : new (...x: Derived[]) => Derived +>foo10(r10arg1) : new (...x: Derived[]) => Derived >foo10 : { (a: new (...x: Derived[]) => Derived): new (...x: Derived[]) => Derived; (a: any): any; } >r10arg1 : new (...x: T[]) => T var r10a = [r10arg1, r10arg2]; ->r10a : (new (...x: T[]) => T)[] ->[r10arg1, r10arg2] : (new (...x: T[]) => T)[] +>r10a : (new (...x: Derived[]) => Derived)[] +>[r10arg1, r10arg2] : (new (...x: Derived[]) => Derived)[] >r10arg1 : new (...x: T[]) => T >r10arg2 : new (...x: Derived[]) => Derived var r10b = [r10arg2, r10arg1]; ->r10b : (new (...x: T[]) => T)[] ->[r10arg2, r10arg1] : (new (...x: T[]) => T)[] +>r10b : (new (...x: Derived[]) => Derived)[] +>[r10arg2, r10arg1] : (new (...x: Derived[]) => Derived)[] >r10arg2 : new (...x: Derived[]) => Derived >r10arg1 : new (...x: T[]) => T @@ -693,20 +693,20 @@ var r11arg2: new (x: { foo: string }, y: { foo: string; bar: string }) => Base; >Base : Base var r11 = foo11(r11arg1); // any ->r11 : any ->foo11(r11arg1) : any +>r11 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base +>foo11(r11arg1) : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >foo11 : { (a: new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base): new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base; (a: any): any; } >r11arg1 : new (x: T, y: T) => T var r11a = [r11arg1, r11arg2]; ->r11a : (new (x: T, y: T) => T)[] ->[r11arg1, r11arg2] : (new (x: T, y: T) => T)[] +>r11a : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] +>[r11arg1, r11arg2] : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] >r11arg1 : new (x: T, y: T) => T >r11arg2 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base var r11b = [r11arg2, r11arg1]; ->r11b : (new (x: T, y: T) => T)[] ->[r11arg2, r11arg1] : (new (x: T, y: T) => T)[] +>r11b : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] +>[r11arg2, r11arg1] : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] >r11arg2 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >r11arg1 : new (x: T, y: T) => T @@ -741,14 +741,14 @@ var r12 = foo12(r12arg1); // any >r12arg1 : new (x: Base[], y: T) => Derived[] var r12a = [r12arg1, r12arg2]; ->r12a : (new (x: Base[], y: T) => Derived[])[] ->[r12arg1, r12arg2] : (new (x: Base[], y: T) => Derived[])[] +>r12a : (new (x: Base[], y: Derived2[]) => Derived[])[] +>[r12arg1, r12arg2] : (new (x: Base[], y: Derived2[]) => Derived[])[] >r12arg1 : new (x: Base[], y: T) => Derived[] >r12arg2 : new (x: Base[], y: Derived2[]) => Derived[] var r12b = [r12arg2, r12arg1]; ->r12b : (new (x: Base[], y: T) => Derived[])[] ->[r12arg2, r12arg1] : (new (x: Base[], y: T) => Derived[])[] +>r12b : (new (x: Base[], y: Derived2[]) => Derived[])[] +>[r12arg2, r12arg1] : (new (x: Base[], y: Derived2[]) => Derived[])[] >r12arg2 : new (x: Base[], y: Derived2[]) => Derived[] >r12arg1 : new (x: Base[], y: T) => Derived[] @@ -776,20 +776,20 @@ var r13arg2: new (x: Array, y: Array) => Array; >Derived : Derived var r13 = foo13(r13arg1); // any ->r13 : any ->foo13(r13arg1) : any +>r13 : new (x: Base[], y: Derived[]) => Derived[] +>foo13(r13arg1) : new (x: Base[], y: Derived[]) => Derived[] >foo13 : { (a: new (x: Base[], y: Derived[]) => Derived[]): new (x: Base[], y: Derived[]) => Derived[]; (a: any): any; } >r13arg1 : new (x: Base[], y: T) => T var r13a = [r13arg1, r13arg2]; ->r13a : (new (x: Base[], y: T) => T)[] ->[r13arg1, r13arg2] : (new (x: Base[], y: T) => T)[] +>r13a : (new (x: Base[], y: Derived[]) => Derived[])[] +>[r13arg1, r13arg2] : (new (x: Base[], y: Derived[]) => Derived[])[] >r13arg1 : new (x: Base[], y: T) => T >r13arg2 : new (x: Base[], y: Derived[]) => Derived[] var r13b = [r13arg2, r13arg1]; ->r13b : (new (x: Base[], y: T) => T)[] ->[r13arg2, r13arg1] : (new (x: Base[], y: T) => T)[] +>r13b : (new (x: Base[], y: Derived[]) => Derived[])[] +>[r13arg2, r13arg1] : (new (x: Base[], y: Derived[]) => Derived[])[] >r13arg2 : new (x: Base[], y: Derived[]) => Derived[] >r13arg1 : new (x: Base[], y: T) => T @@ -811,20 +811,20 @@ var r14arg2: new (x: { a: string; b: number }) => Object; >Object : Object var r14 = foo14(r14arg1); // any ->r14 : any ->foo14(r14arg1) : any +>r14 : new (x: { a: string; b: number; }) => Object +>foo14(r14arg1) : new (x: { a: string; b: number; }) => Object >foo14 : { (a: new (x: { a: string; b: number; }) => Object): new (x: { a: string; b: number; }) => Object; (a: any): any; } >r14arg1 : new (x: { a: T; b: T; }) => T var r14a = [r14arg1, r14arg2]; ->r14a : (new (x: { a: T; b: T; }) => T)[] ->[r14arg1, r14arg2] : (new (x: { a: T; b: T; }) => T)[] +>r14a : (new (x: { a: string; b: number; }) => Object)[] +>[r14arg1, r14arg2] : (new (x: { a: string; b: number; }) => Object)[] >r14arg1 : new (x: { a: T; b: T; }) => T >r14arg2 : new (x: { a: string; b: number; }) => Object var r14b = [r14arg2, r14arg1]; ->r14b : (new (x: { a: T; b: T; }) => T)[] ->[r14arg2, r14arg1] : (new (x: { a: T; b: T; }) => T)[] +>r14b : (new (x: { a: string; b: number; }) => Object)[] +>[r14arg2, r14arg1] : (new (x: { a: string; b: number; }) => Object)[] >r14arg2 : new (x: { a: string; b: number; }) => Object >r14arg1 : new (x: { a: T; b: T; }) => T diff --git a/tests/baselines/reference/subtypingWithConstructSignatures3.types b/tests/baselines/reference/subtypingWithConstructSignatures3.types index b0f0680c7a0..c5cd2569763 100644 --- a/tests/baselines/reference/subtypingWithConstructSignatures3.types +++ b/tests/baselines/reference/subtypingWithConstructSignatures3.types @@ -218,20 +218,20 @@ module Errors { >x : number var r1 = foo2(r1arg1); // any ->r1 : any ->foo2(r1arg1) : any +>r1 : new (x: number) => string[] +>foo2(r1arg1) : new (x: number) => string[] >foo2 : { (a2: new (x: number) => string[]): new (x: number) => string[]; (a2: any): any; } >r1arg1 : new (x: T) => U[] var r1a = [r1arg2, r1arg1]; ->r1a : (new (x: T) => U[])[] ->[r1arg2, r1arg1] : (new (x: T) => U[])[] +>r1a : (new (x: number) => string[])[] +>[r1arg2, r1arg1] : (new (x: number) => string[])[] >r1arg2 : new (x: number) => string[] >r1arg1 : new (x: T) => U[] var r1b = [r1arg1, r1arg2]; ->r1b : (new (x: T) => U[])[] ->[r1arg1, r1arg2] : (new (x: T) => U[])[] +>r1b : (new (x: number) => string[])[] +>[r1arg1, r1arg2] : (new (x: number) => string[])[] >r1arg1 : new (x: T) => U[] >r1arg2 : new (x: number) => string[] @@ -262,20 +262,20 @@ module Errors { >Derived2 : Derived2 var r2 = foo7(r2arg1); // any ->r2 : any ->foo7(r2arg1) : any +>r2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2 +>foo7(r2arg1) : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2 >foo7 : { (a2: new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2): new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2; (a2: any): any; } >r2arg1 : new (x: new (arg: T) => U) => new (r: T) => V var r2a = [r2arg2, r2arg1]; ->r2a : (new (x: new (arg: T) => U) => new (r: T) => V)[] ->[r2arg2, r2arg1] : (new (x: new (arg: T) => U) => new (r: T) => V)[] +>r2a : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2)[] +>[r2arg2, r2arg1] : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2)[] >r2arg2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2 >r2arg1 : new (x: new (arg: T) => U) => new (r: T) => V var r2b = [r2arg1, r2arg2]; ->r2b : (new (x: new (arg: T) => U) => new (r: T) => V)[] ->[r2arg1, r2arg2] : (new (x: new (arg: T) => U) => new (r: T) => V)[] +>r2b : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2)[] +>[r2arg1, r2arg2] : (new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2)[] >r2arg1 : new (x: new (arg: T) => U) => new (r: T) => V >r2arg2 : new (x: new (arg: Base) => Derived) => new (r: Base) => Derived2 @@ -344,20 +344,20 @@ module Errors { >Base : Base var r4 = foo10(r4arg1); // any ->r4 : any ->foo10(r4arg1) : any +>r4 : new (...x: Base[]) => Base +>foo10(r4arg1) : new (...x: Base[]) => Base >foo10 : { (a2: new (...x: Base[]) => Base): new (...x: Base[]) => Base; (a2: any): any; } >r4arg1 : new (...x: T[]) => T var r4a = [r4arg2, r4arg1]; ->r4a : (new (...x: T[]) => T)[] ->[r4arg2, r4arg1] : (new (...x: T[]) => T)[] +>r4a : (new (...x: Base[]) => Base)[] +>[r4arg2, r4arg1] : (new (...x: Base[]) => Base)[] >r4arg2 : new (...x: Base[]) => Base >r4arg1 : new (...x: T[]) => T var r4b = [r4arg1, r4arg2]; ->r4b : (new (...x: T[]) => T)[] ->[r4arg1, r4arg2] : (new (...x: T[]) => T)[] +>r4b : (new (...x: Base[]) => Base)[] +>[r4arg1, r4arg2] : (new (...x: Base[]) => Base)[] >r4arg1 : new (...x: T[]) => T >r4arg2 : new (...x: Base[]) => Base @@ -381,20 +381,20 @@ module Errors { >Base : Base var r5 = foo11(r5arg1); // any ->r5 : any ->foo11(r5arg1) : any +>r5 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base +>foo11(r5arg1) : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >foo11 : { (a2: new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base): new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base; (a2: any): any; } >r5arg1 : new (x: T, y: T) => T var r5a = [r5arg2, r5arg1]; ->r5a : (new (x: T, y: T) => T)[] ->[r5arg2, r5arg1] : (new (x: T, y: T) => T)[] +>r5a : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] +>[r5arg2, r5arg1] : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] >r5arg2 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >r5arg1 : new (x: T, y: T) => T var r5b = [r5arg1, r5arg2]; ->r5b : (new (x: T, y: T) => T)[] ->[r5arg1, r5arg2] : (new (x: T, y: T) => T)[] +>r5b : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] +>[r5arg1, r5arg2] : (new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base)[] >r5arg1 : new (x: T, y: T) => T >r5arg2 : new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base @@ -429,14 +429,14 @@ module Errors { >r6arg1 : new (x: Base[], y: Derived2[]) => Derived[] var r6a = [r6arg2, r6arg1]; ->r6a : (new (x: Base[], y: Base[]) => T)[] ->[r6arg2, r6arg1] : (new (x: Base[], y: Base[]) => T)[] +>r6a : (new (x: Base[], y: Derived2[]) => Derived[])[] +>[r6arg2, r6arg1] : (new (x: Base[], y: Derived2[]) => Derived[])[] >r6arg2 : new (x: Base[], y: Base[]) => T >r6arg1 : new (x: Base[], y: Derived2[]) => Derived[] var r6b = [r6arg1, r6arg2]; ->r6b : (new (x: Base[], y: Base[]) => T)[] ->[r6arg1, r6arg2] : (new (x: Base[], y: Base[]) => T)[] +>r6b : (new (x: Base[], y: Derived2[]) => Derived[])[] +>[r6arg1, r6arg2] : (new (x: Base[], y: Derived2[]) => Derived[])[] >r6arg1 : new (x: Base[], y: Derived2[]) => Derived[] >r6arg2 : new (x: Base[], y: Base[]) => T @@ -463,14 +463,14 @@ module Errors { >r7arg1 : new (x: { a: T; b: T; }) => T var r7a = [r7arg2, r7arg1]; ->r7a : (new (x: { a: T; b: T; }) => T)[] ->[r7arg2, r7arg1] : (new (x: { a: T; b: T; }) => T)[] +>r7a : ((new (x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => number))[] +>[r7arg2, r7arg1] : ((new (x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => number))[] >r7arg2 : new (x: { a: string; b: number; }) => number >r7arg1 : new (x: { a: T; b: T; }) => T var r7b = [r7arg1, r7arg2]; ->r7b : (new (x: { a: T; b: T; }) => T)[] ->[r7arg1, r7arg2] : (new (x: { a: T; b: T; }) => T)[] +>r7b : ((new (x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => number))[] +>[r7arg1, r7arg2] : ((new (x: { a: T; b: T; }) => T) | (new (x: { a: string; b: number; }) => number))[] >r7arg1 : new (x: { a: T; b: T; }) => T >r7arg2 : new (x: { a: string; b: number; }) => number @@ -485,20 +485,20 @@ module Errors { >T : T var r7c = foo15(r7arg3); // any ->r7c : new (x: { a: string; b: number; }) => number ->foo15(r7arg3) : new (x: { a: string; b: number; }) => number +>r7c : any +>foo15(r7arg3) : any >foo15 : { (a2: new (x: { a: string; b: number; }) => number): new (x: { a: string; b: number; }) => number; (a2: any): any; } >r7arg3 : new (x: { a: T; b: T; }) => number var r7d = [r7arg2, r7arg3]; ->r7d : (new (x: { a: string; b: number; }) => number)[] ->[r7arg2, r7arg3] : (new (x: { a: string; b: number; }) => number)[] +>r7d : ((new (x: { a: string; b: number; }) => number) | (new (x: { a: T; b: T; }) => number))[] +>[r7arg2, r7arg3] : ((new (x: { a: string; b: number; }) => number) | (new (x: { a: T; b: T; }) => number))[] >r7arg2 : new (x: { a: string; b: number; }) => number >r7arg3 : new (x: { a: T; b: T; }) => number var r7e = [r7arg3, r7arg2]; ->r7e : (new (x: { a: string; b: number; }) => number)[] ->[r7arg3, r7arg2] : (new (x: { a: string; b: number; }) => number)[] +>r7e : ((new (x: { a: string; b: number; }) => number) | (new (x: { a: T; b: T; }) => number))[] +>[r7arg3, r7arg2] : ((new (x: { a: string; b: number; }) => number) | (new (x: { a: T; b: T; }) => number))[] >r7arg3 : new (x: { a: T; b: T; }) => number >r7arg2 : new (x: { a: string; b: number; }) => number @@ -555,8 +555,8 @@ module WithGenericSignaturesInBaseType { >T : T var r2 = foo2(r2arg2); // (x:T) => T[] since we can infer from generic signatures now ->r2 : new (x: T) => T[] ->foo2(r2arg2) : new (x: T) => T[] +>r2 : any +>foo2(r2arg2) : any >foo2 : { (a2: new (x: T) => T[]): new (x: T) => T[]; (a2: any): any; } >r2arg2 : new (x: T) => string[] diff --git a/tests/baselines/reference/subtypingWithConstructSignatures4.types b/tests/baselines/reference/subtypingWithConstructSignatures4.types index 21a40ecf7fc..5cf612ed1d0 100644 --- a/tests/baselines/reference/subtypingWithConstructSignatures4.types +++ b/tests/baselines/reference/subtypingWithConstructSignatures4.types @@ -301,14 +301,14 @@ var r3 = foo3(r3arg); >r3arg : new (x: T) => T var r3a = [r3arg, r3arg2]; ->r3a : (new (x: T) => T)[] ->[r3arg, r3arg2] : (new (x: T) => T)[] +>r3a : (new (x: T) => void)[] +>[r3arg, r3arg2] : (new (x: T) => void)[] >r3arg : new (x: T) => T >r3arg2 : new (x: T) => void var r3b = [r3arg2, r3arg]; ->r3b : (new (x: T) => T)[] ->[r3arg2, r3arg] : (new (x: T) => T)[] +>r3b : (new (x: T) => void)[] +>[r3arg2, r3arg] : (new (x: T) => void)[] >r3arg2 : new (x: T) => void >r3arg : new (x: T) => T @@ -499,14 +499,14 @@ var r15 = foo15(r15arg); >r15arg : new (x: { a: U; b: V; }) => U[] var r15a = [r15arg, r15arg2]; ->r15a : (new (x: { a: U; b: V; }) => U[])[] ->[r15arg, r15arg2] : (new (x: { a: U; b: V; }) => U[])[] +>r15a : (new (x: { a: T; b: T; }) => T[])[] +>[r15arg, r15arg2] : (new (x: { a: T; b: T; }) => T[])[] >r15arg : new (x: { a: U; b: V; }) => U[] >r15arg2 : new (x: { a: T; b: T; }) => T[] var r15b = [r15arg2, r15arg]; ->r15b : (new (x: { a: U; b: V; }) => U[])[] ->[r15arg2, r15arg] : (new (x: { a: U; b: V; }) => U[])[] +>r15b : (new (x: { a: T; b: T; }) => T[])[] +>[r15arg2, r15arg] : (new (x: { a: T; b: T; }) => T[])[] >r15arg2 : new (x: { a: T; b: T; }) => T[] >r15arg : new (x: { a: U; b: V; }) => U[] diff --git a/tests/baselines/reference/subtypingWithConstructSignatures6.errors.txt b/tests/baselines/reference/subtypingWithConstructSignatures6.errors.txt new file mode 100644 index 00000000000..34fa5ee287a --- /dev/null +++ b/tests/baselines/reference/subtypingWithConstructSignatures6.errors.txt @@ -0,0 +1,142 @@ +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(24,11): error TS2430: Interface 'I' incorrectly extends interface 'A'. + Types of property 'a' are incompatible. + Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(28,11): error TS2430: Interface 'I2' incorrectly extends interface 'A'. + Types of property 'a2' are incompatible. + Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => string[]'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(32,11): error TS2430: Interface 'I3' incorrectly extends interface 'A'. + Types of property 'a3' are incompatible. + Type 'new (x: T) => T' is not assignable to type 'new (x: T) => void'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(36,11): error TS2430: Interface 'I4' incorrectly extends interface 'A'. + Types of property 'a4' are incompatible. + Type 'new (x: T, y: U) => string' is not assignable to type 'new (x: T, y: U) => string'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(40,11): error TS2430: Interface 'I5' incorrectly extends interface 'A'. + Types of property 'a5' are incompatible. + Type 'new (x: (arg: T) => U) => T' is not assignable to type 'new (x: (arg: T) => U) => T'. + Types of parameters 'x' and 'x' are incompatible. + Types of parameters 'arg' and 'arg' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(44,11): error TS2430: Interface 'I7' incorrectly extends interface 'A'. + Types of property 'a11' are incompatible. + Type 'new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated. + Types of property 'foo' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts(48,11): error TS2430: Interface 'I9' incorrectly extends interface 'A'. + Types of property 'a16' are incompatible. + Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: T; b: T; }) => T[]'. + Types of parameters 'x' and 'x' are incompatible. + Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated. + Types of property 'a' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + Type 'Base' is not assignable to type 'T'. + + +==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignatures6.ts (7 errors) ==== + // checking subtype relations for function types as it relates to contextual signature instantiation + // same as subtypingWithConstructSignatures4 but using class type parameters instead of generic signatures + // all are errors + + class Base { foo: string; } + class Derived extends Base { bar: string; } + class Derived2 extends Derived { baz: string; } + class OtherDerived extends Base { bing: string; } + + interface A { // T + // M's + a: new (x: T) => T[]; + a2: new (x: T) => string[]; + a3: new (x: T) => void; + a4: new (x: T, y: U) => string; + a5: new (x: (arg: T) => U) => T; + a6: new (x: (arg: T) => Derived) => T; + a11: new (x: { foo: T }, y: { foo: T; bar: T }) => Base; + a15: new (x: { a: T; b: T }) => T[]; + a16: new (x: { a: T; b: T }) => T[]; + } + + // S's + interface I extends A { + ~ +!!! error TS2430: Interface 'I' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'new (x: T) => T[]' is not assignable to type 'new (x: T) => T[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a: new (x: T) => T[]; + } + + interface I2 extends A { + ~~ +!!! error TS2430: Interface 'I2' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new (x: T) => string[]' is not assignable to type 'new (x: T) => string[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a2: new (x: T) => string[]; + } + + interface I3 extends A { + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type 'new (x: T) => T' is not assignable to type 'new (x: T) => void'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a3: new (x: T) => T; + } + + interface I4 extends A { + ~~ +!!! error TS2430: Interface 'I4' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type 'new (x: T, y: U) => string' is not assignable to type 'new (x: T, y: U) => string'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a4: new (x: T, y: U) => string; + } + + interface I5 extends A { + ~~ +!!! error TS2430: Interface 'I5' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type 'new (x: (arg: T) => U) => T' is not assignable to type 'new (x: (arg: T) => U) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Types of parameters 'arg' and 'arg' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a5: new (x: (arg: T) => U) => T; + } + + interface I7 extends A { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a11' are incompatible. +!!! error TS2430: Type 'new (x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new (x: { foo: T; }, y: { foo: T; bar: T; }) => Base'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Types of property 'foo' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. + a11: new (x: { foo: T }, y: { foo: U; bar: U }) => Base; + } + + interface I9 extends A { + ~~ +!!! error TS2430: Interface 'I9' incorrectly extends interface 'A'. +!!! error TS2430: Types of property 'a16' are incompatible. +!!! error TS2430: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new (x: { a: T; b: T; }) => T[]'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +!!! error TS2430: Type 'Base' is not assignable to type 'T'. + a16: new (x: { a: T; b: T }) => T[]; + } \ No newline at end of file diff --git a/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt b/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt index 8a885a2455f..a862124666d 100644 --- a/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt +++ b/tests/baselines/reference/subtypingWithConstructSignaturesWithSpecializedSignatures.errors.txt @@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Types of property 'a' are incompatible. Type 'new (x: string) => string' is not assignable to type '{ new (x: "a"): number; new (x: string): number; }'. Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts(76,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type 'new (x: T) => string' is not assignable to type 'new (x: T) => T'. + Type 'string' is not assignable to type 'T'. -==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts (1 errors) ==== +==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithConstructSignaturesWithSpecializedSignatures.ts (2 errors) ==== // same as subtypingWithCallSignatures but with additional specialized signatures that should not affect the results module CallSignature { @@ -86,6 +90,11 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW // S's interface I3 extends Base2 { + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new (x: T) => string' is not assignable to type 'new (x: T) => T'. +!!! error TS2430: Type 'string' is not assignable to type 'T'. // N's a2: new (x: T) => string; // error because base returns non-void; } diff --git a/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt b/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt index e8f50236cba..1447c4d3105 100644 --- a/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt +++ b/tests/baselines/reference/subtypingWithGenericCallSignaturesWithOptionalParameters.errors.txt @@ -4,12 +4,86 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(50,15): error TS2430: Interface 'I10' incorrectly extends interface 'Base'. Types of property 'a3' are incompatible. Type '(x: T, y: T) => T' is not assignable to type '(x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(100,15): error TS2430: Interface 'I1' incorrectly extends interface 'Base2'. + Types of property 'a' are incompatible. + Type '() => T' is not assignable to type '() => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(104,15): error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. + Types of property 'a' are incompatible. + Type '(x?: T) => T' is not assignable to type '() => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(108,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. Types of property 'a' are incompatible. Type '(x: T) => T' is not assignable to type '() => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(113,15): error TS2430: Interface 'I4' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type '() => T' is not assignable to type '(x?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(117,15): error TS2430: Interface 'I5' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type '(x?: T) => T' is not assignable to type '(x?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(121,15): error TS2430: Interface 'I6' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type '(x: T) => T' is not assignable to type '(x?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(126,15): error TS2430: Interface 'I7' incorrectly extends interface 'Base2'. + Types of property 'a3' are incompatible. + Type '() => T' is not assignable to type '(x: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(130,15): error TS2430: Interface 'I8' incorrectly extends interface 'Base2'. + Types of property 'a3' are incompatible. + Type '(x?: T) => T' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(134,15): error TS2430: Interface 'I9' incorrectly extends interface 'Base2'. + Types of property 'a3' are incompatible. + Type '(x: T) => T' is not assignable to type '(x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(138,15): error TS2430: Interface 'I10' incorrectly extends interface 'Base2'. Types of property 'a3' are incompatible. Type '(x: T, y: T) => T' is not assignable to type '(x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(143,15): error TS2430: Interface 'I11' incorrectly extends interface 'Base2'. + Types of property 'a4' are incompatible. + Type '() => T' is not assignable to type '(x: T, y?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(147,15): error TS2430: Interface 'I12' incorrectly extends interface 'Base2'. + Types of property 'a4' are incompatible. + Type '(x?: T, y?: T) => T' is not assignable to type '(x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(151,15): error TS2430: Interface 'I13' incorrectly extends interface 'Base2'. + Types of property 'a4' are incompatible. + Type '(x: T) => T' is not assignable to type '(x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(155,15): error TS2430: Interface 'I14' incorrectly extends interface 'Base2'. + Types of property 'a4' are incompatible. + Type '(x: T, y: T) => T' is not assignable to type '(x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(160,15): error TS2430: Interface 'I15' incorrectly extends interface 'Base2'. + Types of property 'a5' are incompatible. + Type '() => T' is not assignable to type '(x?: T, y?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(164,15): error TS2430: Interface 'I16' incorrectly extends interface 'Base2'. + Types of property 'a5' are incompatible. + Type '(x?: T, y?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(168,15): error TS2430: Interface 'I17' incorrectly extends interface 'Base2'. + Types of property 'a5' are incompatible. + Type '(x: T) => T' is not assignable to type '(x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(172,15): error TS2430: Interface 'I18' incorrectly extends interface 'Base2'. + Types of property 'a5' are incompatible. + Type '(x: T, y: T) => T' is not assignable to type '(x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts(196,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. Types of property 'a' are incompatible. Type '(x: T) => T' is not assignable to type '() => T'. @@ -18,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Type '(x: T, y: T) => T' is not assignable to type '(x: T) => T'. -==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts (6 errors) ==== +==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericCallSignaturesWithOptionalParameters.ts (22 errors) ==== // call signatures in derived types must have the same or fewer optional parameters as the base type module ClassTypeParam { @@ -127,10 +201,20 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } interface I1 extends Base2 { + ~~ +!!! error TS2430: Interface 'I1' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type '() => T' is not assignable to type '() => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a: () => T; } interface I2 extends Base2 { + ~~ +!!! error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type '(x?: T) => T' is not assignable to type '() => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a: (x?: T) => T; } @@ -144,27 +228,61 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I4 extends Base2 { + ~~ +!!! error TS2430: Interface 'I4' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type '() => T' is not assignable to type '(x?: T) => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a2: () => T; } interface I5 extends Base2 { + ~~ +!!! error TS2430: Interface 'I5' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type '(x?: T) => T' is not assignable to type '(x?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a2: (x?: T) => T } interface I6 extends Base2 { + ~~ +!!! error TS2430: Interface 'I6' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type '(x: T) => T' is not assignable to type '(x?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a2: (x: T) => T; } interface I7 extends Base2 { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type '() => T' is not assignable to type '(x: T) => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a3: () => T; } interface I8 extends Base2 { + ~~ +!!! error TS2430: Interface 'I8' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type '(x?: T) => T' is not assignable to type '(x: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a3: (x?: T) => T; } interface I9 extends Base2 { + ~~ +!!! error TS2430: Interface 'I9' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type '(x: T) => T' is not assignable to type '(x: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a3: (x: T) => T; } @@ -178,35 +296,81 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I11 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I11' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type '() => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a4: () => T; } interface I12 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I12' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type '(x?: T, y?: T) => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a4: (x?: T, y?: T) => T; } interface I13 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I13' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type '(x: T) => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a4: (x: T) => T; } interface I14 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I14' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type '(x: T, y: T) => T' is not assignable to type '(x: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a4: (x: T, y: T) => T; } interface I15 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I15' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type '() => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a5: () => T; } interface I16 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I16' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type '(x?: T, y?: T) => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a5: (x?: T, y?: T) => T; } interface I17 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I17' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type '(x: T) => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a5: (x: T) => T; } interface I18 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I18' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type '(x: T, y: T) => T' is not assignable to type '(x?: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a5: (x: T, y: T) => T; } } diff --git a/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt b/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt index 27066058238..28682b99a66 100644 --- a/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt +++ b/tests/baselines/reference/subtypingWithGenericConstructSignaturesWithOptionalParameters.errors.txt @@ -4,12 +4,86 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(50,15): error TS2430: Interface 'I10' incorrectly extends interface 'Base'. Types of property 'a3' are incompatible. Type 'new (x: T, y: T) => T' is not assignable to type 'new (x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(100,15): error TS2430: Interface 'I1' incorrectly extends interface 'Base2'. + Types of property 'a' are incompatible. + Type 'new () => T' is not assignable to type 'new () => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(104,15): error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. + Types of property 'a' are incompatible. + Type 'new (x?: T) => T' is not assignable to type 'new () => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(108,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. Types of property 'a' are incompatible. Type 'new (x: T) => T' is not assignable to type 'new () => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(113,15): error TS2430: Interface 'I4' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type 'new () => T' is not assignable to type 'new (x?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(117,15): error TS2430: Interface 'I5' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type 'new (x?: T) => T' is not assignable to type 'new (x?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(121,15): error TS2430: Interface 'I6' incorrectly extends interface 'Base2'. + Types of property 'a2' are incompatible. + Type 'new (x: T) => T' is not assignable to type 'new (x?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(126,15): error TS2430: Interface 'I7' incorrectly extends interface 'Base2'. + Types of property 'a3' are incompatible. + Type 'new () => T' is not assignable to type 'new (x: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(130,15): error TS2430: Interface 'I8' incorrectly extends interface 'Base2'. + Types of property 'a3' are incompatible. + Type 'new (x?: T) => T' is not assignable to type 'new (x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(134,15): error TS2430: Interface 'I9' incorrectly extends interface 'Base2'. + Types of property 'a3' are incompatible. + Type 'new (x: T) => T' is not assignable to type 'new (x: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(138,15): error TS2430: Interface 'I10' incorrectly extends interface 'Base2'. Types of property 'a3' are incompatible. Type 'new (x: T, y: T) => T' is not assignable to type 'new (x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(143,15): error TS2430: Interface 'I11' incorrectly extends interface 'Base2'. + Types of property 'a4' are incompatible. + Type 'new () => T' is not assignable to type 'new (x: T, y?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(147,15): error TS2430: Interface 'I12' incorrectly extends interface 'Base2'. + Types of property 'a4' are incompatible. + Type 'new (x?: T, y?: T) => T' is not assignable to type 'new (x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(151,15): error TS2430: Interface 'I13' incorrectly extends interface 'Base2'. + Types of property 'a4' are incompatible. + Type 'new (x: T) => T' is not assignable to type 'new (x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(155,15): error TS2430: Interface 'I14' incorrectly extends interface 'Base2'. + Types of property 'a4' are incompatible. + Type 'new (x: T, y: T) => T' is not assignable to type 'new (x: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(160,15): error TS2430: Interface 'I15' incorrectly extends interface 'Base2'. + Types of property 'a5' are incompatible. + Type 'new () => T' is not assignable to type 'new (x?: T, y?: T) => T'. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(164,15): error TS2430: Interface 'I16' incorrectly extends interface 'Base2'. + Types of property 'a5' are incompatible. + Type 'new (x?: T, y?: T) => T' is not assignable to type 'new (x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(168,15): error TS2430: Interface 'I17' incorrectly extends interface 'Base2'. + Types of property 'a5' are incompatible. + Type 'new (x: T) => T' is not assignable to type 'new (x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(172,15): error TS2430: Interface 'I18' incorrectly extends interface 'Base2'. + Types of property 'a5' are incompatible. + Type 'new (x: T, y: T) => T' is not assignable to type 'new (x?: T, y?: T) => T'. + Types of parameters 'x' and 'x' are incompatible. + Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts(196,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'. Types of property 'a' are incompatible. Type 'new (x: T) => T' is not assignable to type 'new () => T'. @@ -18,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW Type 'new (x: T, y: T) => T' is not assignable to type 'new (x: T) => T'. -==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts (6 errors) ==== +==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithGenericConstructSignaturesWithOptionalParameters.ts (22 errors) ==== // call signatures in derived types must have the same or fewer optional parameters as the base type module ClassTypeParam { @@ -127,10 +201,20 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW } interface I1 extends Base2 { + ~~ +!!! error TS2430: Interface 'I1' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'new () => T' is not assignable to type 'new () => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a: new () => T; } interface I2 extends Base2 { + ~~ +!!! error TS2430: Interface 'I2' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'new (x?: T) => T' is not assignable to type 'new () => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a: new (x?: T) => T; } @@ -144,27 +228,61 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I4 extends Base2 { + ~~ +!!! error TS2430: Interface 'I4' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new () => T' is not assignable to type 'new (x?: T) => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a2: new () => T; } interface I5 extends Base2 { + ~~ +!!! error TS2430: Interface 'I5' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new (x?: T) => T' is not assignable to type 'new (x?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a2: new (x?: T) => T } interface I6 extends Base2 { + ~~ +!!! error TS2430: Interface 'I6' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a2' are incompatible. +!!! error TS2430: Type 'new (x: T) => T' is not assignable to type 'new (x?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a2: new (x: T) => T; } interface I7 extends Base2 { + ~~ +!!! error TS2430: Interface 'I7' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type 'new () => T' is not assignable to type 'new (x: T) => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a3: new () => T; } interface I8 extends Base2 { + ~~ +!!! error TS2430: Interface 'I8' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type 'new (x?: T) => T' is not assignable to type 'new (x: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a3: new (x?: T) => T; } interface I9 extends Base2 { + ~~ +!!! error TS2430: Interface 'I9' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a3' are incompatible. +!!! error TS2430: Type 'new (x: T) => T' is not assignable to type 'new (x: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a3: new (x: T) => T; } @@ -178,35 +296,81 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface I11 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I11' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type 'new () => T' is not assignable to type 'new (x: T, y?: T) => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a4: new () => T; } interface I12 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I12' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type 'new (x?: T, y?: T) => T' is not assignable to type 'new (x: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a4: new (x?: T, y?: T) => T; } interface I13 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I13' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type 'new (x: T) => T' is not assignable to type 'new (x: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a4: new (x: T) => T; } interface I14 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I14' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a4' are incompatible. +!!! error TS2430: Type 'new (x: T, y: T) => T' is not assignable to type 'new (x: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a4: new (x: T, y: T) => T; } interface I15 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I15' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type 'new () => T' is not assignable to type 'new (x?: T, y?: T) => T'. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a5: new () => T; } interface I16 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I16' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type 'new (x?: T, y?: T) => T' is not assignable to type 'new (x?: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a5: new (x?: T, y?: T) => T; } interface I17 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I17' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type 'new (x: T) => T' is not assignable to type 'new (x?: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a5: new (x: T) => T; } interface I18 extends Base2 { + ~~~ +!!! error TS2430: Interface 'I18' incorrectly extends interface 'Base2'. +!!! error TS2430: Types of property 'a5' are incompatible. +!!! error TS2430: Type 'new (x: T, y: T) => T' is not assignable to type 'new (x?: T, y?: T) => T'. +!!! error TS2430: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated. a5: new (x: T, y: T) => T; } } diff --git a/tests/baselines/reference/symbolMergeValueAndImportedType.js b/tests/baselines/reference/symbolMergeValueAndImportedType.js new file mode 100644 index 00000000000..70da47268d5 --- /dev/null +++ b/tests/baselines/reference/symbolMergeValueAndImportedType.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/symbolMergeValueAndImportedType.ts] //// + +//// [main.ts] +import { X } from "./other"; +const X = 42; +console.log('X is ' + X); +//// [other.ts] +export type X = {}; + +//// [other.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [main.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const X = 42; +console.log('X is ' + X); diff --git a/tests/baselines/reference/symbolMergeValueAndImportedType.symbols b/tests/baselines/reference/symbolMergeValueAndImportedType.symbols new file mode 100644 index 00000000000..7e1422faa46 --- /dev/null +++ b/tests/baselines/reference/symbolMergeValueAndImportedType.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/main.ts === +import { X } from "./other"; +>X : Symbol(X, Decl(main.ts, 0, 8), Decl(main.ts, 1, 5)) + +const X = 42; +>X : Symbol(X, Decl(main.ts, 0, 8), Decl(main.ts, 1, 5)) + +console.log('X is ' + X); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>X : Symbol(X, Decl(main.ts, 0, 8), Decl(main.ts, 1, 5)) + +=== tests/cases/compiler/other.ts === +export type X = {}; +>X : Symbol(X, Decl(other.ts, 0, 0)) + diff --git a/tests/baselines/reference/symbolMergeValueAndImportedType.types b/tests/baselines/reference/symbolMergeValueAndImportedType.types new file mode 100644 index 00000000000..a7dc72ab0b6 --- /dev/null +++ b/tests/baselines/reference/symbolMergeValueAndImportedType.types @@ -0,0 +1,21 @@ +=== tests/cases/compiler/main.ts === +import { X } from "./other"; +>X : 42 + +const X = 42; +>X : 42 +>42 : 42 + +console.log('X is ' + X); +>console.log('X is ' + X) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>'X is ' + X : string +>'X is ' : "X is " +>X : 42 + +=== tests/cases/compiler/other.ts === +export type X = {}; +>X : X + diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt index 4eae70010ce..16ad3358038 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt @@ -1,8 +1,6 @@ -tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts(62,11): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. -tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts(75,79): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; z: Date; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. - Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. +tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts(62,36): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. +tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts(75,79): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'. + Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. ==== tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference.ts (2 errors) ==== @@ -68,9 +66,8 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference return null; } var a9a = someGenerics9 `${ '' }${ 0 }${ [] }`; - ~~~~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type '""'. var a9a: {}; // Generic tag with multiple parameters of generic type passed arguments with multiple best common types @@ -85,9 +82,8 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference var a9e = someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }`; ~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; z: Date; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. -!!! error TS2453: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. +!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'. +!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. var a9e: {}; // Generic tag with multiple parameters of generic type passed arguments with a single best common type diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt index 6a5897bedc7..0d43f3d39b2 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt @@ -1,8 +1,6 @@ -tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts(62,11): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. -tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts(75,79): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; z: Date; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. - Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. +tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts(62,36): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. +tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts(75,79): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'. + Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. ==== tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInferenceES6.ts (2 errors) ==== @@ -68,9 +66,8 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference return null; } var a9a = someGenerics9 `${ '' }${ 0 }${ [] }`; - ~~~~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type '""'. var a9a: {}; // Generic tag with multiple parameters of generic type passed arguments with multiple best common types @@ -85,9 +82,8 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsTypeArgumentInference var a9e = someGenerics9 `${ undefined }${ { x: 6, z: new Date() } }${ { x: 6, y: '' } }`; ~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; z: Date; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. -!!! error TS2453: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. +!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'. +!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. var a9e: {}; // Generic tag with multiple parameters of generic type passed arguments with a single best common type diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution1.js b/tests/baselines/reference/tsxSpreadAttributesResolution1.js index f8c3cfbb594..7d83e9bd390 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution1.js +++ b/tests/baselines/reference/tsxSpreadAttributesResolution1.js @@ -7,11 +7,12 @@ class Poisoned extends React.Component<{}, {}> { } } -const obj: Object = {}; +const obj = {}; // OK let p = ; -let y = ; +let y = ; + //// [file.jsx] "use strict"; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols b/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols index 82a4e5cc822..9b3f535f309 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols +++ b/tests/baselines/reference/tsxSpreadAttributesResolution1.symbols @@ -17,9 +17,8 @@ class Poisoned extends React.Component<{}, {}> { } } -const obj: Object = {}; +const obj = {}; >obj : Symbol(obj, Decl(file.tsx, 8, 5)) ->Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) // OK let p = ; diff --git a/tests/baselines/reference/tsxSpreadAttributesResolution1.types b/tests/baselines/reference/tsxSpreadAttributesResolution1.types index f8f1cb8d15a..26f83c74001 100644 --- a/tests/baselines/reference/tsxSpreadAttributesResolution1.types +++ b/tests/baselines/reference/tsxSpreadAttributesResolution1.types @@ -18,9 +18,8 @@ class Poisoned extends React.Component<{}, {}> { } } -const obj: Object = {}; ->obj : Object ->Object : Object +const obj = {}; +>obj : {} >{} : {} // OK @@ -28,7 +27,7 @@ let p = ; >p : JSX.Element > : JSX.Element >Poisoned : typeof Poisoned ->obj : Object +>obj : {} let y = ; >y : JSX.Element diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt index 7e940116887..3e256c0e3a6 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments2.errors.txt @@ -8,13 +8,15 @@ tests/cases/conformance/jsx/file.tsx(20,19): error TS2322: Type '{ func: (a: num Type '{ func: (a: number, b: string) => void; }' is not assignable to type '{ func: (arg: number) => void; }'. Types of property 'func' are incompatible. Type '(a: number, b: string) => void' is not assignable to type '(arg: number) => void'. -tests/cases/conformance/jsx/file.tsx(31,9): error TS2605: JSX element type 'Element' is not a constructor function for JSX elements. - Property 'render' is missing in type 'Element'. -tests/cases/conformance/jsx/file.tsx(31,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. +tests/cases/conformance/jsx/file.tsx(31,30): error TS2322: Type '{ values: number[]; selectHandler: (val: string) => void; }' is not assignable to type 'IntrinsicAttributes & InferParamProp'. + Type '{ values: number[]; selectHandler: (val: string) => void; }' is not assignable to type 'InferParamProp'. + Types of property 'selectHandler' are incompatible. + Type '(val: string) => void' is not assignable to type '(selectedVal: number) => void'. + Types of parameters 'val' and 'selectedVal' are incompatible. + Type 'number' is not assignable to type 'string'. -==== tests/cases/conformance/jsx/file.tsx (5 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (4 errors) ==== import React = require('react') declare function ComponentSpecific1(l: {prop: U, "ignore-prop": string}): JSX.Element; @@ -59,10 +61,11 @@ tests/cases/conformance/jsx/file.tsx(31,10): error TS2453: The type argument for // Error let i = { }} />; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2605: JSX element type 'Element' is not a constructor function for JSX elements. -!!! error TS2605: Property 'render' is missing in type 'Element'. - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ values: number[]; selectHandler: (val: string) => void; }' is not assignable to type 'IntrinsicAttributes & InferParamProp'. +!!! error TS2322: Type '{ values: number[]; selectHandler: (val: string) => void; }' is not assignable to type 'InferParamProp'. +!!! error TS2322: Types of property 'selectHandler' are incompatible. +!!! error TS2322: Type '(val: string) => void' is not assignable to type '(selectedVal: number) => void'. +!!! error TS2322: Types of parameters 'val' and 'selectedVal' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments5.errors.txt index 57a2ae556f7..b92375797e7 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments5.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments5.errors.txt @@ -1,11 +1,7 @@ -tests/cases/conformance/jsx/file.tsx(15,14): error TS2605: JSX element type 'Element' is not a constructor function for JSX elements. - Property 'render' is missing in type 'Element'. -tests/cases/conformance/jsx/file.tsx(15,15): error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate '"hello"'. tests/cases/conformance/jsx/file.tsx(16,42): error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes & { prop: number; }'. -==== tests/cases/conformance/jsx/file.tsx (3 errors) ==== +==== tests/cases/conformance/jsx/file.tsx (1 errors) ==== import React = require('react') declare function Component(l: U): JSX.Element; @@ -21,12 +17,6 @@ tests/cases/conformance/jsx/file.tsx(16,42): error TS2339: Property 'prop1' does let a1 = ; // U is number let a2 = ; // U is number let a3 = ; // U is "hello" - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2605: JSX element type 'Element' is not a constructor function for JSX elements. -!!! error TS2605: Property 'render' is missing in type 'Element'. - ~~~~~~~~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate '"hello"'. let a4 = ; // U is "hello" ~~~~~~~~~~~~~ !!! error TS2339: Property 'prop1' does not exist on type 'IntrinsicAttributes & { prop: number; }'. diff --git a/tests/baselines/reference/typeArgInference2.errors.txt b/tests/baselines/reference/typeArgInference2.errors.txt index b7201fd1033..41fdd9b0783 100644 --- a/tests/baselines/reference/typeArgInference2.errors.txt +++ b/tests/baselines/reference/typeArgInference2.errors.txt @@ -1,6 +1,5 @@ -tests/cases/compiler/typeArgInference2.ts(12,52): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ name: string; a: number; }' is not a valid type argument because it is not a supertype of candidate '{ name: string; b: number; }'. - Object literal may only specify known properties, and 'b' does not exist in type '{ name: string; a: number; }'. +tests/cases/compiler/typeArgInference2.ts(12,52): error TS2345: Argument of type '{ name: string; b: number; }' is not assignable to parameter of type '{ name: string; a: number; }'. + Object literal may only specify known properties, and 'b' does not exist in type '{ name: string; a: number; }'. ==== tests/cases/compiler/typeArgInference2.ts (1 errors) ==== @@ -17,6 +16,5 @@ tests/cases/compiler/typeArgInference2.ts(12,52): error TS2453: The type argumen var z5 = foo({ name: "abc", a: 5 }); // { name: string; a: number } var z6 = foo({ name: "abc", a: 5 }, { name: "def", b: 5 }); // error ~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ name: string; a: number; }' is not a valid type argument because it is not a supertype of candidate '{ name: string; b: number; }'. -!!! error TS2453: Object literal may only specify known properties, and 'b' does not exist in type '{ name: string; a: number; }'. \ No newline at end of file +!!! error TS2345: Argument of type '{ name: string; b: number; }' is not assignable to parameter of type '{ name: string; a: number; }'. +!!! error TS2345: Object literal may only specify known properties, and 'b' does not exist in type '{ name: string; a: number; }'. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgInference2WithError.errors.txt b/tests/baselines/reference/typeArgInference2WithError.errors.txt index e7abedfecb7..796f49f3438 100644 --- a/tests/baselines/reference/typeArgInference2WithError.errors.txt +++ b/tests/baselines/reference/typeArgInference2WithError.errors.txt @@ -1,5 +1,4 @@ -tests/cases/compiler/typeArgInference2WithError.ts(7,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '"abc"' is not a valid type argument because it is not a supertype of candidate '5'. +tests/cases/compiler/typeArgInference2WithError.ts(7,14): error TS2345: Argument of type '"abc"' is not assignable to parameter of type 'Item'. ==== tests/cases/compiler/typeArgInference2WithError.ts (1 errors) ==== @@ -10,6 +9,5 @@ tests/cases/compiler/typeArgInference2WithError.ts(7,10): error TS2453: The type declare function foo(x?: T, y?: T): T; var z7 = foo("abc", 5); // Error - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '"abc"' is not a valid type argument because it is not a supertype of candidate '5'. \ No newline at end of file + ~~~~~ +!!! error TS2345: Argument of type '"abc"' is not assignable to parameter of type 'Item'. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInference.errors.txt b/tests/baselines/reference/typeArgumentInference.errors.txt index cc6c1d8ce96..4daa055d20a 100644 --- a/tests/baselines/reference/typeArgumentInference.errors.txt +++ b/tests/baselines/reference/typeArgumentInference.errors.txt @@ -1,8 +1,6 @@ -tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(68,11): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. -tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(82,69): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; z: Date; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. - Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. +tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(68,29): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. +tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(82,69): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'. + Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(84,74): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type 'A92'. Object literal may only specify known properties, and 'y' does not exist in type 'A92'. @@ -76,9 +74,8 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(84,74 return null; } var a9a = someGenerics9('', 0, []); - ~~~~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type '""'. var a9a: {}; var a9b = someGenerics9<{ a?: number; b?: string; }>({ a: 0 }, { b: '' }, null); var a9b: { a?: number; b?: string; }; @@ -94,9 +91,8 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInference.ts(84,74 } var a9e = someGenerics9(undefined, { x: 6, z: new Date() }, { x: 6, y: '' }); ~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; z: Date; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. -!!! error TS2453: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. +!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: Date; }'. +!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: Date; }'. var a9e: {}; var a9f = someGenerics9(undefined, { x: 6, z: new Date() }, { x: 6, y: '' }); ~~~~~ diff --git a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt index ab056d461e9..da5558afdf7 100644 --- a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt +++ b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt @@ -9,13 +9,11 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstruct tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(81,45): error TS2345: Argument of type '(n: string) => string' is not assignable to parameter of type '(b: number) => number'. Types of parameters 'n' and 'b' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(106,15): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. +tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(106,33): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(118,9): error TS2304: Cannot find name 'Window'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(120,51): error TS2304: Cannot find name 'window'. -tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(120,69): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; z: any; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. - Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'. +tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(120,69): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: any; }'. + Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(122,56): error TS2304: Cannot find name 'window'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstructSignatures.ts(122,74): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type 'A92'. Object literal may only specify known properties, and 'y' does not exist in type 'A92'. @@ -144,9 +142,8 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstruct } var someGenerics9: someGenerics9; var a9a = new someGenerics9('', 0, []); - ~~~~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type '""'. var a9a: {}; var a9b = new someGenerics9<{ a?: number; b?: string; }>({ a: 0 }, { b: '' }, null); var a9b: { a?: number; b?: string; }; @@ -166,9 +163,8 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceConstruct ~~~~~~ !!! error TS2304: Cannot find name 'window'. ~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; z: any; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. -!!! error TS2453: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'. +!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: any; }'. +!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'. var a9e: {}; var a9f = new someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' }); ~~~~~~ diff --git a/tests/baselines/reference/typeArgumentInferenceWithConstraintAsCommonRoot.errors.txt b/tests/baselines/reference/typeArgumentInferenceWithConstraintAsCommonRoot.errors.txt index 3d24175c757..3f3625fad16 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithConstraintAsCommonRoot.errors.txt +++ b/tests/baselines/reference/typeArgumentInferenceWithConstraintAsCommonRoot.errors.txt @@ -1,6 +1,5 @@ -tests/cases/compiler/typeArgumentInferenceWithConstraintAsCommonRoot.ts(7,1): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'Giraffe' is not a valid type argument because it is not a supertype of candidate 'Elephant'. - Property 'y' is missing in type 'Elephant'. +tests/cases/compiler/typeArgumentInferenceWithConstraintAsCommonRoot.ts(7,6): error TS2345: Argument of type 'Elephant' is not assignable to parameter of type 'Giraffe'. + Property 'y' is missing in type 'Elephant'. ==== tests/cases/compiler/typeArgumentInferenceWithConstraintAsCommonRoot.ts (1 errors) ==== @@ -11,7 +10,6 @@ tests/cases/compiler/typeArgumentInferenceWithConstraintAsCommonRoot.ts(7,1): er var g: Giraffe; var e: Elephant; f(g, e); // valid because both Giraffe and Elephant satisfy the constraint. T is Animal - ~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'Giraffe' is not a valid type argument because it is not a supertype of candidate 'Elephant'. -!!! error TS2453: Property 'y' is missing in type 'Elephant'. \ No newline at end of file + ~ +!!! error TS2345: Argument of type 'Elephant' is not assignable to parameter of type 'Giraffe'. +!!! error TS2345: Property 'y' is missing in type 'Elephant'. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt b/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt index 090f8c9b852..6cc81171bcc 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt +++ b/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt @@ -14,13 +14,11 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConst Types of parameters 'n' and 'b' are incompatible. Type 'number' is not assignable to type 'string'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(66,31): error TS2345: Argument of type '(a: (a: A) => A, b: (b: B) => B, c: (c: C) => C) => void' is not assignable to parameter of type 'string'. -tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(73,11): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. +tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(73,29): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(85,9): error TS2304: Cannot find name 'Window'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(87,47): error TS2304: Cannot find name 'window'. -tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(87,65): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '{ x: number; z: any; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. - Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'. +tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(87,65): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: any; }'. + Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(89,52): error TS2304: Cannot find name 'window'. tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConstraints.ts(89,70): error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type 'A92'. Object literal may only specify known properties, and 'y' does not exist in type 'A92'. @@ -126,9 +124,8 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConst return null; } var a9a = someGenerics9('', 0, []); - ~~~~~~~~~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '0'. + ~ +!!! error TS2345: Argument of type '0' is not assignable to parameter of type '""'. var a9a: {}; var a9b = someGenerics9<{ a?: number; b?: string; }>({ a: 0 }, { b: '' }, null); var a9b: { a?: number; b?: string; }; @@ -148,9 +145,8 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithConst ~~~~~~ !!! error TS2304: Cannot find name 'window'. ~~~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '{ x: number; z: any; }' is not a valid type argument because it is not a supertype of candidate '{ x: number; y: string; }'. -!!! error TS2453: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'. +!!! error TS2345: Argument of type '{ x: number; y: string; }' is not assignable to parameter of type '{ x: number; z: any; }'. +!!! error TS2345: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; z: any; }'. var a9e: {}; var a9f = someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' }); ~~~~~~ diff --git a/tests/baselines/reference/typeArgumentInferenceWithObjectLiteral.errors.txt b/tests/baselines/reference/typeArgumentInferenceWithObjectLiteral.errors.txt index c1352bedb9b..ff718b4c364 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithObjectLiteral.errors.txt +++ b/tests/baselines/reference/typeArgumentInferenceWithObjectLiteral.errors.txt @@ -1,5 +1,4 @@ -tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjectLiteral.ts(35,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'E1' is not a valid type argument because it is not a supertype of candidate 'E2'. +tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjectLiteral.ts(35,43): error TS2345: Argument of type 'E2' is not assignable to parameter of type 'E1'. ==== tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjectLiteral.ts (1 errors) ==== @@ -38,7 +37,6 @@ tests/cases/conformance/expressions/functionCalls/typeArgumentInferenceWithObjec var v2 = f1({ w: x => x, r: () => E1.X }, E1.X); var v3 = f1({ w: x => x, r: () => E1.X }, E2.X); // Error - ~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'E1' is not a valid type argument because it is not a supertype of candidate 'E2'. + ~~~~ +!!! error TS2345: Argument of type 'E2' is not assignable to parameter of type 'E1'. \ No newline at end of file diff --git a/tests/baselines/reference/typeFromParamTagForFunction.symbols b/tests/baselines/reference/typeFromParamTagForFunction.symbols new file mode 100644 index 00000000000..0df0dfdc206 --- /dev/null +++ b/tests/baselines/reference/typeFromParamTagForFunction.symbols @@ -0,0 +1,184 @@ +=== tests/cases/conformance/salsa/node.d.ts === +declare function require(id: string): any; +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>id : Symbol(id, Decl(node.d.ts, 0, 25)) + +declare var module: any, exports: any; +>module : Symbol(module, Decl(node.d.ts, 1, 11)) +>exports : Symbol(exports, Decl(node.d.ts, 1, 24)) + +=== tests/cases/conformance/salsa/a-ext.js === +exports.A = function () { +>exports : Symbol(A, Decl(a-ext.js, 0, 0)) +>A : Symbol(A, Decl(a-ext.js, 0, 0)) + + this.x = 1; +>x : Symbol((Anonymous function).x, Decl(a-ext.js, 0, 25)) + +}; + +=== tests/cases/conformance/salsa/a.js === +const { A } = require("./a-ext"); +>A : Symbol(A, Decl(a.js, 0, 7)) +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>"./a-ext" : Symbol("tests/cases/conformance/salsa/a-ext", Decl(a-ext.js, 0, 0)) + +/** @param {A} p */ +function a(p) { p.x; } +>a : Symbol(a, Decl(a.js, 0, 33)) +>p : Symbol(p, Decl(a.js, 3, 11)) +>p.x : Symbol((Anonymous function).x, Decl(a-ext.js, 0, 25)) +>p : Symbol(p, Decl(a.js, 3, 11)) +>x : Symbol((Anonymous function).x, Decl(a-ext.js, 0, 25)) + +=== tests/cases/conformance/salsa/b-ext.js === +exports.B = class { +>exports : Symbol(B, Decl(b-ext.js, 0, 0)) +>B : Symbol(B, Decl(b-ext.js, 0, 0)) + + constructor() { + this.x = 1; +>this.x : Symbol((Anonymous class).x, Decl(b-ext.js, 1, 19)) +>this : Symbol((Anonymous class), Decl(b-ext.js, 0, 11)) +>x : Symbol((Anonymous class).x, Decl(b-ext.js, 1, 19)) + } +}; + +=== tests/cases/conformance/salsa/b.js === +const { B } = require("./b-ext"); +>B : Symbol(B, Decl(b.js, 0, 7)) +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>"./b-ext" : Symbol("tests/cases/conformance/salsa/b-ext", Decl(b-ext.js, 0, 0)) + +/** @param {B} p */ +function b(p) { p.x; } +>b : Symbol(b, Decl(b.js, 0, 33)) +>p : Symbol(p, Decl(b.js, 3, 11)) +>p.x : Symbol((Anonymous class).x, Decl(b-ext.js, 1, 19)) +>p : Symbol(p, Decl(b.js, 3, 11)) +>x : Symbol((Anonymous class).x, Decl(b-ext.js, 1, 19)) + +=== tests/cases/conformance/salsa/c-ext.js === +export function C() { +>C : Symbol(C, Decl(c-ext.js, 0, 0)) + + this.x = 1; +>x : Symbol(C.x, Decl(c-ext.js, 0, 21)) +} + +=== tests/cases/conformance/salsa/c.js === +const { C } = require("./c-ext"); +>C : Symbol(C, Decl(c.js, 0, 7)) +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>"./c-ext" : Symbol("tests/cases/conformance/salsa/c-ext", Decl(c-ext.js, 0, 0)) + +/** @param {C} p */ +function c(p) { p.x; } +>c : Symbol(c, Decl(c.js, 0, 33)) +>p : Symbol(p, Decl(c.js, 3, 11)) +>p.x : Symbol(C.x, Decl(c-ext.js, 0, 21)) +>p : Symbol(p, Decl(c.js, 3, 11)) +>x : Symbol(C.x, Decl(c-ext.js, 0, 21)) + +=== tests/cases/conformance/salsa/d-ext.js === +export var D = function() { +>D : Symbol(D, Decl(d-ext.js, 0, 10)) + + this.x = 1; +>x : Symbol(D.x, Decl(d-ext.js, 0, 27)) + +}; + +=== tests/cases/conformance/salsa/d.js === +const { D } = require("./d-ext"); +>D : Symbol(D, Decl(d.js, 0, 7)) +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>"./d-ext" : Symbol("tests/cases/conformance/salsa/d-ext", Decl(d-ext.js, 0, 0)) + +/** @param {D} p */ +function d(p) { p.x; } +>d : Symbol(d, Decl(d.js, 0, 33)) +>p : Symbol(p, Decl(d.js, 3, 11)) +>p.x : Symbol(D.x, Decl(d-ext.js, 0, 27)) +>p : Symbol(p, Decl(d.js, 3, 11)) +>x : Symbol(D.x, Decl(d-ext.js, 0, 27)) + +=== tests/cases/conformance/salsa/e-ext.js === +export class E { +>E : Symbol(E, Decl(e-ext.js, 0, 0)) + + constructor() { + this.x = 1; +>this.x : Symbol(E.x, Decl(e-ext.js, 1, 19)) +>this : Symbol(E, Decl(e-ext.js, 0, 0)) +>x : Symbol(E.x, Decl(e-ext.js, 1, 19)) + } +} + +=== tests/cases/conformance/salsa/e.js === +const { E } = require("./e-ext"); +>E : Symbol(E, Decl(e.js, 0, 7)) +>require : Symbol(require, Decl(node.d.ts, 0, 0)) +>"./e-ext" : Symbol("tests/cases/conformance/salsa/e-ext", Decl(e-ext.js, 0, 0)) + +/** @param {E} p */ +function e(p) { p.x; } +>e : Symbol(e, Decl(e.js, 0, 33)) +>p : Symbol(p, Decl(e.js, 3, 11)) +>p.x : Symbol(E.x, Decl(e-ext.js, 1, 19)) +>p : Symbol(p, Decl(e.js, 3, 11)) +>x : Symbol(E.x, Decl(e-ext.js, 1, 19)) + +=== tests/cases/conformance/salsa/f.js === +var F = function () { +>F : Symbol(F, Decl(f.js, 0, 3)) + + this.x = 1; +>x : Symbol(F.x, Decl(f.js, 0, 21)) + +}; + +/** @param {F} p */ +function f(p) { p.x; } +>f : Symbol(f, Decl(f.js, 2, 2)) +>p : Symbol(p, Decl(f.js, 5, 11)) +>p.x : Symbol(F.x, Decl(f.js, 0, 21)) +>p : Symbol(p, Decl(f.js, 5, 11)) +>x : Symbol(F.x, Decl(f.js, 0, 21)) + +=== tests/cases/conformance/salsa/g.js === +function G() { +>G : Symbol(G, Decl(g.js, 0, 0)) + + this.x = 1; +>x : Symbol(G.x, Decl(g.js, 0, 14)) +} + +/** @param {G} p */ +function g(p) { p.x; } +>g : Symbol(g, Decl(g.js, 2, 1)) +>p : Symbol(p, Decl(g.js, 5, 11)) +>p.x : Symbol(G.x, Decl(g.js, 0, 14)) +>p : Symbol(p, Decl(g.js, 5, 11)) +>x : Symbol(G.x, Decl(g.js, 0, 14)) + +=== tests/cases/conformance/salsa/h.js === +class H { +>H : Symbol(H, Decl(h.js, 0, 0)) + + constructor() { + this.x = 1; +>this.x : Symbol(H.x, Decl(h.js, 1, 19)) +>this : Symbol(H, Decl(h.js, 0, 0)) +>x : Symbol(H.x, Decl(h.js, 1, 19)) + } +} + +/** @param {H} p */ +function h(p) { p.x; } +>h : Symbol(h, Decl(h.js, 4, 1)) +>p : Symbol(p, Decl(h.js, 7, 11)) +>p.x : Symbol(H.x, Decl(h.js, 1, 19)) +>p : Symbol(p, Decl(h.js, 7, 11)) +>x : Symbol(H.x, Decl(h.js, 1, 19)) + diff --git a/tests/baselines/reference/typeFromParamTagForFunction.types b/tests/baselines/reference/typeFromParamTagForFunction.types new file mode 100644 index 00000000000..c1e16ddb33d --- /dev/null +++ b/tests/baselines/reference/typeFromParamTagForFunction.types @@ -0,0 +1,223 @@ +=== tests/cases/conformance/salsa/node.d.ts === +declare function require(id: string): any; +>require : (id: string) => any +>id : string + +declare var module: any, exports: any; +>module : any +>exports : any + +=== tests/cases/conformance/salsa/a-ext.js === +exports.A = function () { +>exports.A = function () { this.x = 1;} : () => void +>exports.A : any +>exports : any +>A : any +>function () { this.x = 1;} : () => void + + this.x = 1; +>this.x = 1 : 1 +>this.x : any +>this : any +>x : any +>1 : 1 + +}; + +=== tests/cases/conformance/salsa/a.js === +const { A } = require("./a-ext"); +>A : () => void +>require("./a-ext") : typeof "tests/cases/conformance/salsa/a-ext" +>require : (id: string) => any +>"./a-ext" : "./a-ext" + +/** @param {A} p */ +function a(p) { p.x; } +>a : (p: { x: number; }) => void +>p : { x: number; } +>p.x : number +>p : { x: number; } +>x : number + +=== tests/cases/conformance/salsa/b-ext.js === +exports.B = class { +>exports.B = class { constructor() { this.x = 1; }} : typeof (Anonymous class) +>exports.B : any +>exports : any +>B : any +>class { constructor() { this.x = 1; }} : typeof (Anonymous class) + + constructor() { + this.x = 1; +>this.x = 1 : 1 +>this.x : number +>this : this +>x : number +>1 : 1 + } +}; + +=== tests/cases/conformance/salsa/b.js === +const { B } = require("./b-ext"); +>B : typeof (Anonymous class) +>require("./b-ext") : typeof "tests/cases/conformance/salsa/b-ext" +>require : (id: string) => any +>"./b-ext" : "./b-ext" + +/** @param {B} p */ +function b(p) { p.x; } +>b : (p: (Anonymous class)) => void +>p : (Anonymous class) +>p.x : number +>p : (Anonymous class) +>x : number + +=== tests/cases/conformance/salsa/c-ext.js === +export function C() { +>C : () => void + + this.x = 1; +>this.x = 1 : 1 +>this.x : any +>this : any +>x : any +>1 : 1 +} + +=== tests/cases/conformance/salsa/c.js === +const { C } = require("./c-ext"); +>C : () => void +>require("./c-ext") : typeof "tests/cases/conformance/salsa/c-ext" +>require : (id: string) => any +>"./c-ext" : "./c-ext" + +/** @param {C} p */ +function c(p) { p.x; } +>c : (p: { x: number; }) => void +>p : { x: number; } +>p.x : number +>p : { x: number; } +>x : number + +=== tests/cases/conformance/salsa/d-ext.js === +export var D = function() { +>D : () => void +>function() { this.x = 1;} : () => void + + this.x = 1; +>this.x = 1 : 1 +>this.x : any +>this : any +>x : any +>1 : 1 + +}; + +=== tests/cases/conformance/salsa/d.js === +const { D } = require("./d-ext"); +>D : () => void +>require("./d-ext") : typeof "tests/cases/conformance/salsa/d-ext" +>require : (id: string) => any +>"./d-ext" : "./d-ext" + +/** @param {D} p */ +function d(p) { p.x; } +>d : (p: { x: number; }) => void +>p : { x: number; } +>p.x : number +>p : { x: number; } +>x : number + +=== tests/cases/conformance/salsa/e-ext.js === +export class E { +>E : E + + constructor() { + this.x = 1; +>this.x = 1 : 1 +>this.x : number +>this : this +>x : number +>1 : 1 + } +} + +=== tests/cases/conformance/salsa/e.js === +const { E } = require("./e-ext"); +>E : typeof E +>require("./e-ext") : typeof "tests/cases/conformance/salsa/e-ext" +>require : (id: string) => any +>"./e-ext" : "./e-ext" + +/** @param {E} p */ +function e(p) { p.x; } +>e : (p: E) => void +>p : E +>p.x : number +>p : E +>x : number + +=== tests/cases/conformance/salsa/f.js === +var F = function () { +>F : () => void +>function () { this.x = 1;} : () => void + + this.x = 1; +>this.x = 1 : 1 +>this.x : any +>this : any +>x : any +>1 : 1 + +}; + +/** @param {F} p */ +function f(p) { p.x; } +>f : (p: { x: number; }) => void +>p : { x: number; } +>p.x : number +>p : { x: number; } +>x : number + +=== tests/cases/conformance/salsa/g.js === +function G() { +>G : () => void + + this.x = 1; +>this.x = 1 : 1 +>this.x : any +>this : any +>x : any +>1 : 1 +} + +/** @param {G} p */ +function g(p) { p.x; } +>g : (p: { x: number; }) => void +>p : { x: number; } +>p.x : number +>p : { x: number; } +>x : number + +=== tests/cases/conformance/salsa/h.js === +class H { +>H : H + + constructor() { + this.x = 1; +>this.x = 1 : 1 +>this.x : number +>this : this +>x : number +>1 : 1 + } +} + +/** @param {H} p */ +function h(p) { p.x; } +>h : (p: H) => void +>p : H +>p.x : number +>p : H +>x : number + diff --git a/tests/baselines/reference/typeInferenceConflictingCandidates.errors.txt b/tests/baselines/reference/typeInferenceConflictingCandidates.errors.txt index d20b7ae4ede..c98b39cb4fe 100644 --- a/tests/baselines/reference/typeInferenceConflictingCandidates.errors.txt +++ b/tests/baselines/reference/typeInferenceConflictingCandidates.errors.txt @@ -1,11 +1,9 @@ -tests/cases/compiler/typeInferenceConflictingCandidates.ts(3,1): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '3'. +tests/cases/compiler/typeInferenceConflictingCandidates.ts(3,7): error TS2345: Argument of type '3' is not assignable to parameter of type '""'. ==== tests/cases/compiler/typeInferenceConflictingCandidates.ts (1 errors) ==== declare function g(a: T, b: T, c: (t: T) => T): T; g("", 3, a => a); - ~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate '""' is not a valid type argument because it is not a supertype of candidate '3'. \ No newline at end of file + ~ +!!! error TS2345: Argument of type '3' is not assignable to parameter of type '""'. \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterConstrainedToOuterTypeParameter.errors.txt b/tests/baselines/reference/typeParameterConstrainedToOuterTypeParameter.errors.txt new file mode 100644 index 00000000000..926ad4b3bff --- /dev/null +++ b/tests/baselines/reference/typeParameterConstrainedToOuterTypeParameter.errors.txt @@ -0,0 +1,22 @@ +tests/cases/compiler/typeParameterConstrainedToOuterTypeParameter.ts(10,5): error TS2322: Type 'A' is not assignable to type 'B'. + Types of parameters 'x' and 'x' are incompatible. + Type 'U' is not assignable to type 'string[]'. + Type 'string' is not assignable to type 'string[]'. + + +==== tests/cases/compiler/typeParameterConstrainedToOuterTypeParameter.ts (1 errors) ==== + interface A { + (x: U[]) + } + + interface B { + (x: U) + } + + var a: A + var b: B = a; // assignment should be legal (both U's get instantiated to any for comparison) + ~ +!!! error TS2322: Type 'A' is not assignable to type 'B'. +!!! error TS2322: Types of parameters 'x' and 'x' are incompatible. +!!! error TS2322: Type 'U' is not assignable to type 'string[]'. +!!! error TS2322: Type 'string' is not assignable to type 'string[]'. \ No newline at end of file diff --git a/tests/baselines/reference/underscoreTest1.errors.txt b/tests/baselines/reference/underscoreTest1.errors.txt new file mode 100644 index 00000000000..ca8df792231 --- /dev/null +++ b/tests/baselines/reference/underscoreTest1.errors.txt @@ -0,0 +1,908 @@ +tests/cases/compiler/underscoreTest1_underscoreTests.ts(26,7): error TS2345: Argument of type '(string | number | boolean)[]' is not assignable to parameter of type 'Dictionary<{}>'. + Index signature is missing in type '(string | number | boolean)[]'. + + +==== tests/cases/compiler/underscoreTest1_underscoreTests.ts (1 errors) ==== + /// + + declare var $; + declare function alert(x: string): void; + + _.each([1, 2, 3], (num) => alert(num.toString())); + _.each({ one: 1, two: 2, three: 3 }, (value: number, key?: string) => alert(value.toString())); + + _.map([1, 2, 3], (num) => num * 3); + _.map({ one: 1, two: 2, three: 3 }, (value: number, key?: string) => value * 3); + + var sum = _.reduce([1, 2, 3], (memo, num) => memo + num, 0); + + var list = [[0, 1], [2, 3], [4, 5]]; + var flat = _.reduceRight(list, (a, b) => a.concat(b), []); + + var even = _.find([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); + + var evens = _.filter([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); + + var listOfPlays = [{ title: "Cymbeline", author: "Shakespeare", year: 1611 }, { title: "The Tempest", author: "Shakespeare", year: 1611 }, { title: "Other", author: "Not Shakespeare", year: 2012 }]; + _.where(listOfPlays, { author: "Shakespeare", year: 1611 }); + + var odds = _.reject([1, 2, 3, 4, 5, 6], (num) => num % 2 == 0); + + _.all([true, 1, null, 'yes'], _.identity); + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type '(string | number | boolean)[]' is not assignable to parameter of type 'Dictionary<{}>'. +!!! error TS2345: Index signature is missing in type '(string | number | boolean)[]'. + + _.any([null, 0, 'yes', false]); + + _.contains([1, 2, 3], 3); + + _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + + var stooges = [{ name: 'moe', age: 40 }, { name: 'larry', age: 50 }, { name: 'curly', age: 60 }]; + _.pluck(stooges, 'name'); + + _.max(stooges, (stooge) => stooge.age); + + var numbers = [10, 5, 100, 2, 1000]; + _.min(numbers); + + _.sortBy([1, 2, 3, 4, 5, 6], (num) => Math.sin(num)); + + + // not sure how this is typechecking at all.. Math.floor(e) is number not string..? + _([1.3, 2.1, 2.4]).groupBy((e: number, i?: number, list?: number[]) => Math.floor(e)); + _.groupBy([1.3, 2.1, 2.4], (num: number) => Math.floor(num)); + _.groupBy(['one', 'two', 'three'], 'length'); + + _.countBy([1, 2, 3, 4, 5], (num) => num % 2 == 0 ? 'even' : 'odd'); + + _.shuffle([1, 2, 3, 4, 5, 6]); + + // (function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4); + + _.size({ one: 1, two: 2, three: 3 }); + + /////////////////////////////////////////////////////////////////////////////////////// + + _.first([5, 4, 3, 2, 1]); + _.initial([5, 4, 3, 2, 1]); + _.last([5, 4, 3, 2, 1]); + _.rest([5, 4, 3, 2, 1]); + _.compact([0, 1, false, 2, '', 3]); + + _.flatten([1, 2, 3, 4]); + _.flatten([1, [2]]); + + // typescript doesn't like the elements being different + _.flatten([1, [2], [3, [[4]]]]); + _.flatten([1, [2], [3, [[4]]]], true); + _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); + _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); + _.difference([1, 2, 3, 4, 5], [5, 2, 10]); + _.uniq([1, 2, 1, 3, 1, 4]); + _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]); + _.object(['moe', 'larry', 'curly'], [30, 40, 50]); + _.object([['moe', 30], ['larry', 40], ['curly', 50]]); + _.indexOf([1, 2, 3], 2); + _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + _.sortedIndex([10, 20, 30, 40, 50], 35); + _.range(10); + _.range(1, 11); + _.range(0, 30, 5); + _.range(0, 30, 5); + _.range(0); + + /////////////////////////////////////////////////////////////////////////////////////// + + var func = function (greeting) { return greeting + ': ' + this.name }; + // need a second var otherwise typescript thinks func signature is the above func type, + // instead of the newly returned _bind => func type. + var func2 = _.bind(func, { name: 'moe' }, 'hi'); + func2(); + + var buttonView = { + label: 'underscore', + onClick: function () { alert('clicked: ' + this.label); }, + onHover: function () { alert('hovering: ' + this.label); } + }; + _.bindAll(buttonView); + $('#underscore_button').bind('click', buttonView.onClick); + + var fibonacci = _.memoize(function (n) { + return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); + }); + + var log = _.bind((message?: string, ...rest: string[]) => { }, Date); + _.delay(log, 1000, 'logged later'); + + _.defer(function () { alert('deferred'); }); + + var updatePosition = () => alert('updating position...'); + var throttled = _.throttle(updatePosition, 100); + $(null).scroll(throttled); + + var calculateLayout = () => alert('calculating layout...'); + var lazyLayout = _.debounce(calculateLayout, 300); + $(null).resize(lazyLayout); + + var createApplication = () => alert('creating application...'); + var initialize = _.once(createApplication); + initialize(); + initialize(); + + var notes: any[]; + var render = () => alert("rendering..."); + var renderNotes = _.after(notes.length, render); + _.each(notes, (note) => note.asyncSave({ success: renderNotes })); + + var hello = function (name) { return "hello: " + name; }; + hello = _.wrap(hello, (func, arg) => { return "before, " + func(arg) + ", after"; }); + hello("moe"); + + var greet = function (name) { return "hi: " + name; }; + var exclaim = function (statement) { return statement + "!"; }; + var welcome = _.compose(exclaim, greet); + welcome('moe'); + + /////////////////////////////////////////////////////////////////////////////////////// + + _.keys({ one: 1, two: 2, three: 3 }); + _.values({ one: 1, two: 2, three: 3 }); + _.pairs({ one: 1, two: 2, three: 3 }); + _.invert({ Moe: "Moses", Larry: "Louis", Curly: "Jerome" }); + _.functions(_); + _.extend({ name: 'moe' }, { age: 50 }); + _.pick({ name: 'moe', age: 50, userid: 'moe1' }, 'name', 'age'); + _.omit({ name: 'moe', age: 50, userid: 'moe1' }, 'userid'); + + var iceCream = { flavor: "chocolate" }; + _.defaults(iceCream, { flavor: "vanilla", sprinkles: "lots" }); + + _.clone({ name: 'moe' }); + + _.chain([1, 2, 3, 200]) + .filter(function (num) { return num % 2 == 0; }) + .tap(alert) + .map(function (num) { return num * num }) + .value(); + + _.has({ a: 1, b: 2, c: 3 }, "b"); + + var moe = { name: 'moe', luckyNumbers: [13, 27, 34] }; + var clone = { name: 'moe', luckyNumbers: [13, 27, 34] }; + moe == clone; + _.isEqual(moe, clone); + + _.isEmpty([1, 2, 3]); + _.isEmpty({}); + + _.isElement($('body')[0]); + + (function () { return _.isArray(arguments); })(); + _.isArray([1, 2, 3]); + + _.isObject({}); + _.isObject(1); + + + // (() => { return _.isArguments(arguments); })(1, 2, 3); + _.isArguments([1, 2, 3]); + + _.isFunction(alert); + + _.isString("moe"); + + _.isNumber(8.4 * 5); + + _.isFinite(-101); + + _.isFinite(-Infinity); + + _.isBoolean(null); + + _.isDate(new Date()); + + _.isRegExp(/moe/); + + _.isNaN(NaN); + isNaN(undefined); + _.isNaN(undefined); + + _.isNull(null); + _.isNull(undefined); + + _.isUndefined((null).missingVariable); + + /////////////////////////////////////////////////////////////////////////////////////// + + var underscore = _.noConflict(); + + var moe2 = { name: 'moe' }; + moe2 === _.identity(moe); + + var genie; + + _.times(3, function (n) { genie.grantWishNumber(n); }); + + _.random(0, 100); + + _.mixin({ + capitalize: function (string) { + return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase(); + } + }); + (_("fabio")).capitalize(); + + _.uniqueId('contact_'); + + _.escape('Curly, Larry & Moe'); + + var object = { cheese: 'crumpets', stuff: function () { return 'nonsense'; } }; + _.result(object, 'cheese'); + + _.result(object, 'stuff'); + + var compiled = _.template("hello: <%= name %>"); + compiled({ name: 'moe' }); + var list2 = "<% _.each(people, function(name) { %>
  • <%= name %>
  • <% }); %>"; + _.template(list2, { people: ['moe', 'curly', 'larry'] }); + var template = _.template("<%- value %>"); + template({ value: '