diff --git a/Gulpfile.ts b/Gulpfile.ts index d7e20a557fd..054e99c8003 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -177,7 +177,7 @@ for (const i in libraryTargets) { const configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js"); const configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts"); const packageJson = "package.json"; -const programTs = path.join(compilerDirectory, "program.ts"); +const versionFile = path.join(compilerDirectory, "core.ts"); function needsUpdate(source: string | string[], dest: string | string[]): boolean { if (typeof source === "string" && typeof dest === "string") { @@ -285,7 +285,7 @@ gulp.task(configureNightlyJs, false, [], () => { // Nightly management tasks gulp.task("configure-nightly", "Runs scripts/configureNightly.ts to prepare a build for nightly publishing", [configureNightlyJs], (done) => { - exec(host, [configureNightlyJs, packageJson, programTs], done, done); + exec(host, [configureNightlyJs, packageJson, versionFile], done, done); }); gulp.task("publish-nightly", "Runs `npm publish --tag next` to create a new nightly build on npm", ["LKG"], () => { return runSequence("clean", "useDebugMode", "runtests", (done) => { diff --git a/Jakefile.js b/Jakefile.js index 132a99e5087..087bbb67511 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -593,7 +593,7 @@ task("generate-diagnostics", [diagnosticInfoMapTs]); var configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js"); var configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts"); var packageJson = "package.json"; -var programTs = path.join(compilerDirectory, "program.ts"); +var versionFile = path.join(compilerDirectory, "core.ts"); file(configureNightlyTs); @@ -609,7 +609,7 @@ task("setDebugMode", function () { }); task("configure-nightly", [configureNightlyJs], function () { - var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + programTs; + var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + versionFile; console.log(cmd); exec(cmd); }, { async: true }); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 21563f48e8a..6d89c39c82f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4550,6 +4550,10 @@ namespace ts { unknownType); } + function getErasedTemplateTypeFromMappedType(type: MappedType) { + return instantiateType(getTemplateTypeFromMappedType(type), createUnaryTypeMapper(getTypeParameterFromMappedType(type), anyType)); + } + function isGenericMappedType(type: Type) { if (getObjectFlags(type) & ObjectFlags.Mapped) { const constraintType = getConstraintTypeFromMappedType(type); @@ -7190,29 +7194,18 @@ namespace ts { return result; } } - if (isGenericMappedType(target)) { - // A type [P in S]: X is related to a type [P in T]: Y if T is related to S and X is related to Y. - if (isGenericMappedType(source)) { - if ((result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) && - (result = isRelatedTo(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target), reportErrors))) { - return result; - } - } - } - else { - // Even if relationship doesn't hold for unions, intersections, or generic type references, - // it may hold in a structural comparison. - const apparentSource = getApparentType(source); - // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates - // to X. Failing both of those we want to check if the aggregation of A and B's members structurally - // relates to X. Thus, we include intersection types on the source side here. - if (apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection) && target.flags & TypeFlags.Object) { - // Report structural errors only if we haven't reported any errors yet - const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !(source.flags & TypeFlags.Primitive); - if (result = objectTypeRelatedTo(apparentSource, source, target, reportStructuralErrors)) { - errorInfo = saveErrorInfo; - return result; - } + // Even if relationship doesn't hold for unions, intersections, or generic type references, + // it may hold in a structural comparison. + const apparentSource = getApparentType(source); + // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates + // to X. Failing both of those we want to check if the aggregation of A and B's members structurally + // relates to X. Thus, we include intersection types on the source side here. + if (apparentSource.flags & (TypeFlags.Object | TypeFlags.Intersection) && target.flags & TypeFlags.Object) { + // Report structural errors only if we haven't reported any errors yet + const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !(source.flags & TypeFlags.Primitive); + if (result = objectTypeRelatedTo(apparentSource, source, target, reportStructuralErrors)) { + errorInfo = saveErrorInfo; + return result; } } } @@ -7441,6 +7434,9 @@ namespace ts { if (expandingFlags === 3) { result = Ternary.Maybe; } + else if (isGenericMappedType(source) || isGenericMappedType(target)) { + result = mappedTypeRelatedTo(source, target, reportErrors); + } else { result = propertiesRelatedTo(source, target, reportErrors); if (result) { @@ -7472,6 +7468,30 @@ namespace ts { return result; } + // A type [P in S]: X is related to a type [P in T]: Y if T is related to S and X is related to Y. + function mappedTypeRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary { + if (isGenericMappedType(source) && isGenericMappedType(target)) { + let result: Ternary; + if (relation === identityRelation) { + const readonlyMatches = !(source).declaration.readonlyToken === !(target).declaration.readonlyToken; + const optionalMatches = !(source).declaration.questionToken === !(target).declaration.questionToken; + if (readonlyMatches && optionalMatches) { + if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { + return result & isRelatedTo(getErasedTemplateTypeFromMappedType(source), getErasedTemplateTypeFromMappedType(target), reportErrors); + } + } + } + else { + if (relation === comparableRelation || !(source).declaration.questionToken || (target).declaration.questionToken) { + if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { + return result & isRelatedTo(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target), reportErrors); + } + } + } + } + return Ternary.False; + } + function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary { if (relation === identityRelation) { return propertiesIdenticalTo(source, target); @@ -9721,20 +9741,20 @@ namespace ts { } if (targetType) { - return getNarrowedType(type, targetType, assumeTrue); + return getNarrowedType(type, targetType, assumeTrue, isTypeInstanceOf); } return type; } - function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean) { + function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean, isRelated: (source: Type, target: Type) => boolean) { if (!assumeTrue) { - return filterType(type, t => !isTypeInstanceOf(t, candidate)); + return filterType(type, t => !isRelated(t, candidate)); } // If the current type is a union type, remove all constituents that couldn't be instances of // the candidate type. If one or more constituents remain, return a union of those. if (type.flags & TypeFlags.Union) { - const assignableType = filterType(type, t => isTypeInstanceOf(t, candidate)); + const assignableType = filterType(type, t => isRelated(t, candidate)); if (!(assignableType.flags & TypeFlags.Never)) { return assignableType; } @@ -9770,7 +9790,7 @@ namespace ts { const predicateArgument = callExpression.arguments[predicate.parameterIndex]; if (predicateArgument) { if (isMatchingReference(reference, predicateArgument)) { - return getNarrowedType(type, predicate.type, assumeTrue); + return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf); } if (containsMatchingReference(reference, predicateArgument)) { return declaredType; @@ -9783,7 +9803,7 @@ namespace ts { const accessExpression = invokedExpression as ElementAccessExpression | PropertyAccessExpression; const possibleReference = skipParentheses(accessExpression.expression); if (isMatchingReference(reference, possibleReference)) { - return getNarrowedType(type, predicate.type, assumeTrue); + return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf); } if (containsMatchingReference(reference, possibleReference)) { return declaredType; diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 4f6e873d357..ac330b467c9 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,6 +1,11 @@ /// /// +namespace ts { + /** The version of the TypeScript compiler release */ + export const version = "2.2.0"; +} + /* @internal */ namespace ts { /** diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 85c27a63839..041923a8857 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3,10 +3,6 @@ /// namespace ts { - /** The version of the TypeScript compiler release */ - - export const version = "2.2.0"; - const emptyArray: any[] = []; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string { diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 666baf7d123..5d2fec82f5e 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -946,7 +946,7 @@ namespace ts { * @param node The node to visit. */ function visitArrayLiteralExpression(node: ArrayLiteralExpression) { - return visitElements(node.elements, node.multiLine); + return visitElements(node.elements, /*leadingElement*/ undefined, /*location*/ undefined, node.multiLine); } /** @@ -956,7 +956,7 @@ namespace ts { * @param elements The elements to visit. * @param multiLine Whether array literals created should be emitted on multiple lines. */ - function visitElements(elements: NodeArray, _multiLine?: boolean) { + function visitElements(elements: NodeArray, leadingElement?: Expression, location?: TextRange, multiLine?: boolean) { // [source] // ar = [1, yield, 2]; // @@ -971,18 +971,22 @@ namespace ts { const temp = declareLocal(); let hasAssignedTemp = false; if (numInitialElements > 0) { + const initialElements = visitNodes(elements, visitor, isExpression, 0, numInitialElements); emitAssignment(temp, createArrayLiteral( - visitNodes(elements, visitor, isExpression, 0, numInitialElements) + leadingElement + ? [leadingElement, ...initialElements] + : initialElements ) ); + leadingElement = undefined; hasAssignedTemp = true; } const expressions = reduceLeft(elements, reduceElement, [], numInitialElements); return hasAssignedTemp - ? createArrayConcat(temp, [createArrayLiteral(expressions)]) - : createArrayLiteral(expressions); + ? createArrayConcat(temp, [createArrayLiteral(expressions, /*location*/ undefined, multiLine)]) + : createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, location, multiLine); function reduceElement(expressions: Expression[], element: Expression) { if (containsYield(element) && expressions.length > 0) { @@ -991,11 +995,16 @@ namespace ts { hasAssignedTemp ? createArrayConcat( temp, - [createArrayLiteral(expressions)] + [createArrayLiteral(expressions, /*location*/ undefined, multiLine)] + ) + : createArrayLiteral( + leadingElement ? [leadingElement, ...expressions] : expressions, + /*location*/ undefined, + multiLine ) - : createArrayLiteral(expressions) ); hasAssignedTemp = true; + leadingElement = undefined; expressions = []; } @@ -1131,7 +1140,10 @@ namespace ts { createFunctionApply( cacheExpression(visitNode(target, visitor, isExpression)), thisArg, - visitElements(node.arguments) + visitElements( + node.arguments, + /*leadingElement*/ createVoidZero() + ) ), /*typeArguments*/ undefined, [], diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 2c457a432c6..e402a96fade 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -180,7 +180,7 @@ interface ObjectConstructor { * Prevents the modification of existing property attributes and values, and prevents the addition of new properties. * @param o Object on which to lock the attributes. */ - freeze(o: T): T; + freeze(o: T): Readonly; /** * Prevents the addition of new properties to an object. @@ -1343,6 +1343,34 @@ interface ArrayLike { readonly [n: number]: T; } +/** + * Make all properties in T optional + */ +type Partial = { + [P in keyof T]?: T[P]; +}; + +/** + * Make all properties in T readonly + */ +type Readonly = { + readonly [P in keyof T]: T[P]; +}; + +/** + * From T pick a set of properties K + */ +type Pick = { + [P in K]: T[P]; +} + +/** + * Construct a type with a set of properties K of type T + */ +type Record = { + [P in K]: T; +} + /** * Represents a raw buffer of binary data, which is used to store data for the * different typed arrays. ArrayBuffers cannot be read from or written to directly, diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 0d9a0a76d7a..dad66f3cc71 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2106,6 +2106,11 @@ namespace ts.server.protocol { * true if install request succeeded, otherwise - false */ installSuccess: boolean; + + /** + * version of typings installer + */ + typingsInstallerVersion: string; } export interface NavBarResponse extends Response { diff --git a/src/server/server.ts b/src/server/server.ts index c561277c7d2..220b0d90c65 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -300,7 +300,8 @@ namespace ts.server { telemetryEventName: "typingsInstalled", payload: { installedPackages: response.packagesToInstall.join(","), - installSuccess: response.installSuccess + installSuccess: response.installSuccess, + typingsInstallerVersion: response.typingsInstallerVersion } }; const eventName: protocol.TelemetryEventName = "telemetry"; diff --git a/src/server/types.d.ts b/src/server/types.d.ts index 3fd90e7fd3e..a4032bf062e 100644 --- a/src/server/types.d.ts +++ b/src/server/types.d.ts @@ -69,6 +69,7 @@ declare namespace ts.server { readonly packagesToInstall: ReadonlyArray; readonly kind: EventInstall; readonly installSuccess: boolean; + readonly typingsInstallerVersion: string; } export interface InstallTypingHost extends JsTyping.TypingResolutionHost { diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 74311dae4e2..bdfdda3033c 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -61,17 +61,12 @@ namespace ts.server.typingsInstaller { return combinePaths(normalizeSlashes(globalTypingsCacheLocation), `node_modules/${TypesRegistryPackageName}/index.json`); } - - type Exec = { - (command: string, options: { cwd: string }, callback?: (error: Error, stdout: string, stderr: string) => void): any - }; - type ExecSync = { - (command: string, options: { cwd: string, stdio: "ignore" }): any - }; + (command: string, options: { cwd: string, stdio?: "ignore" }): any + } export class NodeTypingsInstaller extends TypingsInstaller { - private readonly exec: Exec; + private readonly execSync: ExecSync; private readonly npmPath: string; readonly typesRegistry: Map; @@ -87,8 +82,7 @@ namespace ts.server.typingsInstaller { this.log.writeLine(`Process id: ${process.pid}`); } this.npmPath = getNPMLocation(process.argv[0]); - let execSync: ExecSync; - ({ exec: this.exec, execSync } = require("child_process")); + ({ execSync: this.execSync } = require("child_process")); this.ensurePackageDirectoryExists(globalTypingsCacheLocation); @@ -96,7 +90,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Updating ${TypesRegistryPackageName} npm package...`); } - execSync(`${this.npmPath} install ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); + this.execSync(`${this.npmPath} install ${TypesRegistryPackageName}`, { cwd: globalTypingsCacheLocation, stdio: "ignore" }); } catch (e) { if (this.log.isEnabled()) { @@ -135,13 +129,21 @@ namespace ts.server.typingsInstaller { } const command = `${this.npmPath} install ${args.join(" ")} --save-dev`; const start = Date.now(); - this.exec(command, { cwd }, (err, stdout, stderr) => { - if (this.log.isEnabled()) { - this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms${sys.newLine}stdout: ${stdout}${sys.newLine}stderr: ${stderr}`); - } - // treat absence of error as success - onRequestCompleted(!err); - }); + let stdout: Buffer; + let stderr: Buffer; + let hasError = false; + try { + stdout = this.execSync(command, { cwd }); + } + catch (e) { + stdout = e.stdout; + stderr = e.stderr; + hasError = true; + } + if (this.log.isEnabled()) { + this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms${sys.newLine}stdout: ${stdout && stdout.toString()}${sys.newLine}stderr: ${stderr && stderr.toString()}`); + } + onRequestCompleted(!hasError); } } diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 2ea0296e22a..677e2c7bba0 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -19,9 +19,17 @@ namespace ts.server.typingsInstaller { writeLine: noop }; - function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost): string { - const result = resolveModuleName(packageName, combinePaths(cachePath, "index.d.ts"), { moduleResolution: ModuleResolutionKind.NodeJs }, installTypingHost); - return result.resolvedModule && result.resolvedModule.resolvedFileName; + function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost, log: Log): string { + try { + const result = resolveModuleName(packageName, combinePaths(cachePath, "index.d.ts"), { moduleResolution: ModuleResolutionKind.NodeJs }, installTypingHost); + return result.resolvedModule && result.resolvedModule.resolvedFileName; + } + catch (e) { + if (log.isEnabled()) { + log.writeLine(`Failed to resolve ${packageName} in folder '${cachePath}': ${(e).message}`); + } + return undefined; + } } export enum PackageNameValidationResult { @@ -192,8 +200,9 @@ namespace ts.server.typingsInstaller { if (!packageName) { continue; } - const typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost); + const typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost, this.log); if (!typingFile) { + this.missingTypingsSet[packageName] = true; continue; } const existingTypingFile = this.packageNameToTypingLocation[packageName]; @@ -224,7 +233,7 @@ namespace ts.server.typingsInstaller { } const result: string[] = []; for (const typing of typingsToInstall) { - if (this.missingTypingsSet[typing]) { + if (this.missingTypingsSet[typing] || this.packageNameToTypingLocation[typing]) { continue; } const validationResult = validatePackageName(typing); @@ -305,7 +314,8 @@ namespace ts.server.typingsInstaller { this.sendResponse({ kind: EventInstall, packagesToInstall: scopedTypings, - installSuccess: ok + installSuccess: ok, + typingsInstallerVersion: ts.version // qualified explicitly to prevent occasional shadowing }); } @@ -321,16 +331,13 @@ namespace ts.server.typingsInstaller { // TODO: watch project directory if (this.log.isEnabled()) { - this.log.writeLine(`Requested to install typings ${JSON.stringify(scopedTypings)}, installed typings ${JSON.stringify(scopedTypings)}`); + this.log.writeLine(`Installed typings ${JSON.stringify(scopedTypings)}`); } const installedTypingFiles: string[] = []; - for (const t of scopedTypings) { - const packageName = getBaseFileName(t); - if (!packageName) { - continue; - } - const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost); + for (const packageName of filteredTypings) { + const typingFile = typingToFileName(cachePath, packageName, this.installTypingHost, this.log); if (!typingFile) { + this.missingTypingsSet[packageName] = true; continue; } if (!this.packageNameToTypingLocation[packageName]) { diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols index 217e11dc95d..5251973005f 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.symbols +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.symbols @@ -64,25 +64,13 @@ if (isNodeList(sourceObj)) { >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) sourceObj.length; ->sourceObj.length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +>sourceObj.length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) ->length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +>length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) } if (isHTMLCollection(sourceObj)) { >isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) ->sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) - - sourceObj.length; ->sourceObj.length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) ->sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) ->length : Symbol(HTMLCollection.length, Decl(controlFlowBinaryOrExpression.ts, 14, 33)) -} - -if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { ->isNodeList : Symbol(isNodeList, Decl(controlFlowBinaryOrExpression.ts, 16, 1)) ->sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) ->isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) >sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) sourceObj.length; @@ -91,3 +79,15 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { >length : Symbol(length, Decl(controlFlowBinaryOrExpression.ts, 10, 27), Decl(controlFlowBinaryOrExpression.ts, 14, 33)) } +if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { +>isNodeList : Symbol(isNodeList, Decl(controlFlowBinaryOrExpression.ts, 16, 1)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>isHTMLCollection : Symbol(isHTMLCollection, Decl(controlFlowBinaryOrExpression.ts, 18, 67)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) + + sourceObj.length; +>sourceObj.length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +>sourceObj : Symbol(sourceObj, Decl(controlFlowBinaryOrExpression.ts, 23, 3)) +>length : Symbol(NodeList.length, Decl(controlFlowBinaryOrExpression.ts, 10, 27)) +} + diff --git a/tests/baselines/reference/controlFlowBinaryOrExpression.types b/tests/baselines/reference/controlFlowBinaryOrExpression.types index 3634a322396..e843844ebf1 100644 --- a/tests/baselines/reference/controlFlowBinaryOrExpression.types +++ b/tests/baselines/reference/controlFlowBinaryOrExpression.types @@ -80,7 +80,7 @@ if (isNodeList(sourceObj)) { sourceObj.length; >sourceObj.length : number ->sourceObj : NodeList +>sourceObj : NodeList | HTMLCollection >length : number } @@ -91,7 +91,7 @@ if (isHTMLCollection(sourceObj)) { sourceObj.length; >sourceObj.length : number ->sourceObj : HTMLCollection +>sourceObj : NodeList | HTMLCollection >length : number } @@ -102,11 +102,11 @@ if (isNodeList(sourceObj) || isHTMLCollection(sourceObj)) { >sourceObj : NodeList | HTMLCollection | { a: string; } >isHTMLCollection(sourceObj) : boolean >isHTMLCollection : (sourceObj: any) => sourceObj is HTMLCollection ->sourceObj : HTMLCollection | { a: string; } +>sourceObj : { a: string; } sourceObj.length; >sourceObj.length : number ->sourceObj : NodeList | HTMLCollection +>sourceObj : NodeList >length : number } diff --git a/tests/baselines/reference/es5-asyncFunctionNewExpressions.js b/tests/baselines/reference/es5-asyncFunctionNewExpressions.js index 486bf0fdd7f..0fb1140f129 100644 --- a/tests/baselines/reference/es5-asyncFunctionNewExpressions.js +++ b/tests/baselines/reference/es5-asyncFunctionNewExpressions.js @@ -119,7 +119,7 @@ function newExpression2() { _a = x.bind; return [4 /*yield*/, y]; case 1: - new (_a.apply(x, [_c.sent(), z]))(); + new (_a.apply(x, [void 0, _c.sent(), z]))(); return [2 /*return*/]; } }); @@ -132,7 +132,7 @@ function newExpression3() { switch (_c.label) { case 0: _a = x.bind; - _b = [y]; + _b = [void 0, y]; return [4 /*yield*/, z]; case 1: new (_a.apply(x, _b.concat([_c.sent()])))(); @@ -280,7 +280,7 @@ function newExpression13() { _b = (_a = x.a).bind; return [4 /*yield*/, y]; case 1: - new (_b.apply(_a, [_d.sent(), z]))(); + new (_b.apply(_a, [void 0, _d.sent(), z]))(); return [2 /*return*/]; } }); @@ -293,7 +293,7 @@ function newExpression14() { switch (_d.label) { case 0: _b = (_a = x.a).bind; - _c = [y]; + _c = [void 0, y]; return [4 /*yield*/, z]; case 1: new (_b.apply(_a, _c.concat([_d.sent()])))(); @@ -362,7 +362,7 @@ function newExpression19() { _b = (_a = x[a]).bind; return [4 /*yield*/, y]; case 1: - new (_b.apply(_a, [_d.sent(), z]))(); + new (_b.apply(_a, [void 0, _d.sent(), z]))(); return [2 /*return*/]; } }); @@ -375,7 +375,7 @@ function newExpression20() { switch (_d.label) { case 0: _b = (_a = x[a]).bind; - _c = [y]; + _c = [void 0, y]; return [4 /*yield*/, z]; case 1: new (_b.apply(_a, _c.concat([_d.sent()])))(); diff --git a/tests/baselines/reference/instanceofWithStructurallyIdenticalTypes.errors.txt b/tests/baselines/reference/instanceofWithStructurallyIdenticalTypes.errors.txt new file mode 100644 index 00000000000..3f1e210d7b4 --- /dev/null +++ b/tests/baselines/reference/instanceofWithStructurallyIdenticalTypes.errors.txt @@ -0,0 +1,76 @@ +tests/cases/compiler/instanceofWithStructurallyIdenticalTypes.ts(32,18): error TS2339: Property 'item' does not exist on type 'never'. + + +==== tests/cases/compiler/instanceofWithStructurallyIdenticalTypes.ts (1 errors) ==== + // Repro from #7271 + + class C1 { item: string } + class C2 { item: string[] } + class C3 { item: string } + + function foo1(x: C1 | C2 | C3): string { + if (x instanceof C1) { + return x.item; + } + else if (x instanceof C2) { + return x.item[0]; + } + else if (x instanceof C3) { + return x.item; + } + return "error"; + } + + function isC1(c: C1 | C2 | C3): c is C1 { return c instanceof C1 } + function isC2(c: C1 | C2 | C3): c is C2 { return c instanceof C2 } + function isC3(c: C1 | C2 | C3): c is C3 { return c instanceof C3 } + + function foo2(x: C1 | C2 | C3): string { + if (isC1(x)) { + return x.item; + } + else if (isC2(x)) { + return x.item[0]; + } + else if (isC3(x)) { + return x.item; + ~~~~ +!!! error TS2339: Property 'item' does not exist on type 'never'. + } + return "error"; + } + + // More tests + + class A { a: string } + class A1 extends A { } + class A2 { a: string } + class B extends A { b: string } + + function goo(x: A) { + if (x instanceof A) { + x; // A + } + else { + x; // never + } + if (x instanceof A1) { + x; // A1 + } + else { + x; // A + } + if (x instanceof A2) { + x; // A2 + } + else { + x; // A + } + if (x instanceof B) { + x; // B + } + else { + x; // A + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeErrors.errors.txt b/tests/baselines/reference/mappedTypeErrors.errors.txt index 4efcc579ba8..0e1198285ba 100644 --- a/tests/baselines/reference/mappedTypeErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeErrors.errors.txt @@ -1,41 +1,29 @@ -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(34,20): error TS2313: Type parameter 'P' has a circular constraint. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(35,20): error TS2322: Type 'Date' is not assignable to type 'string | number'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(20,20): error TS2313: Type parameter 'P' has a circular constraint. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(21,20): error TS2322: Type 'Date' is not assignable to type 'string | number'. Type 'Date' is not assignable to type 'number'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(36,19): error TS2344: Type 'Date' does not satisfy the constraint 'string | number'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(22,19): error TS2344: Type 'Date' does not satisfy the constraint 'string | number'. Type 'Date' is not assignable to type 'number'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(39,24): error TS2344: Type '"foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(40,24): error TS2344: Type '"name" | "foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(25,24): error TS2344: Type '"foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(26,24): error TS2344: Type '"name" | "foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. Type '"foo"' is not assignable to type '"name" | "width" | "height" | "visible"'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(42,24): error TS2344: Type '"x" | "y"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(28,24): error TS2344: Type '"x" | "y"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. Type '"x"' is not assignable to type '"name" | "width" | "height" | "visible"'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(44,24): error TS2344: Type 'undefined' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(47,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(30,24): error TS2344: Type 'undefined' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(33,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. Type 'T' is not assignable to type '"visible"'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(51,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(37,24): error TS2344: Type 'T' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. Type 'string | number' is not assignable to type '"name" | "width" | "height" | "visible"'. Type 'string' is not assignable to type '"name" | "width" | "height" | "visible"'. Type 'T' is not assignable to type '"visible"'. Type 'string | number' is not assignable to type '"visible"'. Type 'string' is not assignable to type '"visible"'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(59,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P]; }'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(60,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(61,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P]; }'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(66,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]: T[P][]; }'. -==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (9 errors) ==== - - type Partial = { - [P in keyof T]?: T[P]; - }; - - type Readonly = { - readonly [P in keyof T]: T[P]; - }; - - type Pick = { - [P in K]: T[P]; - } - - type Record = { - [_ in K]: T; - } +==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (13 errors) ==== interface Shape { name: string; @@ -53,6 +41,8 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(51,24): error TS2344: T y: number; } + // Constraint checking + type T00 = { [P in P]: string }; // Error ~ !!! error TS2313: Type parameter 'P' has a circular constraint. @@ -107,4 +97,33 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(51,24): error TS2344: T function f4(x: T) { let y: Pick; + } + + // Type identity checking + + function f10() { + type K = keyof T; + var x: { [P in keyof T]: T[P] }; + var x: { [Q in keyof T]: T[Q] }; + var x: { [R in K]: T[R] }; + } + + function f11() { + var x: { [P in keyof T]: T[P] }; + var x: { [P in keyof T]?: T[P] }; // Error + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]?: T[P]; }'. + var x: { readonly [P in keyof T]: T[P] }; // Error + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]: T[P]; }'. + var x: { readonly [P in keyof T]?: T[P] }; // Error + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ readonly [P in keyof T]?: T[P]; }'. + } + + function f12() { + var x: { [P in keyof T]: T[P] }; + var x: { [P in keyof T]: T[P][] }; // Error + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '{ [P in keyof T]: T[P]; }', but here has type '{ [P in keyof T]: T[P][]; }'. } \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeErrors.js b/tests/baselines/reference/mappedTypeErrors.js index b2c8dc2e84a..fe03b5c9593 100644 --- a/tests/baselines/reference/mappedTypeErrors.js +++ b/tests/baselines/reference/mappedTypeErrors.js @@ -1,21 +1,5 @@ //// [mappedTypeErrors.ts] -type Partial = { - [P in keyof T]?: T[P]; -}; - -type Readonly = { - readonly [P in keyof T]: T[P]; -}; - -type Pick = { - [P in K]: T[P]; -} - -type Record = { - [_ in K]: T; -} - interface Shape { name: string; width: number; @@ -32,6 +16,8 @@ interface Point { y: number; } +// Constraint checking + type T00 = { [P in P]: string }; // Error type T01 = { [P in Date]: number }; // Error type T02 = Record; // Error @@ -58,6 +44,27 @@ function f3(x: T) { function f4(x: T) { let y: Pick; +} + +// Type identity checking + +function f10() { + type K = keyof T; + var x: { [P in keyof T]: T[P] }; + var x: { [Q in keyof T]: T[Q] }; + var x: { [R in K]: T[R] }; +} + +function f11() { + var x: { [P in keyof T]: T[P] }; + var x: { [P in keyof T]?: T[P] }; // Error + var x: { readonly [P in keyof T]: T[P] }; // Error + var x: { readonly [P in keyof T]?: T[P] }; // Error +} + +function f12() { + var x: { [P in keyof T]: T[P] }; + var x: { [P in keyof T]: T[P][] }; // Error } //// [mappedTypeErrors.js] @@ -73,21 +80,25 @@ function f3(x) { function f4(x) { var y; } +// Type identity checking +function f10() { + var x; + var x; + var x; +} +function f11() { + var x; + var x; // Error + var x; // Error + var x; // Error +} +function f12() { + var x; + var x; // Error +} //// [mappedTypeErrors.d.ts] -declare type Partial = { - [P in keyof T]?: T[P]; -}; -declare type Readonly = { - readonly [P in keyof T]: T[P]; -}; -declare type Pick = { - [P in K]: T[P]; -}; -declare type Record = { - [_ in K]: T; -}; interface Shape { name: string; width: number; @@ -119,3 +130,6 @@ declare function f1(x: T): void; declare function f2(x: T): void; declare function f3(x: T): void; declare function f4(x: T): void; +declare function f10(): void; +declare function f11(): void; +declare function f12(): void; diff --git a/tests/baselines/reference/mappedTypes2.js b/tests/baselines/reference/mappedTypes2.js index 8796244c390..25bb3fb6ded 100644 --- a/tests/baselines/reference/mappedTypes2.js +++ b/tests/baselines/reference/mappedTypes2.js @@ -1,19 +1,14 @@ //// [mappedTypes2.ts] -type Partial = { - [P in keyof T]?: T[P]; -}; - -type Readonly = { - readonly [P in keyof T]: T[P]; -}; - -type Pick = { - [P in K]: T[P]; -} - -type Record = { - [_ in K]: T; +function verifyLibTypes() { + var x1: Partial; + var x1: { [P in keyof T]?: T[P] }; + var x2: Readonly; + var x2: { readonly [P in keyof T]: T[P] }; + var x3: Pick; + var x3: { [P in K]: T[P] }; + var x4: Record; + var x4: { [P in K]: U }; } type Proxy = { @@ -95,6 +90,16 @@ function f6(shape: DeepReadonly) { } //// [mappedTypes2.js] +function verifyLibTypes() { + var x1; + var x1; + var x2; + var x2; + var x3; + var x3; + var x4; + var x4; +} function f0(s1, s2) { assign(s1, { name: "circle" }); assign(s2, { width: 10, height: 20 }); @@ -129,18 +134,7 @@ function f6(shape) { //// [mappedTypes2.d.ts] -declare type Partial = { - [P in keyof T]?: T[P]; -}; -declare type Readonly = { - readonly [P in keyof T]: T[P]; -}; -declare type Pick = { - [P in K]: T[P]; -}; -declare type Record = { - [_ in K]: T; -}; +declare function verifyLibTypes(): void; declare type Proxy = { get(): T; set(value: T): void; diff --git a/tests/baselines/reference/mappedTypes2.symbols b/tests/baselines/reference/mappedTypes2.symbols index bc823ed0081..a610658869e 100644 --- a/tests/baselines/reference/mappedTypes2.symbols +++ b/tests/baselines/reference/mappedTypes2.symbols @@ -1,331 +1,340 @@ === tests/cases/conformance/types/mapped/mappedTypes2.ts === -type Partial = { ->Partial : Symbol(Partial, Decl(mappedTypes2.ts, 0, 0)) ->T : Symbol(T, Decl(mappedTypes2.ts, 1, 13)) +function verifyLibTypes() { +>verifyLibTypes : Symbol(verifyLibTypes, Decl(mappedTypes2.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) +>K : Symbol(K, Decl(mappedTypes2.ts, 1, 26)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) +>U : Symbol(U, Decl(mappedTypes2.ts, 1, 45)) - [P in keyof T]?: T[P]; ->P : Symbol(P, Decl(mappedTypes2.ts, 2, 5)) ->T : Symbol(T, Decl(mappedTypes2.ts, 1, 13)) ->T : Symbol(T, Decl(mappedTypes2.ts, 1, 13)) ->P : Symbol(P, Decl(mappedTypes2.ts, 2, 5)) + var x1: Partial; +>x1 : Symbol(x1, Decl(mappedTypes2.ts, 2, 7), Decl(mappedTypes2.ts, 3, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) -}; + var x1: { [P in keyof T]?: T[P] }; +>x1 : Symbol(x1, Decl(mappedTypes2.ts, 2, 7), Decl(mappedTypes2.ts, 3, 7)) +>P : Symbol(P, Decl(mappedTypes2.ts, 3, 15)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) +>P : Symbol(P, Decl(mappedTypes2.ts, 3, 15)) -type Readonly = { ->Readonly : Symbol(Readonly, Decl(mappedTypes2.ts, 3, 2)) ->T : Symbol(T, Decl(mappedTypes2.ts, 5, 14)) + var x2: Readonly; +>x2 : Symbol(x2, Decl(mappedTypes2.ts, 4, 7), Decl(mappedTypes2.ts, 5, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) - readonly [P in keyof T]: T[P]; ->P : Symbol(P, Decl(mappedTypes2.ts, 6, 14)) ->T : Symbol(T, Decl(mappedTypes2.ts, 5, 14)) ->T : Symbol(T, Decl(mappedTypes2.ts, 5, 14)) ->P : Symbol(P, Decl(mappedTypes2.ts, 6, 14)) + var x2: { readonly [P in keyof T]: T[P] }; +>x2 : Symbol(x2, Decl(mappedTypes2.ts, 4, 7), Decl(mappedTypes2.ts, 5, 7)) +>P : Symbol(P, Decl(mappedTypes2.ts, 5, 24)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) +>P : Symbol(P, Decl(mappedTypes2.ts, 5, 24)) -}; + var x3: Pick; +>x3 : Symbol(x3, Decl(mappedTypes2.ts, 6, 7), Decl(mappedTypes2.ts, 7, 7)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) +>K : Symbol(K, Decl(mappedTypes2.ts, 1, 26)) -type Pick = { ->Pick : Symbol(Pick, Decl(mappedTypes2.ts, 7, 2)) ->T : Symbol(T, Decl(mappedTypes2.ts, 9, 10)) ->K : Symbol(K, Decl(mappedTypes2.ts, 9, 12)) ->T : Symbol(T, Decl(mappedTypes2.ts, 9, 10)) + var x3: { [P in K]: T[P] }; +>x3 : Symbol(x3, Decl(mappedTypes2.ts, 6, 7), Decl(mappedTypes2.ts, 7, 7)) +>P : Symbol(P, Decl(mappedTypes2.ts, 7, 15)) +>K : Symbol(K, Decl(mappedTypes2.ts, 1, 26)) +>T : Symbol(T, Decl(mappedTypes2.ts, 1, 24)) +>P : Symbol(P, Decl(mappedTypes2.ts, 7, 15)) - [P in K]: T[P]; ->P : Symbol(P, Decl(mappedTypes2.ts, 10, 5)) ->K : Symbol(K, Decl(mappedTypes2.ts, 9, 12)) ->T : Symbol(T, Decl(mappedTypes2.ts, 9, 10)) ->P : Symbol(P, Decl(mappedTypes2.ts, 10, 5)) -} + var x4: Record; +>x4 : Symbol(x4, Decl(mappedTypes2.ts, 8, 7), Decl(mappedTypes2.ts, 9, 7)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(mappedTypes2.ts, 1, 26)) +>U : Symbol(U, Decl(mappedTypes2.ts, 1, 45)) -type Record = { ->Record : Symbol(Record, Decl(mappedTypes2.ts, 11, 1)) ->K : Symbol(K, Decl(mappedTypes2.ts, 13, 12)) ->T : Symbol(T, Decl(mappedTypes2.ts, 13, 38)) - - [_ in K]: T; ->_ : Symbol(_, Decl(mappedTypes2.ts, 14, 5)) ->K : Symbol(K, Decl(mappedTypes2.ts, 13, 12)) ->T : Symbol(T, Decl(mappedTypes2.ts, 13, 38)) + var x4: { [P in K]: U }; +>x4 : Symbol(x4, Decl(mappedTypes2.ts, 8, 7), Decl(mappedTypes2.ts, 9, 7)) +>P : Symbol(P, Decl(mappedTypes2.ts, 9, 15)) +>K : Symbol(K, Decl(mappedTypes2.ts, 1, 26)) +>U : Symbol(U, Decl(mappedTypes2.ts, 1, 45)) } type Proxy = { ->Proxy : Symbol(Proxy, Decl(mappedTypes2.ts, 15, 1)) ->T : Symbol(T, Decl(mappedTypes2.ts, 17, 11)) +>Proxy : Symbol(Proxy, Decl(mappedTypes2.ts, 10, 1)) +>T : Symbol(T, Decl(mappedTypes2.ts, 12, 11)) get(): T; ->get : Symbol(get, Decl(mappedTypes2.ts, 17, 17)) ->T : Symbol(T, Decl(mappedTypes2.ts, 17, 11)) +>get : Symbol(get, Decl(mappedTypes2.ts, 12, 17)) +>T : Symbol(T, Decl(mappedTypes2.ts, 12, 11)) set(value: T): void; ->set : Symbol(set, Decl(mappedTypes2.ts, 18, 13)) ->value : Symbol(value, Decl(mappedTypes2.ts, 19, 8)) ->T : Symbol(T, Decl(mappedTypes2.ts, 17, 11)) +>set : Symbol(set, Decl(mappedTypes2.ts, 13, 13)) +>value : Symbol(value, Decl(mappedTypes2.ts, 14, 8)) +>T : Symbol(T, Decl(mappedTypes2.ts, 12, 11)) } type Proxify = { ->Proxify : Symbol(Proxify, Decl(mappedTypes2.ts, 20, 1)) ->T : Symbol(T, Decl(mappedTypes2.ts, 22, 13)) +>Proxify : Symbol(Proxify, Decl(mappedTypes2.ts, 15, 1)) +>T : Symbol(T, Decl(mappedTypes2.ts, 17, 13)) [P in keyof T]: Proxy; ->P : Symbol(P, Decl(mappedTypes2.ts, 23, 5)) ->T : Symbol(T, Decl(mappedTypes2.ts, 22, 13)) ->Proxy : Symbol(Proxy, Decl(mappedTypes2.ts, 15, 1)) ->T : Symbol(T, Decl(mappedTypes2.ts, 22, 13)) ->P : Symbol(P, Decl(mappedTypes2.ts, 23, 5)) +>P : Symbol(P, Decl(mappedTypes2.ts, 18, 5)) +>T : Symbol(T, Decl(mappedTypes2.ts, 17, 13)) +>Proxy : Symbol(Proxy, Decl(mappedTypes2.ts, 10, 1)) +>T : Symbol(T, Decl(mappedTypes2.ts, 17, 13)) +>P : Symbol(P, Decl(mappedTypes2.ts, 18, 5)) } type DeepReadonly = { ->DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 24, 1)) ->T : Symbol(T, Decl(mappedTypes2.ts, 26, 18)) +>DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 19, 1)) +>T : Symbol(T, Decl(mappedTypes2.ts, 21, 18)) readonly [P in keyof T]: DeepReadonly; ->P : Symbol(P, Decl(mappedTypes2.ts, 27, 14)) ->T : Symbol(T, Decl(mappedTypes2.ts, 26, 18)) ->DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 24, 1)) ->T : Symbol(T, Decl(mappedTypes2.ts, 26, 18)) ->P : Symbol(P, Decl(mappedTypes2.ts, 27, 14)) +>P : Symbol(P, Decl(mappedTypes2.ts, 22, 14)) +>T : Symbol(T, Decl(mappedTypes2.ts, 21, 18)) +>DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 19, 1)) +>T : Symbol(T, Decl(mappedTypes2.ts, 21, 18)) +>P : Symbol(P, Decl(mappedTypes2.ts, 22, 14)) }; declare function assign(obj: T, props: Partial): void; ->assign : Symbol(assign, Decl(mappedTypes2.ts, 28, 2)) ->T : Symbol(T, Decl(mappedTypes2.ts, 30, 24)) ->obj : Symbol(obj, Decl(mappedTypes2.ts, 30, 27)) ->T : Symbol(T, Decl(mappedTypes2.ts, 30, 24)) ->props : Symbol(props, Decl(mappedTypes2.ts, 30, 34)) ->Partial : Symbol(Partial, Decl(mappedTypes2.ts, 0, 0)) ->T : Symbol(T, Decl(mappedTypes2.ts, 30, 24)) +>assign : Symbol(assign, Decl(mappedTypes2.ts, 23, 2)) +>T : Symbol(T, Decl(mappedTypes2.ts, 25, 24)) +>obj : Symbol(obj, Decl(mappedTypes2.ts, 25, 27)) +>T : Symbol(T, Decl(mappedTypes2.ts, 25, 24)) +>props : Symbol(props, Decl(mappedTypes2.ts, 25, 34)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes2.ts, 25, 24)) declare function freeze(obj: T): Readonly; ->freeze : Symbol(freeze, Decl(mappedTypes2.ts, 30, 60)) ->T : Symbol(T, Decl(mappedTypes2.ts, 31, 24)) ->obj : Symbol(obj, Decl(mappedTypes2.ts, 31, 27)) ->T : Symbol(T, Decl(mappedTypes2.ts, 31, 24)) ->Readonly : Symbol(Readonly, Decl(mappedTypes2.ts, 3, 2)) ->T : Symbol(T, Decl(mappedTypes2.ts, 31, 24)) +>freeze : Symbol(freeze, Decl(mappedTypes2.ts, 25, 60)) +>T : Symbol(T, Decl(mappedTypes2.ts, 26, 24)) +>obj : Symbol(obj, Decl(mappedTypes2.ts, 26, 27)) +>T : Symbol(T, Decl(mappedTypes2.ts, 26, 24)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes2.ts, 26, 24)) declare function pick(obj: T, ...keys: K[]): Pick; ->pick : Symbol(pick, Decl(mappedTypes2.ts, 31, 48)) ->T : Symbol(T, Decl(mappedTypes2.ts, 32, 22)) ->K : Symbol(K, Decl(mappedTypes2.ts, 32, 24)) ->T : Symbol(T, Decl(mappedTypes2.ts, 32, 22)) ->obj : Symbol(obj, Decl(mappedTypes2.ts, 32, 44)) ->T : Symbol(T, Decl(mappedTypes2.ts, 32, 22)) ->keys : Symbol(keys, Decl(mappedTypes2.ts, 32, 51)) ->K : Symbol(K, Decl(mappedTypes2.ts, 32, 24)) ->Pick : Symbol(Pick, Decl(mappedTypes2.ts, 7, 2)) ->T : Symbol(T, Decl(mappedTypes2.ts, 32, 22)) ->K : Symbol(K, Decl(mappedTypes2.ts, 32, 24)) +>pick : Symbol(pick, Decl(mappedTypes2.ts, 26, 48)) +>T : Symbol(T, Decl(mappedTypes2.ts, 27, 22)) +>K : Symbol(K, Decl(mappedTypes2.ts, 27, 24)) +>T : Symbol(T, Decl(mappedTypes2.ts, 27, 22)) +>obj : Symbol(obj, Decl(mappedTypes2.ts, 27, 44)) +>T : Symbol(T, Decl(mappedTypes2.ts, 27, 22)) +>keys : Symbol(keys, Decl(mappedTypes2.ts, 27, 51)) +>K : Symbol(K, Decl(mappedTypes2.ts, 27, 24)) +>Pick : Symbol(Pick, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes2.ts, 27, 22)) +>K : Symbol(K, Decl(mappedTypes2.ts, 27, 24)) declare function mapObject(obj: Record, f: (x: T) => U): Record; ->mapObject : Symbol(mapObject, Decl(mappedTypes2.ts, 32, 78)) ->K : Symbol(K, Decl(mappedTypes2.ts, 33, 27)) ->T : Symbol(T, Decl(mappedTypes2.ts, 33, 53)) ->U : Symbol(U, Decl(mappedTypes2.ts, 33, 56)) ->obj : Symbol(obj, Decl(mappedTypes2.ts, 33, 60)) ->Record : Symbol(Record, Decl(mappedTypes2.ts, 11, 1)) ->K : Symbol(K, Decl(mappedTypes2.ts, 33, 27)) ->T : Symbol(T, Decl(mappedTypes2.ts, 33, 53)) ->f : Symbol(f, Decl(mappedTypes2.ts, 33, 78)) ->x : Symbol(x, Decl(mappedTypes2.ts, 33, 83)) ->T : Symbol(T, Decl(mappedTypes2.ts, 33, 53)) ->U : Symbol(U, Decl(mappedTypes2.ts, 33, 56)) ->Record : Symbol(Record, Decl(mappedTypes2.ts, 11, 1)) ->K : Symbol(K, Decl(mappedTypes2.ts, 33, 27)) ->U : Symbol(U, Decl(mappedTypes2.ts, 33, 56)) +>mapObject : Symbol(mapObject, Decl(mappedTypes2.ts, 27, 78)) +>K : Symbol(K, Decl(mappedTypes2.ts, 28, 27)) +>T : Symbol(T, Decl(mappedTypes2.ts, 28, 53)) +>U : Symbol(U, Decl(mappedTypes2.ts, 28, 56)) +>obj : Symbol(obj, Decl(mappedTypes2.ts, 28, 60)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(mappedTypes2.ts, 28, 27)) +>T : Symbol(T, Decl(mappedTypes2.ts, 28, 53)) +>f : Symbol(f, Decl(mappedTypes2.ts, 28, 78)) +>x : Symbol(x, Decl(mappedTypes2.ts, 28, 83)) +>T : Symbol(T, Decl(mappedTypes2.ts, 28, 53)) +>U : Symbol(U, Decl(mappedTypes2.ts, 28, 56)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(mappedTypes2.ts, 28, 27)) +>U : Symbol(U, Decl(mappedTypes2.ts, 28, 56)) declare function proxify(obj: T): Proxify; ->proxify : Symbol(proxify, Decl(mappedTypes2.ts, 33, 109)) ->T : Symbol(T, Decl(mappedTypes2.ts, 34, 25)) ->obj : Symbol(obj, Decl(mappedTypes2.ts, 34, 28)) ->T : Symbol(T, Decl(mappedTypes2.ts, 34, 25)) ->Proxify : Symbol(Proxify, Decl(mappedTypes2.ts, 20, 1)) ->T : Symbol(T, Decl(mappedTypes2.ts, 34, 25)) +>proxify : Symbol(proxify, Decl(mappedTypes2.ts, 28, 109)) +>T : Symbol(T, Decl(mappedTypes2.ts, 29, 25)) +>obj : Symbol(obj, Decl(mappedTypes2.ts, 29, 28)) +>T : Symbol(T, Decl(mappedTypes2.ts, 29, 25)) +>Proxify : Symbol(Proxify, Decl(mappedTypes2.ts, 15, 1)) +>T : Symbol(T, Decl(mappedTypes2.ts, 29, 25)) interface Shape { ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) name: string; ->name : Symbol(Shape.name, Decl(mappedTypes2.ts, 36, 17)) +>name : Symbol(Shape.name, Decl(mappedTypes2.ts, 31, 17)) width: number; ->width : Symbol(Shape.width, Decl(mappedTypes2.ts, 37, 17)) +>width : Symbol(Shape.width, Decl(mappedTypes2.ts, 32, 17)) height: number; ->height : Symbol(Shape.height, Decl(mappedTypes2.ts, 38, 18)) +>height : Symbol(Shape.height, Decl(mappedTypes2.ts, 33, 18)) visible: boolean; ->visible : Symbol(Shape.visible, Decl(mappedTypes2.ts, 39, 19)) +>visible : Symbol(Shape.visible, Decl(mappedTypes2.ts, 34, 19)) } interface PartialShape { ->PartialShape : Symbol(PartialShape, Decl(mappedTypes2.ts, 41, 1)) +>PartialShape : Symbol(PartialShape, Decl(mappedTypes2.ts, 36, 1)) name?: string; ->name : Symbol(PartialShape.name, Decl(mappedTypes2.ts, 43, 24)) +>name : Symbol(PartialShape.name, Decl(mappedTypes2.ts, 38, 24)) width?: number; ->width : Symbol(PartialShape.width, Decl(mappedTypes2.ts, 44, 18)) +>width : Symbol(PartialShape.width, Decl(mappedTypes2.ts, 39, 18)) height?: number; ->height : Symbol(PartialShape.height, Decl(mappedTypes2.ts, 45, 19)) +>height : Symbol(PartialShape.height, Decl(mappedTypes2.ts, 40, 19)) visible?: boolean; ->visible : Symbol(PartialShape.visible, Decl(mappedTypes2.ts, 46, 20)) +>visible : Symbol(PartialShape.visible, Decl(mappedTypes2.ts, 41, 20)) } interface ReadonlyShape { ->ReadonlyShape : Symbol(ReadonlyShape, Decl(mappedTypes2.ts, 48, 1)) +>ReadonlyShape : Symbol(ReadonlyShape, Decl(mappedTypes2.ts, 43, 1)) readonly name: string; ->name : Symbol(ReadonlyShape.name, Decl(mappedTypes2.ts, 50, 25)) +>name : Symbol(ReadonlyShape.name, Decl(mappedTypes2.ts, 45, 25)) readonly width: number; ->width : Symbol(ReadonlyShape.width, Decl(mappedTypes2.ts, 51, 26)) +>width : Symbol(ReadonlyShape.width, Decl(mappedTypes2.ts, 46, 26)) readonly height: number; ->height : Symbol(ReadonlyShape.height, Decl(mappedTypes2.ts, 52, 27)) +>height : Symbol(ReadonlyShape.height, Decl(mappedTypes2.ts, 47, 27)) readonly visible: boolean; ->visible : Symbol(ReadonlyShape.visible, Decl(mappedTypes2.ts, 53, 28)) +>visible : Symbol(ReadonlyShape.visible, Decl(mappedTypes2.ts, 48, 28)) } function f0(s1: Shape, s2: Shape) { ->f0 : Symbol(f0, Decl(mappedTypes2.ts, 55, 1)) ->s1 : Symbol(s1, Decl(mappedTypes2.ts, 57, 12)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) ->s2 : Symbol(s2, Decl(mappedTypes2.ts, 57, 22)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>f0 : Symbol(f0, Decl(mappedTypes2.ts, 50, 1)) +>s1 : Symbol(s1, Decl(mappedTypes2.ts, 52, 12)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) +>s2 : Symbol(s2, Decl(mappedTypes2.ts, 52, 22)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) assign(s1, { name: "circle" }); ->assign : Symbol(assign, Decl(mappedTypes2.ts, 28, 2)) ->s1 : Symbol(s1, Decl(mappedTypes2.ts, 57, 12)) ->name : Symbol(name, Decl(mappedTypes2.ts, 58, 16)) +>assign : Symbol(assign, Decl(mappedTypes2.ts, 23, 2)) +>s1 : Symbol(s1, Decl(mappedTypes2.ts, 52, 12)) +>name : Symbol(name, Decl(mappedTypes2.ts, 53, 16)) assign(s2, { width: 10, height: 20 }); ->assign : Symbol(assign, Decl(mappedTypes2.ts, 28, 2)) ->s2 : Symbol(s2, Decl(mappedTypes2.ts, 57, 22)) ->width : Symbol(width, Decl(mappedTypes2.ts, 59, 16)) ->height : Symbol(height, Decl(mappedTypes2.ts, 59, 27)) +>assign : Symbol(assign, Decl(mappedTypes2.ts, 23, 2)) +>s2 : Symbol(s2, Decl(mappedTypes2.ts, 52, 22)) +>width : Symbol(width, Decl(mappedTypes2.ts, 54, 16)) +>height : Symbol(height, Decl(mappedTypes2.ts, 54, 27)) } function f1(shape: Shape) { ->f1 : Symbol(f1, Decl(mappedTypes2.ts, 60, 1)) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 62, 12)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>f1 : Symbol(f1, Decl(mappedTypes2.ts, 55, 1)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 57, 12)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) var frozen: ReadonlyShape; ->frozen : Symbol(frozen, Decl(mappedTypes2.ts, 63, 7), Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7)) ->ReadonlyShape : Symbol(ReadonlyShape, Decl(mappedTypes2.ts, 48, 1)) +>frozen : Symbol(frozen, Decl(mappedTypes2.ts, 58, 7), Decl(mappedTypes2.ts, 59, 7), Decl(mappedTypes2.ts, 60, 7)) +>ReadonlyShape : Symbol(ReadonlyShape, Decl(mappedTypes2.ts, 43, 1)) var frozen: Readonly; ->frozen : Symbol(frozen, Decl(mappedTypes2.ts, 63, 7), Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7)) ->Readonly : Symbol(Readonly, Decl(mappedTypes2.ts, 3, 2)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>frozen : Symbol(frozen, Decl(mappedTypes2.ts, 58, 7), Decl(mappedTypes2.ts, 59, 7), Decl(mappedTypes2.ts, 60, 7)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) var frozen = freeze(shape); ->frozen : Symbol(frozen, Decl(mappedTypes2.ts, 63, 7), Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7)) ->freeze : Symbol(freeze, Decl(mappedTypes2.ts, 30, 60)) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 62, 12)) +>frozen : Symbol(frozen, Decl(mappedTypes2.ts, 58, 7), Decl(mappedTypes2.ts, 59, 7), Decl(mappedTypes2.ts, 60, 7)) +>freeze : Symbol(freeze, Decl(mappedTypes2.ts, 25, 60)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 57, 12)) } function f2(shape: Shape) { ->f2 : Symbol(f2, Decl(mappedTypes2.ts, 66, 1)) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 68, 12)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>f2 : Symbol(f2, Decl(mappedTypes2.ts, 61, 1)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 63, 12)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) var partial: PartialShape; ->partial : Symbol(partial, Decl(mappedTypes2.ts, 69, 7), Decl(mappedTypes2.ts, 70, 7), Decl(mappedTypes2.ts, 71, 7)) ->PartialShape : Symbol(PartialShape, Decl(mappedTypes2.ts, 41, 1)) +>partial : Symbol(partial, Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7), Decl(mappedTypes2.ts, 66, 7)) +>PartialShape : Symbol(PartialShape, Decl(mappedTypes2.ts, 36, 1)) var partial: Partial; ->partial : Symbol(partial, Decl(mappedTypes2.ts, 69, 7), Decl(mappedTypes2.ts, 70, 7), Decl(mappedTypes2.ts, 71, 7)) ->Partial : Symbol(Partial, Decl(mappedTypes2.ts, 0, 0)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>partial : Symbol(partial, Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7), Decl(mappedTypes2.ts, 66, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) var partial: Partial = {}; ->partial : Symbol(partial, Decl(mappedTypes2.ts, 69, 7), Decl(mappedTypes2.ts, 70, 7), Decl(mappedTypes2.ts, 71, 7)) ->Partial : Symbol(Partial, Decl(mappedTypes2.ts, 0, 0)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>partial : Symbol(partial, Decl(mappedTypes2.ts, 64, 7), Decl(mappedTypes2.ts, 65, 7), Decl(mappedTypes2.ts, 66, 7)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) } function f3(shape: Shape) { ->f3 : Symbol(f3, Decl(mappedTypes2.ts, 72, 1)) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 74, 12)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>f3 : Symbol(f3, Decl(mappedTypes2.ts, 67, 1)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 69, 12)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) const x = pick(shape, "name", "visible"); // { name: string, visible: boolean } ->x : Symbol(x, Decl(mappedTypes2.ts, 75, 9)) ->pick : Symbol(pick, Decl(mappedTypes2.ts, 31, 48)) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 74, 12)) +>x : Symbol(x, Decl(mappedTypes2.ts, 70, 9)) +>pick : Symbol(pick, Decl(mappedTypes2.ts, 26, 48)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 69, 12)) } function f4() { ->f4 : Symbol(f4, Decl(mappedTypes2.ts, 76, 1)) +>f4 : Symbol(f4, Decl(mappedTypes2.ts, 71, 1)) const rec = { foo: "hello", bar: "world", baz: "bye" }; ->rec : Symbol(rec, Decl(mappedTypes2.ts, 79, 9)) ->foo : Symbol(foo, Decl(mappedTypes2.ts, 79, 17)) ->bar : Symbol(bar, Decl(mappedTypes2.ts, 79, 31)) ->baz : Symbol(baz, Decl(mappedTypes2.ts, 79, 45)) +>rec : Symbol(rec, Decl(mappedTypes2.ts, 74, 9)) +>foo : Symbol(foo, Decl(mappedTypes2.ts, 74, 17)) +>bar : Symbol(bar, Decl(mappedTypes2.ts, 74, 31)) +>baz : Symbol(baz, Decl(mappedTypes2.ts, 74, 45)) const lengths = mapObject(rec, s => s.length); // { foo: number, bar: number, baz: number } ->lengths : Symbol(lengths, Decl(mappedTypes2.ts, 80, 9)) ->mapObject : Symbol(mapObject, Decl(mappedTypes2.ts, 32, 78)) ->rec : Symbol(rec, Decl(mappedTypes2.ts, 79, 9)) ->s : Symbol(s, Decl(mappedTypes2.ts, 80, 34)) +>lengths : Symbol(lengths, Decl(mappedTypes2.ts, 75, 9)) +>mapObject : Symbol(mapObject, Decl(mappedTypes2.ts, 27, 78)) +>rec : Symbol(rec, Decl(mappedTypes2.ts, 74, 9)) +>s : Symbol(s, Decl(mappedTypes2.ts, 75, 34)) >s.length : Symbol(String.length, Decl(lib.d.ts, --, --)) ->s : Symbol(s, Decl(mappedTypes2.ts, 80, 34)) +>s : Symbol(s, Decl(mappedTypes2.ts, 75, 34)) >length : Symbol(String.length, Decl(lib.d.ts, --, --)) } function f5(shape: Shape) { ->f5 : Symbol(f5, Decl(mappedTypes2.ts, 81, 1)) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 83, 12)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>f5 : Symbol(f5, Decl(mappedTypes2.ts, 76, 1)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 78, 12)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) const p = proxify(shape); ->p : Symbol(p, Decl(mappedTypes2.ts, 84, 9)) ->proxify : Symbol(proxify, Decl(mappedTypes2.ts, 33, 109)) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 83, 12)) +>p : Symbol(p, Decl(mappedTypes2.ts, 79, 9)) +>proxify : Symbol(proxify, Decl(mappedTypes2.ts, 28, 109)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 78, 12)) let name = p.name.get(); ->name : Symbol(name, Decl(mappedTypes2.ts, 85, 7)) ->p.name.get : Symbol(get, Decl(mappedTypes2.ts, 17, 17)) +>name : Symbol(name, Decl(mappedTypes2.ts, 80, 7)) +>p.name.get : Symbol(get, Decl(mappedTypes2.ts, 12, 17)) >p.name : Symbol(name) ->p : Symbol(p, Decl(mappedTypes2.ts, 84, 9)) +>p : Symbol(p, Decl(mappedTypes2.ts, 79, 9)) >name : Symbol(name) ->get : Symbol(get, Decl(mappedTypes2.ts, 17, 17)) +>get : Symbol(get, Decl(mappedTypes2.ts, 12, 17)) p.visible.set(false); ->p.visible.set : Symbol(set, Decl(mappedTypes2.ts, 18, 13)) +>p.visible.set : Symbol(set, Decl(mappedTypes2.ts, 13, 13)) >p.visible : Symbol(visible) ->p : Symbol(p, Decl(mappedTypes2.ts, 84, 9)) +>p : Symbol(p, Decl(mappedTypes2.ts, 79, 9)) >visible : Symbol(visible) ->set : Symbol(set, Decl(mappedTypes2.ts, 18, 13)) +>set : Symbol(set, Decl(mappedTypes2.ts, 13, 13)) } function f6(shape: DeepReadonly) { ->f6 : Symbol(f6, Decl(mappedTypes2.ts, 87, 1)) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 89, 12)) ->DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 24, 1)) ->Shape : Symbol(Shape, Decl(mappedTypes2.ts, 34, 48)) +>f6 : Symbol(f6, Decl(mappedTypes2.ts, 82, 1)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 84, 12)) +>DeepReadonly : Symbol(DeepReadonly, Decl(mappedTypes2.ts, 19, 1)) +>Shape : Symbol(Shape, Decl(mappedTypes2.ts, 29, 48)) let name = shape.name; // DeepReadonly ->name : Symbol(name, Decl(mappedTypes2.ts, 90, 7)) +>name : Symbol(name, Decl(mappedTypes2.ts, 85, 7)) >shape.name : Symbol(name) ->shape : Symbol(shape, Decl(mappedTypes2.ts, 89, 12)) +>shape : Symbol(shape, Decl(mappedTypes2.ts, 84, 12)) >name : Symbol(name) let length = name.length; // DeepReadonly ->length : Symbol(length, Decl(mappedTypes2.ts, 91, 7)) +>length : Symbol(length, Decl(mappedTypes2.ts, 86, 7)) >name.length : Symbol(length) ->name : Symbol(name, Decl(mappedTypes2.ts, 90, 7)) +>name : Symbol(name, Decl(mappedTypes2.ts, 85, 7)) >length : Symbol(length) let toString = length.toString; // DeepReadonly<(radix?: number) => string> ->toString : Symbol(toString, Decl(mappedTypes2.ts, 92, 7)) +>toString : Symbol(toString, Decl(mappedTypes2.ts, 87, 7)) >length.toString : Symbol(toString) ->length : Symbol(length, Decl(mappedTypes2.ts, 91, 7)) +>length : Symbol(length, Decl(mappedTypes2.ts, 86, 7)) >toString : Symbol(toString) } diff --git a/tests/baselines/reference/mappedTypes2.types b/tests/baselines/reference/mappedTypes2.types index e3b67647993..8c487288a6f 100644 --- a/tests/baselines/reference/mappedTypes2.types +++ b/tests/baselines/reference/mappedTypes2.types @@ -1,51 +1,60 @@ === tests/cases/conformance/types/mapped/mappedTypes2.ts === -type Partial = { +function verifyLibTypes() { +>verifyLibTypes : () => void +>T : T +>K : K +>T : T +>U : U + + var x1: Partial; +>x1 : Partial >Partial : Partial >T : T - [P in keyof T]?: T[P]; + var x1: { [P in keyof T]?: T[P] }; +>x1 : Partial >P : P >T : T >T : T >P : P -}; - -type Readonly = { + var x2: Readonly; +>x2 : Readonly >Readonly : Readonly >T : T - readonly [P in keyof T]: T[P]; + var x2: { readonly [P in keyof T]: T[P] }; +>x2 : Readonly >P : P >T : T >T : T >P : P -}; - -type Pick = { + var x3: Pick; +>x3 : Pick >Pick : Pick >T : T >K : K ->T : T - [P in K]: T[P]; + var x3: { [P in K]: T[P] }; +>x3 : Pick >P : P >K : K >T : T >P : P -} -type Record = { + var x4: Record; +>x4 : Record >Record : Record >K : K ->T : T +>U : U - [_ in K]: T; ->_ : _ + var x4: { [P in K]: U }; +>x4 : Record +>P : P >K : K ->T : T +>U : U } type Proxy = { diff --git a/tests/baselines/reference/typePredicateStructuralMatch.js b/tests/baselines/reference/typePredicateStructuralMatch.js new file mode 100644 index 00000000000..682fac5536e --- /dev/null +++ b/tests/baselines/reference/typePredicateStructuralMatch.js @@ -0,0 +1,46 @@ +//// [typePredicateStructuralMatch.ts] +// Repro from #12235 + +getResults1([]); +getResults1({data: []}); + +getResults2([]); +getResults2({data: []}); + +type Result = { value: string }; +type Results = Result[]; + +function isResponseInData(value: T | { data: T}): value is { data: T } { + return value.hasOwnProperty('data'); +} + +function getResults1(value: Results | { data: Results }): Results { + return isResponseInData(value) ? value.data : value; +} + +function isPlainResponse(value: T | { data: T}): value is T { + return !value.hasOwnProperty('data'); +} + +function getResults2(value: Results | { data: Results }): Results { + return isPlainResponse(value) ? value : value.data; +} + +//// [typePredicateStructuralMatch.js] +// Repro from #12235 +getResults1([]); +getResults1({ data: [] }); +getResults2([]); +getResults2({ data: [] }); +function isResponseInData(value) { + return value.hasOwnProperty('data'); +} +function getResults1(value) { + return isResponseInData(value) ? value.data : value; +} +function isPlainResponse(value) { + return !value.hasOwnProperty('data'); +} +function getResults2(value) { + return isPlainResponse(value) ? value : value.data; +} diff --git a/tests/baselines/reference/typePredicateStructuralMatch.symbols b/tests/baselines/reference/typePredicateStructuralMatch.symbols new file mode 100644 index 00000000000..59d548d4bfc --- /dev/null +++ b/tests/baselines/reference/typePredicateStructuralMatch.symbols @@ -0,0 +1,91 @@ +=== tests/cases/compiler/typePredicateStructuralMatch.ts === +// Repro from #12235 + +getResults1([]); +>getResults1 : Symbol(getResults1, Decl(typePredicateStructuralMatch.ts, 13, 1)) + +getResults1({data: []}); +>getResults1 : Symbol(getResults1, Decl(typePredicateStructuralMatch.ts, 13, 1)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 3, 13)) + +getResults2([]); +>getResults2 : Symbol(getResults2, Decl(typePredicateStructuralMatch.ts, 21, 1)) + +getResults2({data: []}); +>getResults2 : Symbol(getResults2, Decl(typePredicateStructuralMatch.ts, 21, 1)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 6, 13)) + +type Result = { value: string }; +>Result : Symbol(Result, Decl(typePredicateStructuralMatch.ts, 6, 24)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 8, 15)) + +type Results = Result[]; +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>Result : Symbol(Result, Decl(typePredicateStructuralMatch.ts, 6, 24)) + +function isResponseInData(value: T | { data: T}): value is { data: T } { +>isResponseInData : Symbol(isResponseInData, Decl(typePredicateStructuralMatch.ts, 9, 24)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 11, 26)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 11, 29)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 11, 26)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 11, 41)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 11, 26)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 11, 29)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 11, 63)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 11, 26)) + + return value.hasOwnProperty('data'); +>value.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.d.ts, --, --)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 11, 29)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.d.ts, --, --)) +} + +function getResults1(value: Results | { data: Results }): Results { +>getResults1 : Symbol(getResults1, Decl(typePredicateStructuralMatch.ts, 13, 1)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 15, 21)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 15, 39)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) + + return isResponseInData(value) ? value.data : value; +>isResponseInData : Symbol(isResponseInData, Decl(typePredicateStructuralMatch.ts, 9, 24)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 15, 21)) +>value.data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 15, 39)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 15, 21)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 15, 39)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 15, 21)) +} + +function isPlainResponse(value: T | { data: T}): value is T { +>isPlainResponse : Symbol(isPlainResponse, Decl(typePredicateStructuralMatch.ts, 17, 1)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 19, 25)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 19, 28)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 19, 25)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 19, 40)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 19, 25)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 19, 28)) +>T : Symbol(T, Decl(typePredicateStructuralMatch.ts, 19, 25)) + + return !value.hasOwnProperty('data'); +>value.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.d.ts, --, --)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 19, 28)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.d.ts, --, --)) +} + +function getResults2(value: Results | { data: Results }): Results { +>getResults2 : Symbol(getResults2, Decl(typePredicateStructuralMatch.ts, 21, 1)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 23, 21)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 23, 39)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) +>Results : Symbol(Results, Decl(typePredicateStructuralMatch.ts, 8, 32)) + + return isPlainResponse(value) ? value : value.data; +>isPlainResponse : Symbol(isPlainResponse, Decl(typePredicateStructuralMatch.ts, 17, 1)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 23, 21)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 23, 21)) +>value.data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 23, 39)) +>value : Symbol(value, Decl(typePredicateStructuralMatch.ts, 23, 21)) +>data : Symbol(data, Decl(typePredicateStructuralMatch.ts, 23, 39)) +} diff --git a/tests/baselines/reference/typePredicateStructuralMatch.types b/tests/baselines/reference/typePredicateStructuralMatch.types new file mode 100644 index 00000000000..9f7a129da15 --- /dev/null +++ b/tests/baselines/reference/typePredicateStructuralMatch.types @@ -0,0 +1,110 @@ +=== tests/cases/compiler/typePredicateStructuralMatch.ts === +// Repro from #12235 + +getResults1([]); +>getResults1([]) : Result[] +>getResults1 : (value: Result[] | { data: Result[]; }) => Result[] +>[] : undefined[] + +getResults1({data: []}); +>getResults1({data: []}) : Result[] +>getResults1 : (value: Result[] | { data: Result[]; }) => Result[] +>{data: []} : { data: undefined[]; } +>data : undefined[] +>[] : undefined[] + +getResults2([]); +>getResults2([]) : Result[] +>getResults2 : (value: Result[] | { data: Result[]; }) => Result[] +>[] : undefined[] + +getResults2({data: []}); +>getResults2({data: []}) : Result[] +>getResults2 : (value: Result[] | { data: Result[]; }) => Result[] +>{data: []} : { data: undefined[]; } +>data : undefined[] +>[] : undefined[] + +type Result = { value: string }; +>Result : Result +>value : string + +type Results = Result[]; +>Results : Result[] +>Result : Result + +function isResponseInData(value: T | { data: T}): value is { data: T } { +>isResponseInData : (value: T | { data: T; }) => value is { data: T; } +>T : T +>value : T | { data: T; } +>T : T +>data : T +>T : T +>value : any +>data : T +>T : T + + return value.hasOwnProperty('data'); +>value.hasOwnProperty('data') : boolean +>value.hasOwnProperty : (v: string) => boolean +>value : T | { data: T; } +>hasOwnProperty : (v: string) => boolean +>'data' : "data" +} + +function getResults1(value: Results | { data: Results }): Results { +>getResults1 : (value: Result[] | { data: Result[]; }) => Result[] +>value : Result[] | { data: Result[]; } +>Results : Result[] +>data : Result[] +>Results : Result[] +>Results : Result[] + + return isResponseInData(value) ? value.data : value; +>isResponseInData(value) ? value.data : value : Result[] +>isResponseInData(value) : boolean +>isResponseInData : (value: T | { data: T; }) => value is { data: T; } +>value : Result[] | { data: Result[]; } +>value.data : Result[] +>value : { data: Result[]; } +>data : Result[] +>value : Result[] +} + +function isPlainResponse(value: T | { data: T}): value is T { +>isPlainResponse : (value: T | { data: T; }) => value is T +>T : T +>value : T | { data: T; } +>T : T +>data : T +>T : T +>value : any +>T : T + + return !value.hasOwnProperty('data'); +>!value.hasOwnProperty('data') : boolean +>value.hasOwnProperty('data') : boolean +>value.hasOwnProperty : (v: string) => boolean +>value : T | { data: T; } +>hasOwnProperty : (v: string) => boolean +>'data' : "data" +} + +function getResults2(value: Results | { data: Results }): Results { +>getResults2 : (value: Result[] | { data: Result[]; }) => Result[] +>value : Result[] | { data: Result[]; } +>Results : Result[] +>data : Result[] +>Results : Result[] +>Results : Result[] + + return isPlainResponse(value) ? value : value.data; +>isPlainResponse(value) ? value : value.data : Result[] +>isPlainResponse(value) : boolean +>isPlainResponse : (value: T | { data: T; }) => value is T +>value : Result[] | { data: Result[]; } +>value : Result[] +>value.data : Result[] +>value : { data: Result[]; } +>data : Result[] +} diff --git a/tests/cases/compiler/typePredicateStructuralMatch.ts b/tests/cases/compiler/typePredicateStructuralMatch.ts new file mode 100644 index 00000000000..690e5f62b27 --- /dev/null +++ b/tests/cases/compiler/typePredicateStructuralMatch.ts @@ -0,0 +1,26 @@ +// Repro from #12235 + +getResults1([]); +getResults1({data: []}); + +getResults2([]); +getResults2({data: []}); + +type Result = { value: string }; +type Results = Result[]; + +function isResponseInData(value: T | { data: T}): value is { data: T } { + return value.hasOwnProperty('data'); +} + +function getResults1(value: Results | { data: Results }): Results { + return isResponseInData(value) ? value.data : value; +} + +function isPlainResponse(value: T | { data: T}): value is T { + return !value.hasOwnProperty('data'); +} + +function getResults2(value: Results | { data: Results }): Results { + return isPlainResponse(value) ? value : value.data; +} \ No newline at end of file diff --git a/tests/cases/conformance/types/mapped/mappedTypeErrors.ts b/tests/cases/conformance/types/mapped/mappedTypeErrors.ts index fce80872185..c507bf64a6e 100644 --- a/tests/cases/conformance/types/mapped/mappedTypeErrors.ts +++ b/tests/cases/conformance/types/mapped/mappedTypeErrors.ts @@ -1,22 +1,6 @@ // @strictNullChecks: true // @declaration: true -type Partial = { - [P in keyof T]?: T[P]; -}; - -type Readonly = { - readonly [P in keyof T]: T[P]; -}; - -type Pick = { - [P in K]: T[P]; -} - -type Record = { - [_ in K]: T; -} - interface Shape { name: string; width: number; @@ -33,6 +17,8 @@ interface Point { y: number; } +// Constraint checking + type T00 = { [P in P]: string }; // Error type T01 = { [P in Date]: number }; // Error type T02 = Record; // Error @@ -59,4 +45,25 @@ function f3(x: T) { function f4(x: T) { let y: Pick; +} + +// Type identity checking + +function f10() { + type K = keyof T; + var x: { [P in keyof T]: T[P] }; + var x: { [Q in keyof T]: T[Q] }; + var x: { [R in K]: T[R] }; +} + +function f11() { + var x: { [P in keyof T]: T[P] }; + var x: { [P in keyof T]?: T[P] }; // Error + var x: { readonly [P in keyof T]: T[P] }; // Error + var x: { readonly [P in keyof T]?: T[P] }; // Error +} + +function f12() { + var x: { [P in keyof T]: T[P] }; + var x: { [P in keyof T]: T[P][] }; // Error } \ No newline at end of file diff --git a/tests/cases/conformance/types/mapped/mappedTypes2.ts b/tests/cases/conformance/types/mapped/mappedTypes2.ts index 84bffe2ea17..7f5841410e4 100644 --- a/tests/cases/conformance/types/mapped/mappedTypes2.ts +++ b/tests/cases/conformance/types/mapped/mappedTypes2.ts @@ -1,20 +1,15 @@ // @strictNullChecks: true // @declaration: true -type Partial = { - [P in keyof T]?: T[P]; -}; - -type Readonly = { - readonly [P in keyof T]: T[P]; -}; - -type Pick = { - [P in K]: T[P]; -} - -type Record = { - [_ in K]: T; +function verifyLibTypes() { + var x1: Partial; + var x1: { [P in keyof T]?: T[P] }; + var x2: Readonly; + var x2: { readonly [P in keyof T]: T[P] }; + var x3: Pick; + var x3: { [P in K]: T[P] }; + var x4: Record; + var x4: { [P in K]: U }; } type Proxy = {