diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e6c34fd434e52..84f6b40192b93 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15598,6 +15598,13 @@ namespace ts { return result; } + function getInstanceOfAliasOrReferenceWithMarker(input: Type, typeArguments: readonly Type[]) { + const s = input.aliasSymbol ? getTypeAliasInstantiation(input.aliasSymbol, typeArguments) : createTypeReference((input).target, typeArguments); + if (s.aliasSymbol) s.aliasTypeArgumentsContainsMarker = true; + else (s).objectFlags |= ObjectFlags.MarkerType; + return s; + } + function structuredTypeRelatedTo(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState): Ternary { const flags = source.flags & target.flags; if (relation === identityRelation && !(flags & TypeFlags.Object)) { @@ -15652,6 +15659,57 @@ namespace ts { } } + // If a more _general_ version of the source and target are being compared, consider them related with assumptions + // eg, if { x: Q } and { x: Q, y: A } are being compared and we're about to look at { x: Q' } and { x: Q', y: A } where Q' + // is some specialization or subtype of Q + // This is difficult to detect generally, so we scan for prior comparisons of the same instantiated type, and match up matching + // type arguments into sets to create a canonicalization based on those matches + if (relation !== identityRelation && ((source.aliasSymbol && !source.aliasTypeArgumentsContainsMarker && source.aliasTypeArguments) || (getObjectFlags(source) & ObjectFlags.Reference && !!getTypeArguments(source).length && !(getObjectFlags(source) & ObjectFlags.MarkerType))) && + ((target.aliasSymbol && !target.aliasTypeArgumentsContainsMarker && target.aliasTypeArguments) || (getObjectFlags(target) & ObjectFlags.Reference && !!getTypeArguments(target).length && !(getObjectFlags(target) & ObjectFlags.MarkerType)))) { + if (source.aliasSymbol || target.aliasSymbol || (source).target !== (target).target) { // ensure like symbols are just handled by standard variance analysis + const sourceTypeArguments = source.aliasTypeArguments || getTypeArguments(source); + const sourceHasMarker = some(sourceTypeArguments, a => a === markerOtherType); + const targetTypeArguments = target.aliasTypeArguments || getTypeArguments(target); + const targetHasMarker = some(targetTypeArguments, a => a === markerOtherType); + // We're using `markerOtherType` as an existential, so we can't use it again if it's already in use, + // as we'd get spurious equivalencies - we'd need to use a second existential type, and once we're doing + // that we lose a lot of the benefit of canonicalizing back to a single-existential comparison, since then + // we'd need to manufacture new type identities for every new existential we make + // The above checks don't catch all cases this can occur, as they can only detect when the containing type + // was flagged during construction as containing a marker; however if a marker enters a type through instantiation + // we need to catch that here. + if (!sourceHasMarker && !targetHasMarker) { + const originalKey = getRelationKey(source, target, intersectionState, relation); + for (let i = 0; i < sourceTypeArguments.length; i++) { + for (let j = 0; j < targetTypeArguments.length; j++) { + if ((!(sourceTypeArguments[i].flags & TypeFlags.TypeParameter) && !isTypeAny(sourceTypeArguments[i]) && isTypeIdenticalTo(sourceTypeArguments[i], targetTypeArguments[j])) || + // Similarly, if we're comparing X to Z, X is assignable to Z trivially if X is assignable to Z + (!(sourceTypeArguments[i].flags & TypeFlags.TypeParameter) && isTypeAny(targetTypeArguments[j])) || + // Again, but for `X` vs `Z` + (isTypeAny(sourceTypeArguments[i]) && !(targetTypeArguments[j].flags & TypeFlags.TypeParameter))) { + const sourceClone = sourceTypeArguments.slice(); + sourceClone[i] = markerOtherType; + const s = getInstanceOfAliasOrReferenceWithMarker(source, sourceClone); + const targetClone = targetTypeArguments.slice(); + targetClone[j] = markerOtherType; + const t = getInstanceOfAliasOrReferenceWithMarker(target, targetClone); + // If the marker-instantiated form looks "the same" as the type we already have (eg, + // because we replace unconstrained generics with unconstrained generics), skip the check + // since we'll otherwise deliver a spurious `Maybe` result from the key _just_ set upon + // entry into `recursiveTypeRelatedTo` + if (getRelationKey(s, t, intersectionState, relation) !== originalKey) { + const result = isRelatedTo(s, t, /*reportErrors*/ false); + if (result) { + return result; + } + } + } + } + } + } + } + } + if (target.flags & TypeFlags.TypeParameter) { // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q]. if (getObjectFlags(source) & ObjectFlags.Mapped && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source))) { @@ -16835,7 +16893,7 @@ namespace ts { // In addition, this will also detect when an indexed access has been chained off of 5 or more times (which is essentially // the dual of the structural comparison), and likewise mark the type as deeply nested, potentially adding false positives // for finite but deeply expanding indexed accesses (eg, for `Q[P1][P2][P3][P4][P5]`). - function isDeeplyNestedType(type: Type, stack: Type[], depth: number): boolean { + function isDeeplyNestedType(type: Type, stack: Type[], depth: number, maxCount = 5): boolean { // We track all object types that have an associated symbol (representing the origin of the type) if (depth >= 5 && type.flags & TypeFlags.Object && !isObjectOrArrayLiteralType(type)) { const symbol = type.symbol; @@ -16845,7 +16903,7 @@ namespace ts { const t = stack[i]; if (t.flags & TypeFlags.Object && t.symbol === symbol) { count++; - if (count >= 5) return true; + if (count >= maxCount) return true; } } } @@ -17886,18 +17944,44 @@ namespace ts { } function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) { - let symbolStack: Symbol[]; + let sourceStack: Type[]; + let targetStack: Type[]; + let depth = 0; let visited: Map; let bivariant = false; let propagationType: Type; let inferencePriority = InferencePriority.MaxValue; let allowComplexConstraintInference = true; + let expandingFlags = ExpandingFlags.None; inferFromTypes(originalSource, originalTarget); function inferFromTypes(source: Type, target: Type): void { + const maxdepth = every(inferences, i => !!(length(i.candidates) || length(i.contraCandidates))) ? 1 : 5; // Expand up to 5 layers deep unless we've found an inference, in which case stop at 1 + const saveExpandingFlags = expandingFlags; + if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, depth, maxdepth)) expandingFlags |= ExpandingFlags.Source; + if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, depth, maxdepth)) expandingFlags |= ExpandingFlags.Target; + if (expandingFlags === ExpandingFlags.Both) { + expandingFlags = saveExpandingFlags; + return; + } + + if (!sourceStack) { + sourceStack = []; + targetStack = []; + } + sourceStack[depth] = source; + targetStack[depth] = target; + depth++; + inferFromTypesWorker(source, target); + depth--; + expandingFlags = saveExpandingFlags; + } + + function inferFromTypesWorker(source: Type, target: Type): void { if (!couldContainTypeVariables(target)) { return; } + if (source === wildcardType) { // We are inferring from an 'any' type. We want to infer this type for every type parameter // referenced in the target type, so we record it as the propagation type and infer from the @@ -18318,28 +18402,6 @@ namespace ts { } function inferFromObjectTypes(source: Type, target: Type) { - // If we are already processing another target type with the same associated symbol (such as - // an instantiation of the same generic type), we do not explore this target as it would yield - // no further inferences. We exclude the static side of classes from this check since it shares - // its symbol with the instance side which would lead to false positives. - const isNonConstructorObject = target.flags & TypeFlags.Object && - !(getObjectFlags(target) & ObjectFlags.Anonymous && target.symbol && target.symbol.flags & SymbolFlags.Class); - const symbol = isNonConstructorObject ? target.symbol : undefined; - if (symbol) { - if (contains(symbolStack, symbol)) { - inferencePriority = InferencePriority.Circularity; - return; - } - (symbolStack || (symbolStack = [])).push(symbol); - inferFromObjectTypesWorker(source, target); - symbolStack.pop(); - } - else { - inferFromObjectTypesWorker(source, target); - } - } - - function inferFromObjectTypesWorker(source: Type, target: Type) { if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && ( (source).target === (target).target || isArrayType(source) && isArrayType(target))) { // If source and target are references to the same generic type, infer from type arguments diff --git a/tests/baselines/reference/mappedTypeAliasSubstitutability.js b/tests/baselines/reference/mappedTypeAliasSubstitutability.js new file mode 100644 index 0000000000000..47e5f12755694 --- /dev/null +++ b/tests/baselines/reference/mappedTypeAliasSubstitutability.js @@ -0,0 +1,18 @@ +//// [mappedTypeAliasSubstitutability.ts] +// repro from https://github.com/microsoft/TypeScript/issues/31616 + +const v = { test: { smth: 5 } }; +type Field = { [K in A]: R }; +const f = (x: { [K in A]: Field } ): R => ({} as any); +const g = (x: Field>): R => ({} as any); +const r1 = f(v); // number +const r2 = g(v); // unknown + + +//// [mappedTypeAliasSubstitutability.js] +// repro from https://github.com/microsoft/TypeScript/issues/31616 +var v = { test: { smth: 5 } }; +var f = function (x) { return ({}); }; +var g = function (x) { return ({}); }; +var r1 = f(v); // number +var r2 = g(v); // unknown diff --git a/tests/baselines/reference/mappedTypeAliasSubstitutability.symbols b/tests/baselines/reference/mappedTypeAliasSubstitutability.symbols new file mode 100644 index 0000000000000..d39da570bfcf1 --- /dev/null +++ b/tests/baselines/reference/mappedTypeAliasSubstitutability.symbols @@ -0,0 +1,52 @@ +=== tests/cases/compiler/mappedTypeAliasSubstitutability.ts === +// repro from https://github.com/microsoft/TypeScript/issues/31616 + +const v = { test: { smth: 5 } }; +>v : Symbol(v, Decl(mappedTypeAliasSubstitutability.ts, 2, 5)) +>test : Symbol(test, Decl(mappedTypeAliasSubstitutability.ts, 2, 11)) +>smth : Symbol(smth, Decl(mappedTypeAliasSubstitutability.ts, 2, 19)) + +type Field = { [K in A]: R }; +>Field : Symbol(Field, Decl(mappedTypeAliasSubstitutability.ts, 2, 32)) +>A : Symbol(A, Decl(mappedTypeAliasSubstitutability.ts, 3, 11)) +>R : Symbol(R, Decl(mappedTypeAliasSubstitutability.ts, 3, 28)) +>K : Symbol(K, Decl(mappedTypeAliasSubstitutability.ts, 3, 37)) +>A : Symbol(A, Decl(mappedTypeAliasSubstitutability.ts, 3, 11)) +>R : Symbol(R, Decl(mappedTypeAliasSubstitutability.ts, 3, 28)) + +const f = (x: { [K in A]: Field } ): R => ({} as any); +>f : Symbol(f, Decl(mappedTypeAliasSubstitutability.ts, 4, 5)) +>A : Symbol(A, Decl(mappedTypeAliasSubstitutability.ts, 4, 11)) +>B : Symbol(B, Decl(mappedTypeAliasSubstitutability.ts, 4, 28)) +>R : Symbol(R, Decl(mappedTypeAliasSubstitutability.ts, 4, 46)) +>x : Symbol(x, Decl(mappedTypeAliasSubstitutability.ts, 4, 50)) +>K : Symbol(K, Decl(mappedTypeAliasSubstitutability.ts, 4, 56)) +>A : Symbol(A, Decl(mappedTypeAliasSubstitutability.ts, 4, 11)) +>Field : Symbol(Field, Decl(mappedTypeAliasSubstitutability.ts, 2, 32)) +>B : Symbol(B, Decl(mappedTypeAliasSubstitutability.ts, 4, 28)) +>R : Symbol(R, Decl(mappedTypeAliasSubstitutability.ts, 4, 46)) +>R : Symbol(R, Decl(mappedTypeAliasSubstitutability.ts, 4, 46)) + +const g = (x: Field>): R => ({} as any); +>g : Symbol(g, Decl(mappedTypeAliasSubstitutability.ts, 5, 5)) +>A : Symbol(A, Decl(mappedTypeAliasSubstitutability.ts, 5, 11)) +>B : Symbol(B, Decl(mappedTypeAliasSubstitutability.ts, 5, 28)) +>R : Symbol(R, Decl(mappedTypeAliasSubstitutability.ts, 5, 46)) +>x : Symbol(x, Decl(mappedTypeAliasSubstitutability.ts, 5, 50)) +>Field : Symbol(Field, Decl(mappedTypeAliasSubstitutability.ts, 2, 32)) +>A : Symbol(A, Decl(mappedTypeAliasSubstitutability.ts, 5, 11)) +>Field : Symbol(Field, Decl(mappedTypeAliasSubstitutability.ts, 2, 32)) +>B : Symbol(B, Decl(mappedTypeAliasSubstitutability.ts, 5, 28)) +>R : Symbol(R, Decl(mappedTypeAliasSubstitutability.ts, 5, 46)) +>R : Symbol(R, Decl(mappedTypeAliasSubstitutability.ts, 5, 46)) + +const r1 = f(v); // number +>r1 : Symbol(r1, Decl(mappedTypeAliasSubstitutability.ts, 6, 5)) +>f : Symbol(f, Decl(mappedTypeAliasSubstitutability.ts, 4, 5)) +>v : Symbol(v, Decl(mappedTypeAliasSubstitutability.ts, 2, 5)) + +const r2 = g(v); // unknown +>r2 : Symbol(r2, Decl(mappedTypeAliasSubstitutability.ts, 7, 5)) +>g : Symbol(g, Decl(mappedTypeAliasSubstitutability.ts, 5, 5)) +>v : Symbol(v, Decl(mappedTypeAliasSubstitutability.ts, 2, 5)) + diff --git a/tests/baselines/reference/mappedTypeAliasSubstitutability.types b/tests/baselines/reference/mappedTypeAliasSubstitutability.types new file mode 100644 index 0000000000000..9c8373c7632af --- /dev/null +++ b/tests/baselines/reference/mappedTypeAliasSubstitutability.types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/mappedTypeAliasSubstitutability.ts === +// repro from https://github.com/microsoft/TypeScript/issues/31616 + +const v = { test: { smth: 5 } }; +>v : { test: { smth: number; }; } +>{ test: { smth: 5 } } : { test: { smth: number; }; } +>test : { smth: number; } +>{ smth: 5 } : { smth: number; } +>smth : number +>5 : 5 + +type Field = { [K in A]: R }; +>Field : Field + +const f = (x: { [K in A]: Field } ): R => ({} as any); +>f : (x: { [K in A]: Field; }) => R +>(x: { [K in A]: Field } ): R => ({} as any) : (x: { [K in A]: Field; }) => R +>x : { [K in A]: Field; } +>({} as any) : any +>{} as any : any +>{} : {} + +const g = (x: Field>): R => ({} as any); +>g : (x: Field>) => R +>(x: Field>): R => ({} as any) : (x: Field>) => R +>x : Field> +>({} as any) : any +>{} as any : any +>{} : {} + +const r1 = f(v); // number +>r1 : number +>f(v) : number +>f : (x: { [K in A]: Field; }) => R +>v : { test: { smth: number; }; } + +const r2 = g(v); // unknown +>r2 : number +>g(v) : number +>g : (x: Field>) => R +>v : { test: { smth: number; }; } + diff --git a/tests/baselines/reference/promiseTypeInference.errors.txt b/tests/baselines/reference/promiseTypeInference.errors.txt deleted file mode 100644 index ada81bfb4962b..0000000000000 --- a/tests/baselines/reference/promiseTypeInference.errors.txt +++ /dev/null @@ -1,38 +0,0 @@ -tests/cases/compiler/promiseTypeInference.ts(10,39): error TS2769: No overload matches this call. - Overload 1 of 2, '(success?: (value: string) => Promise): Promise', gave the following error. - Property 'catch' is missing in type 'IPromise' but required in type 'Promise'. - Overload 2 of 2, '(onfulfilled?: (value: string) => number | PromiseLike, onrejected?: (reason: any) => PromiseLike): Promise', gave the following error. - Type 'IPromise' is not assignable to type 'number | PromiseLike'. - Type 'IPromise' is not assignable to type 'PromiseLike'. - Types of property 'then' are incompatible. - 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 TS2769: No overload matches this call. -!!! error TS2769: Overload 1 of 2, '(success?: (value: string) => Promise): Promise', gave the following error. -!!! error TS2769: Property 'catch' is missing in type 'IPromise' but required in type 'Promise'. -!!! error TS2769: Overload 2 of 2, '(onfulfilled?: (value: string) => number | PromiseLike, onrejected?: (reason: any) => PromiseLike): Promise', gave the following error. -!!! error TS2769: Type 'IPromise' is not assignable to type 'number | PromiseLike'. -!!! error TS2769: Type 'IPromise' is not assignable to type 'PromiseLike'. -!!! error TS2769: Types of property 'then' are incompatible. -!!! error TS2769: Types of parameters 'success' and 'onfulfilled' are incompatible. -!!! error TS2769: Type 'TResult1 | PromiseLike' is not assignable to type 'IPromise'. -!!! error TS2769: Type 'TResult1' is not assignable to type 'IPromise'. -!!! related TS2728 /.ts/lib.es5.d.ts:1430:5: 'catch' is declared here. -!!! related TS6502 tests/cases/compiler/promiseTypeInference.ts:2:23: The expected type comes from the return type of this signature. -!!! related TS6502 /.ts/lib.es5.d.ts:1423:57: The expected type comes from the return type of this signature. - \ No newline at end of file diff --git a/tests/baselines/reference/promiseTypeInference.types b/tests/baselines/reference/promiseTypeInference.types index 72c7001f52554..37329daf7322d 100644 --- a/tests/baselines/reference/promiseTypeInference.types +++ b/tests/baselines/reference/promiseTypeInference.types @@ -22,8 +22,8 @@ declare function convert(s: string): IPromise; >s : string var $$x = load("something").then(s => convert(s)); ->$$x : Promise ->load("something").then(s => convert(s)) : Promise +>$$x : Promise +>load("something").then(s => convert(s)) : Promise >load("something").then : { (onfulfilled?: (value: string) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike): Promise; (success?: (value: string) => Promise): Promise; } >load("something") : Promise >load : (name: string) => Promise diff --git a/tests/baselines/reference/registryMonoidalPatternNoOOM.js b/tests/baselines/reference/registryMonoidalPatternNoOOM.js new file mode 100644 index 0000000000000..df9978e89c404 --- /dev/null +++ b/tests/baselines/reference/registryMonoidalPatternNoOOM.js @@ -0,0 +1,201 @@ +//// [registryMonoidalPatternNoOOM.ts] +interface Plugins {} + +type PluginNames = keyof Plugins; + +interface MiddlewarePlugin { + readonly _group: TKind; + configure(cb: (conf: TPreviousConfig) => TConfig): Plugins[TKind]; + // combine(cb: Plugins<(conf: TPreviousConfig) => TConfig>[TKind]): Plugins[TKind]; + // The above "works", but the below _should_ result in less to check and is simpler (and is needed to trigger the OOM bug) + combine(cb: MiddlewarePlugin TConfig>): Plugins[TKind]; +} + +const GroupOneName = "GroupOne"; +type GroupOneName = typeof GroupOneName; +type GroupOne = PluginA | PluginB; +interface Plugins { + [GroupOneName]: GroupOne; +} +class PluginA implements MiddlewarePlugin { + readonly _kind = "PluginA"; + readonly _group = GroupOneName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupOne { + return new PluginA(cb(this.value)); + } + combine(plug: GroupOne<(conf: TConf) => T>): GroupOne { + return plug.configure(f => f(this.value)); + } +} + +class PluginB implements MiddlewarePlugin { + readonly _kind = "PluginB"; + readonly _group = GroupOneName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupOne { + return new PluginB(cb(this.value)); + } + combine(plug: GroupOne<(conf: TConf) => T>): GroupOne { + return plug.configure(f => f(this.value)); + } +} + +// One plugin group isn't quite enough to run OOM - we need a few more + +const GroupTwoName = "GroupTwo"; +type GroupTwoName = typeof GroupTwoName; +type GroupTwo = PluginC | PluginD; +interface Plugins { + [GroupTwoName]: GroupTwo; +} +class PluginC implements MiddlewarePlugin { + readonly _kind = "PluginC"; + readonly _group = GroupTwoName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupTwo { + return new PluginC(cb(this.value)); + } + combine(plug: GroupTwo<(conf: TConf) => T>): GroupTwo { + return plug.configure(f => f(this.value)); + } +} + +class PluginD implements MiddlewarePlugin { + readonly _kind = "PluginD"; + readonly _group = GroupTwoName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupTwo { + return new PluginD(cb(this.value)); + } + combine(plug: GroupTwo<(conf: TConf) => T>): GroupTwo { + return plug.configure(f => f(this.value)); + } +} + +const GroupThreeName = "GroupThree"; +type GroupThreeName = typeof GroupThreeName; +type GroupThree = PluginE | PluginF; +interface Plugins { + [GroupThreeName]: GroupThree; +} +class PluginE implements MiddlewarePlugin { + readonly _kind = "PluginC"; + readonly _group = GroupThreeName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupThree { + return new PluginE(cb(this.value)); + } + combine(plug: GroupThree<(conf: TConf) => T>): GroupThree { + return plug.configure(f => f(this.value)); + } +} + +class PluginF implements MiddlewarePlugin { + readonly _kind = "PluginD"; + readonly _group = GroupThreeName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupThree { + return new PluginF(cb(this.value)); + } + combine(plug: GroupThree<(conf: TConf) => T>): GroupThree { + return plug.configure(f => f(this.value)); + } +} + + +//// [registryMonoidalPatternNoOOM.js] +var GroupOneName = "GroupOne"; +var PluginA = /** @class */ (function () { + function PluginA(value) { + this.value = value; + this._kind = "PluginA"; + this._group = GroupOneName; + } + PluginA.prototype.configure = function (cb) { + return new PluginA(cb(this.value)); + }; + PluginA.prototype.combine = function (plug) { + var _this = this; + return plug.configure(function (f) { return f(_this.value); }); + }; + return PluginA; +}()); +var PluginB = /** @class */ (function () { + function PluginB(value) { + this.value = value; + this._kind = "PluginB"; + this._group = GroupOneName; + } + PluginB.prototype.configure = function (cb) { + return new PluginB(cb(this.value)); + }; + PluginB.prototype.combine = function (plug) { + var _this = this; + return plug.configure(function (f) { return f(_this.value); }); + }; + return PluginB; +}()); +// One plugin group isn't quite enough to run OOM - we need a few more +var GroupTwoName = "GroupTwo"; +var PluginC = /** @class */ (function () { + function PluginC(value) { + this.value = value; + this._kind = "PluginC"; + this._group = GroupTwoName; + } + PluginC.prototype.configure = function (cb) { + return new PluginC(cb(this.value)); + }; + PluginC.prototype.combine = function (plug) { + var _this = this; + return plug.configure(function (f) { return f(_this.value); }); + }; + return PluginC; +}()); +var PluginD = /** @class */ (function () { + function PluginD(value) { + this.value = value; + this._kind = "PluginD"; + this._group = GroupTwoName; + } + PluginD.prototype.configure = function (cb) { + return new PluginD(cb(this.value)); + }; + PluginD.prototype.combine = function (plug) { + var _this = this; + return plug.configure(function (f) { return f(_this.value); }); + }; + return PluginD; +}()); +var GroupThreeName = "GroupThree"; +var PluginE = /** @class */ (function () { + function PluginE(value) { + this.value = value; + this._kind = "PluginC"; + this._group = GroupThreeName; + } + PluginE.prototype.configure = function (cb) { + return new PluginE(cb(this.value)); + }; + PluginE.prototype.combine = function (plug) { + var _this = this; + return plug.configure(function (f) { return f(_this.value); }); + }; + return PluginE; +}()); +var PluginF = /** @class */ (function () { + function PluginF(value) { + this.value = value; + this._kind = "PluginD"; + this._group = GroupThreeName; + } + PluginF.prototype.configure = function (cb) { + return new PluginF(cb(this.value)); + }; + PluginF.prototype.combine = function (plug) { + var _this = this; + return plug.configure(function (f) { return f(_this.value); }); + }; + return PluginF; +}()); diff --git a/tests/baselines/reference/registryMonoidalPatternNoOOM.symbols b/tests/baselines/reference/registryMonoidalPatternNoOOM.symbols new file mode 100644 index 0000000000000..e02e59728f277 --- /dev/null +++ b/tests/baselines/reference/registryMonoidalPatternNoOOM.symbols @@ -0,0 +1,471 @@ +=== tests/cases/compiler/registryMonoidalPatternNoOOM.ts === +interface Plugins {} +>Plugins : Symbol(Plugins, Decl(registryMonoidalPatternNoOOM.ts, 0, 0), Decl(registryMonoidalPatternNoOOM.ts, 14, 43), Decl(registryMonoidalPatternNoOOM.ts, 46, 43), Decl(registryMonoidalPatternNoOOM.ts, 76, 45)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 0, 18), Decl(registryMonoidalPatternNoOOM.ts, 15, 18), Decl(registryMonoidalPatternNoOOM.ts, 47, 18), Decl(registryMonoidalPatternNoOOM.ts, 77, 18)) + +type PluginNames = keyof Plugins; +>PluginNames : Symbol(PluginNames, Decl(registryMonoidalPatternNoOOM.ts, 0, 29)) +>Plugins : Symbol(Plugins, Decl(registryMonoidalPatternNoOOM.ts, 0, 0), Decl(registryMonoidalPatternNoOOM.ts, 14, 43), Decl(registryMonoidalPatternNoOOM.ts, 46, 43), Decl(registryMonoidalPatternNoOOM.ts, 76, 45)) + +interface MiddlewarePlugin { +>MiddlewarePlugin : Symbol(MiddlewarePlugin, Decl(registryMonoidalPatternNoOOM.ts, 2, 38)) +>TKind : Symbol(TKind, Decl(registryMonoidalPatternNoOOM.ts, 4, 27)) +>PluginNames : Symbol(PluginNames, Decl(registryMonoidalPatternNoOOM.ts, 0, 29)) +>TPreviousConfig : Symbol(TPreviousConfig, Decl(registryMonoidalPatternNoOOM.ts, 4, 53)) + + readonly _group: TKind; +>_group : Symbol(MiddlewarePlugin._group, Decl(registryMonoidalPatternNoOOM.ts, 4, 72)) +>TKind : Symbol(TKind, Decl(registryMonoidalPatternNoOOM.ts, 4, 27)) + + configure(cb: (conf: TPreviousConfig) => TConfig): Plugins[TKind]; +>configure : Symbol(MiddlewarePlugin.configure, Decl(registryMonoidalPatternNoOOM.ts, 5, 27)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 6, 14)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 6, 23)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 6, 28)) +>TPreviousConfig : Symbol(TPreviousConfig, Decl(registryMonoidalPatternNoOOM.ts, 4, 53)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 6, 14)) +>Plugins : Symbol(Plugins, Decl(registryMonoidalPatternNoOOM.ts, 0, 0), Decl(registryMonoidalPatternNoOOM.ts, 14, 43), Decl(registryMonoidalPatternNoOOM.ts, 46, 43), Decl(registryMonoidalPatternNoOOM.ts, 76, 45)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 6, 14)) +>TKind : Symbol(TKind, Decl(registryMonoidalPatternNoOOM.ts, 4, 27)) + + // combine(cb: Plugins<(conf: TPreviousConfig) => TConfig>[TKind]): Plugins[TKind]; + // The above "works", but the below _should_ result in less to check and is simpler (and is needed to trigger the OOM bug) + combine(cb: MiddlewarePlugin TConfig>): Plugins[TKind]; +>combine : Symbol(MiddlewarePlugin.combine, Decl(registryMonoidalPatternNoOOM.ts, 6, 88)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 9, 12)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 9, 21)) +>MiddlewarePlugin : Symbol(MiddlewarePlugin, Decl(registryMonoidalPatternNoOOM.ts, 2, 38)) +>TKind : Symbol(TKind, Decl(registryMonoidalPatternNoOOM.ts, 4, 27)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 9, 50)) +>TPreviousConfig : Symbol(TPreviousConfig, Decl(registryMonoidalPatternNoOOM.ts, 4, 53)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 9, 12)) +>Plugins : Symbol(Plugins, Decl(registryMonoidalPatternNoOOM.ts, 0, 0), Decl(registryMonoidalPatternNoOOM.ts, 14, 43), Decl(registryMonoidalPatternNoOOM.ts, 46, 43), Decl(registryMonoidalPatternNoOOM.ts, 76, 45)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 9, 12)) +>TKind : Symbol(TKind, Decl(registryMonoidalPatternNoOOM.ts, 4, 27)) +} + +const GroupOneName = "GroupOne"; +>GroupOneName : Symbol(GroupOneName, Decl(registryMonoidalPatternNoOOM.ts, 12, 5), Decl(registryMonoidalPatternNoOOM.ts, 12, 32)) + +type GroupOneName = typeof GroupOneName; +>GroupOneName : Symbol(GroupOneName, Decl(registryMonoidalPatternNoOOM.ts, 12, 5), Decl(registryMonoidalPatternNoOOM.ts, 12, 32)) +>GroupOneName : Symbol(GroupOneName, Decl(registryMonoidalPatternNoOOM.ts, 12, 5), Decl(registryMonoidalPatternNoOOM.ts, 12, 32)) + +type GroupOne = PluginA | PluginB; +>GroupOne : Symbol(GroupOne, Decl(registryMonoidalPatternNoOOM.ts, 13, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 14, 14)) +>PluginA : Symbol(PluginA, Decl(registryMonoidalPatternNoOOM.ts, 17, 1)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 14, 14)) +>PluginB : Symbol(PluginB, Decl(registryMonoidalPatternNoOOM.ts, 28, 1)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 14, 14)) + +interface Plugins { +>Plugins : Symbol(Plugins, Decl(registryMonoidalPatternNoOOM.ts, 0, 0), Decl(registryMonoidalPatternNoOOM.ts, 14, 43), Decl(registryMonoidalPatternNoOOM.ts, 46, 43), Decl(registryMonoidalPatternNoOOM.ts, 76, 45)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 0, 18), Decl(registryMonoidalPatternNoOOM.ts, 15, 18), Decl(registryMonoidalPatternNoOOM.ts, 47, 18), Decl(registryMonoidalPatternNoOOM.ts, 77, 18)) + + [GroupOneName]: GroupOne; +>[GroupOneName] : Symbol(Plugins[GroupOneName], Decl(registryMonoidalPatternNoOOM.ts, 15, 28)) +>GroupOneName : Symbol(GroupOneName, Decl(registryMonoidalPatternNoOOM.ts, 12, 5), Decl(registryMonoidalPatternNoOOM.ts, 12, 32)) +>GroupOne : Symbol(GroupOne, Decl(registryMonoidalPatternNoOOM.ts, 13, 40)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 0, 18), Decl(registryMonoidalPatternNoOOM.ts, 15, 18), Decl(registryMonoidalPatternNoOOM.ts, 47, 18), Decl(registryMonoidalPatternNoOOM.ts, 77, 18)) +} +class PluginA implements MiddlewarePlugin { +>PluginA : Symbol(PluginA, Decl(registryMonoidalPatternNoOOM.ts, 17, 1)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 18, 14)) +>MiddlewarePlugin : Symbol(MiddlewarePlugin, Decl(registryMonoidalPatternNoOOM.ts, 2, 38)) +>GroupOneName : Symbol(GroupOneName, Decl(registryMonoidalPatternNoOOM.ts, 12, 5), Decl(registryMonoidalPatternNoOOM.ts, 12, 32)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 18, 14)) + + readonly _kind = "PluginA"; +>_kind : Symbol(PluginA._kind, Decl(registryMonoidalPatternNoOOM.ts, 18, 71)) + + readonly _group = GroupOneName; +>_group : Symbol(PluginA._group, Decl(registryMonoidalPatternNoOOM.ts, 19, 31)) +>GroupOneName : Symbol(GroupOneName, Decl(registryMonoidalPatternNoOOM.ts, 12, 5), Decl(registryMonoidalPatternNoOOM.ts, 12, 32)) + + constructor(public value: TConf) {} +>value : Symbol(PluginA.value, Decl(registryMonoidalPatternNoOOM.ts, 21, 16)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 18, 14)) + + configure(cb: (conf: TConf) => T): GroupOne { +>configure : Symbol(PluginA.configure, Decl(registryMonoidalPatternNoOOM.ts, 21, 39)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 22, 14)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 22, 17)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 22, 22)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 18, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 22, 14)) +>GroupOne : Symbol(GroupOne, Decl(registryMonoidalPatternNoOOM.ts, 13, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 22, 14)) + + return new PluginA(cb(this.value)); +>PluginA : Symbol(PluginA, Decl(registryMonoidalPatternNoOOM.ts, 17, 1)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 22, 17)) +>this.value : Symbol(PluginA.value, Decl(registryMonoidalPatternNoOOM.ts, 21, 16)) +>this : Symbol(PluginA, Decl(registryMonoidalPatternNoOOM.ts, 17, 1)) +>value : Symbol(PluginA.value, Decl(registryMonoidalPatternNoOOM.ts, 21, 16)) + } + combine(plug: GroupOne<(conf: TConf) => T>): GroupOne { +>combine : Symbol(PluginA.combine, Decl(registryMonoidalPatternNoOOM.ts, 24, 5)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 25, 12)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 25, 15)) +>GroupOne : Symbol(GroupOne, Decl(registryMonoidalPatternNoOOM.ts, 13, 40)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 25, 31)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 18, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 25, 12)) +>GroupOne : Symbol(GroupOne, Decl(registryMonoidalPatternNoOOM.ts, 13, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 25, 12)) + + return plug.configure(f => f(this.value)); +>plug.configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 21, 39), Decl(registryMonoidalPatternNoOOM.ts, 33, 39)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 25, 15)) +>configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 21, 39), Decl(registryMonoidalPatternNoOOM.ts, 33, 39)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 26, 30)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 26, 30)) +>this.value : Symbol(PluginA.value, Decl(registryMonoidalPatternNoOOM.ts, 21, 16)) +>this : Symbol(PluginA, Decl(registryMonoidalPatternNoOOM.ts, 17, 1)) +>value : Symbol(PluginA.value, Decl(registryMonoidalPatternNoOOM.ts, 21, 16)) + } +} + +class PluginB implements MiddlewarePlugin { +>PluginB : Symbol(PluginB, Decl(registryMonoidalPatternNoOOM.ts, 28, 1)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 30, 14)) +>MiddlewarePlugin : Symbol(MiddlewarePlugin, Decl(registryMonoidalPatternNoOOM.ts, 2, 38)) +>GroupOneName : Symbol(GroupOneName, Decl(registryMonoidalPatternNoOOM.ts, 12, 5), Decl(registryMonoidalPatternNoOOM.ts, 12, 32)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 30, 14)) + + readonly _kind = "PluginB"; +>_kind : Symbol(PluginB._kind, Decl(registryMonoidalPatternNoOOM.ts, 30, 71)) + + readonly _group = GroupOneName; +>_group : Symbol(PluginB._group, Decl(registryMonoidalPatternNoOOM.ts, 31, 31)) +>GroupOneName : Symbol(GroupOneName, Decl(registryMonoidalPatternNoOOM.ts, 12, 5), Decl(registryMonoidalPatternNoOOM.ts, 12, 32)) + + constructor(public value: TConf) {} +>value : Symbol(PluginB.value, Decl(registryMonoidalPatternNoOOM.ts, 33, 16)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 30, 14)) + + configure(cb: (conf: TConf) => T): GroupOne { +>configure : Symbol(PluginB.configure, Decl(registryMonoidalPatternNoOOM.ts, 33, 39)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 34, 14)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 34, 17)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 34, 22)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 30, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 34, 14)) +>GroupOne : Symbol(GroupOne, Decl(registryMonoidalPatternNoOOM.ts, 13, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 34, 14)) + + return new PluginB(cb(this.value)); +>PluginB : Symbol(PluginB, Decl(registryMonoidalPatternNoOOM.ts, 28, 1)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 34, 17)) +>this.value : Symbol(PluginB.value, Decl(registryMonoidalPatternNoOOM.ts, 33, 16)) +>this : Symbol(PluginB, Decl(registryMonoidalPatternNoOOM.ts, 28, 1)) +>value : Symbol(PluginB.value, Decl(registryMonoidalPatternNoOOM.ts, 33, 16)) + } + combine(plug: GroupOne<(conf: TConf) => T>): GroupOne { +>combine : Symbol(PluginB.combine, Decl(registryMonoidalPatternNoOOM.ts, 36, 5)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 37, 12)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 37, 15)) +>GroupOne : Symbol(GroupOne, Decl(registryMonoidalPatternNoOOM.ts, 13, 40)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 37, 31)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 30, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 37, 12)) +>GroupOne : Symbol(GroupOne, Decl(registryMonoidalPatternNoOOM.ts, 13, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 37, 12)) + + return plug.configure(f => f(this.value)); +>plug.configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 21, 39), Decl(registryMonoidalPatternNoOOM.ts, 33, 39)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 37, 15)) +>configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 21, 39), Decl(registryMonoidalPatternNoOOM.ts, 33, 39)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 38, 30)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 38, 30)) +>this.value : Symbol(PluginB.value, Decl(registryMonoidalPatternNoOOM.ts, 33, 16)) +>this : Symbol(PluginB, Decl(registryMonoidalPatternNoOOM.ts, 28, 1)) +>value : Symbol(PluginB.value, Decl(registryMonoidalPatternNoOOM.ts, 33, 16)) + } +} + +// One plugin group isn't quite enough to run OOM - we need a few more + +const GroupTwoName = "GroupTwo"; +>GroupTwoName : Symbol(GroupTwoName, Decl(registryMonoidalPatternNoOOM.ts, 44, 5), Decl(registryMonoidalPatternNoOOM.ts, 44, 32)) + +type GroupTwoName = typeof GroupTwoName; +>GroupTwoName : Symbol(GroupTwoName, Decl(registryMonoidalPatternNoOOM.ts, 44, 5), Decl(registryMonoidalPatternNoOOM.ts, 44, 32)) +>GroupTwoName : Symbol(GroupTwoName, Decl(registryMonoidalPatternNoOOM.ts, 44, 5), Decl(registryMonoidalPatternNoOOM.ts, 44, 32)) + +type GroupTwo = PluginC | PluginD; +>GroupTwo : Symbol(GroupTwo, Decl(registryMonoidalPatternNoOOM.ts, 45, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 46, 14)) +>PluginC : Symbol(PluginC, Decl(registryMonoidalPatternNoOOM.ts, 49, 1)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 46, 14)) +>PluginD : Symbol(PluginD, Decl(registryMonoidalPatternNoOOM.ts, 60, 1)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 46, 14)) + +interface Plugins { +>Plugins : Symbol(Plugins, Decl(registryMonoidalPatternNoOOM.ts, 0, 0), Decl(registryMonoidalPatternNoOOM.ts, 14, 43), Decl(registryMonoidalPatternNoOOM.ts, 46, 43), Decl(registryMonoidalPatternNoOOM.ts, 76, 45)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 0, 18), Decl(registryMonoidalPatternNoOOM.ts, 15, 18), Decl(registryMonoidalPatternNoOOM.ts, 47, 18), Decl(registryMonoidalPatternNoOOM.ts, 77, 18)) + + [GroupTwoName]: GroupTwo; +>[GroupTwoName] : Symbol(Plugins[GroupTwoName], Decl(registryMonoidalPatternNoOOM.ts, 47, 28)) +>GroupTwoName : Symbol(GroupTwoName, Decl(registryMonoidalPatternNoOOM.ts, 44, 5), Decl(registryMonoidalPatternNoOOM.ts, 44, 32)) +>GroupTwo : Symbol(GroupTwo, Decl(registryMonoidalPatternNoOOM.ts, 45, 40)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 0, 18), Decl(registryMonoidalPatternNoOOM.ts, 15, 18), Decl(registryMonoidalPatternNoOOM.ts, 47, 18), Decl(registryMonoidalPatternNoOOM.ts, 77, 18)) +} +class PluginC implements MiddlewarePlugin { +>PluginC : Symbol(PluginC, Decl(registryMonoidalPatternNoOOM.ts, 49, 1)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 50, 14)) +>MiddlewarePlugin : Symbol(MiddlewarePlugin, Decl(registryMonoidalPatternNoOOM.ts, 2, 38)) +>GroupTwoName : Symbol(GroupTwoName, Decl(registryMonoidalPatternNoOOM.ts, 44, 5), Decl(registryMonoidalPatternNoOOM.ts, 44, 32)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 50, 14)) + + readonly _kind = "PluginC"; +>_kind : Symbol(PluginC._kind, Decl(registryMonoidalPatternNoOOM.ts, 50, 71)) + + readonly _group = GroupTwoName; +>_group : Symbol(PluginC._group, Decl(registryMonoidalPatternNoOOM.ts, 51, 31)) +>GroupTwoName : Symbol(GroupTwoName, Decl(registryMonoidalPatternNoOOM.ts, 44, 5), Decl(registryMonoidalPatternNoOOM.ts, 44, 32)) + + constructor(public value: TConf) {} +>value : Symbol(PluginC.value, Decl(registryMonoidalPatternNoOOM.ts, 53, 16)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 50, 14)) + + configure(cb: (conf: TConf) => T): GroupTwo { +>configure : Symbol(PluginC.configure, Decl(registryMonoidalPatternNoOOM.ts, 53, 39)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 54, 14)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 54, 17)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 54, 22)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 50, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 54, 14)) +>GroupTwo : Symbol(GroupTwo, Decl(registryMonoidalPatternNoOOM.ts, 45, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 54, 14)) + + return new PluginC(cb(this.value)); +>PluginC : Symbol(PluginC, Decl(registryMonoidalPatternNoOOM.ts, 49, 1)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 54, 17)) +>this.value : Symbol(PluginC.value, Decl(registryMonoidalPatternNoOOM.ts, 53, 16)) +>this : Symbol(PluginC, Decl(registryMonoidalPatternNoOOM.ts, 49, 1)) +>value : Symbol(PluginC.value, Decl(registryMonoidalPatternNoOOM.ts, 53, 16)) + } + combine(plug: GroupTwo<(conf: TConf) => T>): GroupTwo { +>combine : Symbol(PluginC.combine, Decl(registryMonoidalPatternNoOOM.ts, 56, 5)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 57, 12)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 57, 15)) +>GroupTwo : Symbol(GroupTwo, Decl(registryMonoidalPatternNoOOM.ts, 45, 40)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 57, 31)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 50, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 57, 12)) +>GroupTwo : Symbol(GroupTwo, Decl(registryMonoidalPatternNoOOM.ts, 45, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 57, 12)) + + return plug.configure(f => f(this.value)); +>plug.configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 53, 39), Decl(registryMonoidalPatternNoOOM.ts, 65, 39)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 57, 15)) +>configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 53, 39), Decl(registryMonoidalPatternNoOOM.ts, 65, 39)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 58, 30)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 58, 30)) +>this.value : Symbol(PluginC.value, Decl(registryMonoidalPatternNoOOM.ts, 53, 16)) +>this : Symbol(PluginC, Decl(registryMonoidalPatternNoOOM.ts, 49, 1)) +>value : Symbol(PluginC.value, Decl(registryMonoidalPatternNoOOM.ts, 53, 16)) + } +} + +class PluginD implements MiddlewarePlugin { +>PluginD : Symbol(PluginD, Decl(registryMonoidalPatternNoOOM.ts, 60, 1)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 62, 14)) +>MiddlewarePlugin : Symbol(MiddlewarePlugin, Decl(registryMonoidalPatternNoOOM.ts, 2, 38)) +>GroupTwoName : Symbol(GroupTwoName, Decl(registryMonoidalPatternNoOOM.ts, 44, 5), Decl(registryMonoidalPatternNoOOM.ts, 44, 32)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 62, 14)) + + readonly _kind = "PluginD"; +>_kind : Symbol(PluginD._kind, Decl(registryMonoidalPatternNoOOM.ts, 62, 71)) + + readonly _group = GroupTwoName; +>_group : Symbol(PluginD._group, Decl(registryMonoidalPatternNoOOM.ts, 63, 31)) +>GroupTwoName : Symbol(GroupTwoName, Decl(registryMonoidalPatternNoOOM.ts, 44, 5), Decl(registryMonoidalPatternNoOOM.ts, 44, 32)) + + constructor(public value: TConf) {} +>value : Symbol(PluginD.value, Decl(registryMonoidalPatternNoOOM.ts, 65, 16)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 62, 14)) + + configure(cb: (conf: TConf) => T): GroupTwo { +>configure : Symbol(PluginD.configure, Decl(registryMonoidalPatternNoOOM.ts, 65, 39)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 66, 14)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 66, 17)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 66, 22)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 62, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 66, 14)) +>GroupTwo : Symbol(GroupTwo, Decl(registryMonoidalPatternNoOOM.ts, 45, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 66, 14)) + + return new PluginD(cb(this.value)); +>PluginD : Symbol(PluginD, Decl(registryMonoidalPatternNoOOM.ts, 60, 1)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 66, 17)) +>this.value : Symbol(PluginD.value, Decl(registryMonoidalPatternNoOOM.ts, 65, 16)) +>this : Symbol(PluginD, Decl(registryMonoidalPatternNoOOM.ts, 60, 1)) +>value : Symbol(PluginD.value, Decl(registryMonoidalPatternNoOOM.ts, 65, 16)) + } + combine(plug: GroupTwo<(conf: TConf) => T>): GroupTwo { +>combine : Symbol(PluginD.combine, Decl(registryMonoidalPatternNoOOM.ts, 68, 5)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 69, 12)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 69, 15)) +>GroupTwo : Symbol(GroupTwo, Decl(registryMonoidalPatternNoOOM.ts, 45, 40)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 69, 31)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 62, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 69, 12)) +>GroupTwo : Symbol(GroupTwo, Decl(registryMonoidalPatternNoOOM.ts, 45, 40)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 69, 12)) + + return plug.configure(f => f(this.value)); +>plug.configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 53, 39), Decl(registryMonoidalPatternNoOOM.ts, 65, 39)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 69, 15)) +>configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 53, 39), Decl(registryMonoidalPatternNoOOM.ts, 65, 39)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 70, 30)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 70, 30)) +>this.value : Symbol(PluginD.value, Decl(registryMonoidalPatternNoOOM.ts, 65, 16)) +>this : Symbol(PluginD, Decl(registryMonoidalPatternNoOOM.ts, 60, 1)) +>value : Symbol(PluginD.value, Decl(registryMonoidalPatternNoOOM.ts, 65, 16)) + } +} + +const GroupThreeName = "GroupThree"; +>GroupThreeName : Symbol(GroupThreeName, Decl(registryMonoidalPatternNoOOM.ts, 74, 5), Decl(registryMonoidalPatternNoOOM.ts, 74, 36)) + +type GroupThreeName = typeof GroupThreeName; +>GroupThreeName : Symbol(GroupThreeName, Decl(registryMonoidalPatternNoOOM.ts, 74, 5), Decl(registryMonoidalPatternNoOOM.ts, 74, 36)) +>GroupThreeName : Symbol(GroupThreeName, Decl(registryMonoidalPatternNoOOM.ts, 74, 5), Decl(registryMonoidalPatternNoOOM.ts, 74, 36)) + +type GroupThree = PluginE | PluginF; +>GroupThree : Symbol(GroupThree, Decl(registryMonoidalPatternNoOOM.ts, 75, 44)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 76, 16)) +>PluginE : Symbol(PluginE, Decl(registryMonoidalPatternNoOOM.ts, 79, 1)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 76, 16)) +>PluginF : Symbol(PluginF, Decl(registryMonoidalPatternNoOOM.ts, 90, 1)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 76, 16)) + +interface Plugins { +>Plugins : Symbol(Plugins, Decl(registryMonoidalPatternNoOOM.ts, 0, 0), Decl(registryMonoidalPatternNoOOM.ts, 14, 43), Decl(registryMonoidalPatternNoOOM.ts, 46, 43), Decl(registryMonoidalPatternNoOOM.ts, 76, 45)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 0, 18), Decl(registryMonoidalPatternNoOOM.ts, 15, 18), Decl(registryMonoidalPatternNoOOM.ts, 47, 18), Decl(registryMonoidalPatternNoOOM.ts, 77, 18)) + + [GroupThreeName]: GroupThree; +>[GroupThreeName] : Symbol(Plugins[GroupThreeName], Decl(registryMonoidalPatternNoOOM.ts, 77, 28)) +>GroupThreeName : Symbol(GroupThreeName, Decl(registryMonoidalPatternNoOOM.ts, 74, 5), Decl(registryMonoidalPatternNoOOM.ts, 74, 36)) +>GroupThree : Symbol(GroupThree, Decl(registryMonoidalPatternNoOOM.ts, 75, 44)) +>TConfig : Symbol(TConfig, Decl(registryMonoidalPatternNoOOM.ts, 0, 18), Decl(registryMonoidalPatternNoOOM.ts, 15, 18), Decl(registryMonoidalPatternNoOOM.ts, 47, 18), Decl(registryMonoidalPatternNoOOM.ts, 77, 18)) +} +class PluginE implements MiddlewarePlugin { +>PluginE : Symbol(PluginE, Decl(registryMonoidalPatternNoOOM.ts, 79, 1)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 80, 14)) +>MiddlewarePlugin : Symbol(MiddlewarePlugin, Decl(registryMonoidalPatternNoOOM.ts, 2, 38)) +>GroupThreeName : Symbol(GroupThreeName, Decl(registryMonoidalPatternNoOOM.ts, 74, 5), Decl(registryMonoidalPatternNoOOM.ts, 74, 36)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 80, 14)) + + readonly _kind = "PluginC"; +>_kind : Symbol(PluginE._kind, Decl(registryMonoidalPatternNoOOM.ts, 80, 73)) + + readonly _group = GroupThreeName; +>_group : Symbol(PluginE._group, Decl(registryMonoidalPatternNoOOM.ts, 81, 31)) +>GroupThreeName : Symbol(GroupThreeName, Decl(registryMonoidalPatternNoOOM.ts, 74, 5), Decl(registryMonoidalPatternNoOOM.ts, 74, 36)) + + constructor(public value: TConf) {} +>value : Symbol(PluginE.value, Decl(registryMonoidalPatternNoOOM.ts, 83, 16)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 80, 14)) + + configure(cb: (conf: TConf) => T): GroupThree { +>configure : Symbol(PluginE.configure, Decl(registryMonoidalPatternNoOOM.ts, 83, 39)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 84, 14)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 84, 17)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 84, 22)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 80, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 84, 14)) +>GroupThree : Symbol(GroupThree, Decl(registryMonoidalPatternNoOOM.ts, 75, 44)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 84, 14)) + + return new PluginE(cb(this.value)); +>PluginE : Symbol(PluginE, Decl(registryMonoidalPatternNoOOM.ts, 79, 1)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 84, 17)) +>this.value : Symbol(PluginE.value, Decl(registryMonoidalPatternNoOOM.ts, 83, 16)) +>this : Symbol(PluginE, Decl(registryMonoidalPatternNoOOM.ts, 79, 1)) +>value : Symbol(PluginE.value, Decl(registryMonoidalPatternNoOOM.ts, 83, 16)) + } + combine(plug: GroupThree<(conf: TConf) => T>): GroupThree { +>combine : Symbol(PluginE.combine, Decl(registryMonoidalPatternNoOOM.ts, 86, 5)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 87, 12)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 87, 15)) +>GroupThree : Symbol(GroupThree, Decl(registryMonoidalPatternNoOOM.ts, 75, 44)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 87, 33)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 80, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 87, 12)) +>GroupThree : Symbol(GroupThree, Decl(registryMonoidalPatternNoOOM.ts, 75, 44)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 87, 12)) + + return plug.configure(f => f(this.value)); +>plug.configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 83, 39), Decl(registryMonoidalPatternNoOOM.ts, 95, 39)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 87, 15)) +>configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 83, 39), Decl(registryMonoidalPatternNoOOM.ts, 95, 39)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 88, 30)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 88, 30)) +>this.value : Symbol(PluginE.value, Decl(registryMonoidalPatternNoOOM.ts, 83, 16)) +>this : Symbol(PluginE, Decl(registryMonoidalPatternNoOOM.ts, 79, 1)) +>value : Symbol(PluginE.value, Decl(registryMonoidalPatternNoOOM.ts, 83, 16)) + } +} + +class PluginF implements MiddlewarePlugin { +>PluginF : Symbol(PluginF, Decl(registryMonoidalPatternNoOOM.ts, 90, 1)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 92, 14)) +>MiddlewarePlugin : Symbol(MiddlewarePlugin, Decl(registryMonoidalPatternNoOOM.ts, 2, 38)) +>GroupThreeName : Symbol(GroupThreeName, Decl(registryMonoidalPatternNoOOM.ts, 74, 5), Decl(registryMonoidalPatternNoOOM.ts, 74, 36)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 92, 14)) + + readonly _kind = "PluginD"; +>_kind : Symbol(PluginF._kind, Decl(registryMonoidalPatternNoOOM.ts, 92, 73)) + + readonly _group = GroupThreeName; +>_group : Symbol(PluginF._group, Decl(registryMonoidalPatternNoOOM.ts, 93, 31)) +>GroupThreeName : Symbol(GroupThreeName, Decl(registryMonoidalPatternNoOOM.ts, 74, 5), Decl(registryMonoidalPatternNoOOM.ts, 74, 36)) + + constructor(public value: TConf) {} +>value : Symbol(PluginF.value, Decl(registryMonoidalPatternNoOOM.ts, 95, 16)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 92, 14)) + + configure(cb: (conf: TConf) => T): GroupThree { +>configure : Symbol(PluginF.configure, Decl(registryMonoidalPatternNoOOM.ts, 95, 39)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 96, 14)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 96, 17)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 96, 22)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 92, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 96, 14)) +>GroupThree : Symbol(GroupThree, Decl(registryMonoidalPatternNoOOM.ts, 75, 44)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 96, 14)) + + return new PluginF(cb(this.value)); +>PluginF : Symbol(PluginF, Decl(registryMonoidalPatternNoOOM.ts, 90, 1)) +>cb : Symbol(cb, Decl(registryMonoidalPatternNoOOM.ts, 96, 17)) +>this.value : Symbol(PluginF.value, Decl(registryMonoidalPatternNoOOM.ts, 95, 16)) +>this : Symbol(PluginF, Decl(registryMonoidalPatternNoOOM.ts, 90, 1)) +>value : Symbol(PluginF.value, Decl(registryMonoidalPatternNoOOM.ts, 95, 16)) + } + combine(plug: GroupThree<(conf: TConf) => T>): GroupThree { +>combine : Symbol(PluginF.combine, Decl(registryMonoidalPatternNoOOM.ts, 98, 5)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 99, 12)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 99, 15)) +>GroupThree : Symbol(GroupThree, Decl(registryMonoidalPatternNoOOM.ts, 75, 44)) +>conf : Symbol(conf, Decl(registryMonoidalPatternNoOOM.ts, 99, 33)) +>TConf : Symbol(TConf, Decl(registryMonoidalPatternNoOOM.ts, 92, 14)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 99, 12)) +>GroupThree : Symbol(GroupThree, Decl(registryMonoidalPatternNoOOM.ts, 75, 44)) +>T : Symbol(T, Decl(registryMonoidalPatternNoOOM.ts, 99, 12)) + + return plug.configure(f => f(this.value)); +>plug.configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 83, 39), Decl(registryMonoidalPatternNoOOM.ts, 95, 39)) +>plug : Symbol(plug, Decl(registryMonoidalPatternNoOOM.ts, 99, 15)) +>configure : Symbol(configure, Decl(registryMonoidalPatternNoOOM.ts, 83, 39), Decl(registryMonoidalPatternNoOOM.ts, 95, 39)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 100, 30)) +>f : Symbol(f, Decl(registryMonoidalPatternNoOOM.ts, 100, 30)) +>this.value : Symbol(PluginF.value, Decl(registryMonoidalPatternNoOOM.ts, 95, 16)) +>this : Symbol(PluginF, Decl(registryMonoidalPatternNoOOM.ts, 90, 1)) +>value : Symbol(PluginF.value, Decl(registryMonoidalPatternNoOOM.ts, 95, 16)) + } +} + diff --git a/tests/baselines/reference/registryMonoidalPatternNoOOM.types b/tests/baselines/reference/registryMonoidalPatternNoOOM.types new file mode 100644 index 0000000000000..a23ec34acca5b --- /dev/null +++ b/tests/baselines/reference/registryMonoidalPatternNoOOM.types @@ -0,0 +1,361 @@ +=== tests/cases/compiler/registryMonoidalPatternNoOOM.ts === +interface Plugins {} + +type PluginNames = keyof Plugins; +>PluginNames : "GroupOne" | "GroupTwo" | "GroupThree" + +interface MiddlewarePlugin { + readonly _group: TKind; +>_group : TKind + + configure(cb: (conf: TPreviousConfig) => TConfig): Plugins[TKind]; +>configure : (cb: (conf: TPreviousConfig) => TConfig) => Plugins[TKind] +>cb : (conf: TPreviousConfig) => TConfig +>conf : TPreviousConfig + + // combine(cb: Plugins<(conf: TPreviousConfig) => TConfig>[TKind]): Plugins[TKind]; + // The above "works", but the below _should_ result in less to check and is simpler (and is needed to trigger the OOM bug) + combine(cb: MiddlewarePlugin TConfig>): Plugins[TKind]; +>combine : (cb: MiddlewarePlugin TConfig>) => Plugins[TKind] +>cb : MiddlewarePlugin TConfig> +>conf : TPreviousConfig +} + +const GroupOneName = "GroupOne"; +>GroupOneName : "GroupOne" +>"GroupOne" : "GroupOne" + +type GroupOneName = typeof GroupOneName; +>GroupOneName : "GroupOne" +>GroupOneName : "GroupOne" + +type GroupOne = PluginA | PluginB; +>GroupOne : GroupOne + +interface Plugins { + [GroupOneName]: GroupOne; +>[GroupOneName] : GroupOne +>GroupOneName : "GroupOne" +} +class PluginA implements MiddlewarePlugin { +>PluginA : PluginA + + readonly _kind = "PluginA"; +>_kind : "PluginA" +>"PluginA" : "PluginA" + + readonly _group = GroupOneName; +>_group : "GroupOne" +>GroupOneName : "GroupOne" + + constructor(public value: TConf) {} +>value : TConf + + configure(cb: (conf: TConf) => T): GroupOne { +>configure : (cb: (conf: TConf) => T) => GroupOne +>cb : (conf: TConf) => T +>conf : TConf + + return new PluginA(cb(this.value)); +>new PluginA(cb(this.value)) : PluginA +>PluginA : typeof PluginA +>cb(this.value) : T +>cb : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } + combine(plug: GroupOne<(conf: TConf) => T>): GroupOne { +>combine : (plug: GroupOne<(conf: TConf) => T>) => GroupOne +>plug : GroupOne<(conf: TConf) => T> +>conf : TConf + + return plug.configure(f => f(this.value)); +>plug.configure(f => f(this.value)) : GroupOne +>plug.configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupOne) | ((cb: (conf: (conf: TConf) => T) => T) => GroupOne) +>plug : GroupOne<(conf: TConf) => T> +>configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupOne) | ((cb: (conf: (conf: TConf) => T) => T) => GroupOne) +>f => f(this.value) : (f: (conf: TConf) => T) => T +>f : (conf: TConf) => T +>f(this.value) : T +>f : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } +} + +class PluginB implements MiddlewarePlugin { +>PluginB : PluginB + + readonly _kind = "PluginB"; +>_kind : "PluginB" +>"PluginB" : "PluginB" + + readonly _group = GroupOneName; +>_group : "GroupOne" +>GroupOneName : "GroupOne" + + constructor(public value: TConf) {} +>value : TConf + + configure(cb: (conf: TConf) => T): GroupOne { +>configure : (cb: (conf: TConf) => T) => GroupOne +>cb : (conf: TConf) => T +>conf : TConf + + return new PluginB(cb(this.value)); +>new PluginB(cb(this.value)) : PluginB +>PluginB : typeof PluginB +>cb(this.value) : T +>cb : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } + combine(plug: GroupOne<(conf: TConf) => T>): GroupOne { +>combine : (plug: GroupOne<(conf: TConf) => T>) => GroupOne +>plug : GroupOne<(conf: TConf) => T> +>conf : TConf + + return plug.configure(f => f(this.value)); +>plug.configure(f => f(this.value)) : GroupOne +>plug.configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupOne) | ((cb: (conf: (conf: TConf) => T) => T) => GroupOne) +>plug : GroupOne<(conf: TConf) => T> +>configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupOne) | ((cb: (conf: (conf: TConf) => T) => T) => GroupOne) +>f => f(this.value) : (f: (conf: TConf) => T) => T +>f : (conf: TConf) => T +>f(this.value) : T +>f : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } +} + +// One plugin group isn't quite enough to run OOM - we need a few more + +const GroupTwoName = "GroupTwo"; +>GroupTwoName : "GroupTwo" +>"GroupTwo" : "GroupTwo" + +type GroupTwoName = typeof GroupTwoName; +>GroupTwoName : "GroupTwo" +>GroupTwoName : "GroupTwo" + +type GroupTwo = PluginC | PluginD; +>GroupTwo : GroupTwo + +interface Plugins { + [GroupTwoName]: GroupTwo; +>[GroupTwoName] : GroupTwo +>GroupTwoName : "GroupTwo" +} +class PluginC implements MiddlewarePlugin { +>PluginC : PluginC + + readonly _kind = "PluginC"; +>_kind : "PluginC" +>"PluginC" : "PluginC" + + readonly _group = GroupTwoName; +>_group : "GroupTwo" +>GroupTwoName : "GroupTwo" + + constructor(public value: TConf) {} +>value : TConf + + configure(cb: (conf: TConf) => T): GroupTwo { +>configure : (cb: (conf: TConf) => T) => GroupTwo +>cb : (conf: TConf) => T +>conf : TConf + + return new PluginC(cb(this.value)); +>new PluginC(cb(this.value)) : PluginC +>PluginC : typeof PluginC +>cb(this.value) : T +>cb : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } + combine(plug: GroupTwo<(conf: TConf) => T>): GroupTwo { +>combine : (plug: GroupTwo<(conf: TConf) => T>) => GroupTwo +>plug : GroupTwo<(conf: TConf) => T> +>conf : TConf + + return plug.configure(f => f(this.value)); +>plug.configure(f => f(this.value)) : GroupTwo +>plug.configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupTwo) | ((cb: (conf: (conf: TConf) => T) => T) => GroupTwo) +>plug : GroupTwo<(conf: TConf) => T> +>configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupTwo) | ((cb: (conf: (conf: TConf) => T) => T) => GroupTwo) +>f => f(this.value) : (f: (conf: TConf) => T) => T +>f : (conf: TConf) => T +>f(this.value) : T +>f : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } +} + +class PluginD implements MiddlewarePlugin { +>PluginD : PluginD + + readonly _kind = "PluginD"; +>_kind : "PluginD" +>"PluginD" : "PluginD" + + readonly _group = GroupTwoName; +>_group : "GroupTwo" +>GroupTwoName : "GroupTwo" + + constructor(public value: TConf) {} +>value : TConf + + configure(cb: (conf: TConf) => T): GroupTwo { +>configure : (cb: (conf: TConf) => T) => GroupTwo +>cb : (conf: TConf) => T +>conf : TConf + + return new PluginD(cb(this.value)); +>new PluginD(cb(this.value)) : PluginD +>PluginD : typeof PluginD +>cb(this.value) : T +>cb : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } + combine(plug: GroupTwo<(conf: TConf) => T>): GroupTwo { +>combine : (plug: GroupTwo<(conf: TConf) => T>) => GroupTwo +>plug : GroupTwo<(conf: TConf) => T> +>conf : TConf + + return plug.configure(f => f(this.value)); +>plug.configure(f => f(this.value)) : GroupTwo +>plug.configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupTwo) | ((cb: (conf: (conf: TConf) => T) => T) => GroupTwo) +>plug : GroupTwo<(conf: TConf) => T> +>configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupTwo) | ((cb: (conf: (conf: TConf) => T) => T) => GroupTwo) +>f => f(this.value) : (f: (conf: TConf) => T) => T +>f : (conf: TConf) => T +>f(this.value) : T +>f : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } +} + +const GroupThreeName = "GroupThree"; +>GroupThreeName : "GroupThree" +>"GroupThree" : "GroupThree" + +type GroupThreeName = typeof GroupThreeName; +>GroupThreeName : "GroupThree" +>GroupThreeName : "GroupThree" + +type GroupThree = PluginE | PluginF; +>GroupThree : GroupThree + +interface Plugins { + [GroupThreeName]: GroupThree; +>[GroupThreeName] : GroupThree +>GroupThreeName : "GroupThree" +} +class PluginE implements MiddlewarePlugin { +>PluginE : PluginE + + readonly _kind = "PluginC"; +>_kind : "PluginC" +>"PluginC" : "PluginC" + + readonly _group = GroupThreeName; +>_group : "GroupThree" +>GroupThreeName : "GroupThree" + + constructor(public value: TConf) {} +>value : TConf + + configure(cb: (conf: TConf) => T): GroupThree { +>configure : (cb: (conf: TConf) => T) => GroupThree +>cb : (conf: TConf) => T +>conf : TConf + + return new PluginE(cb(this.value)); +>new PluginE(cb(this.value)) : PluginE +>PluginE : typeof PluginE +>cb(this.value) : T +>cb : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } + combine(plug: GroupThree<(conf: TConf) => T>): GroupThree { +>combine : (plug: GroupThree<(conf: TConf) => T>) => GroupThree +>plug : GroupThree<(conf: TConf) => T> +>conf : TConf + + return plug.configure(f => f(this.value)); +>plug.configure(f => f(this.value)) : GroupThree +>plug.configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupThree) | ((cb: (conf: (conf: TConf) => T) => T) => GroupThree) +>plug : GroupThree<(conf: TConf) => T> +>configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupThree) | ((cb: (conf: (conf: TConf) => T) => T) => GroupThree) +>f => f(this.value) : (f: (conf: TConf) => T) => T +>f : (conf: TConf) => T +>f(this.value) : T +>f : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } +} + +class PluginF implements MiddlewarePlugin { +>PluginF : PluginF + + readonly _kind = "PluginD"; +>_kind : "PluginD" +>"PluginD" : "PluginD" + + readonly _group = GroupThreeName; +>_group : "GroupThree" +>GroupThreeName : "GroupThree" + + constructor(public value: TConf) {} +>value : TConf + + configure(cb: (conf: TConf) => T): GroupThree { +>configure : (cb: (conf: TConf) => T) => GroupThree +>cb : (conf: TConf) => T +>conf : TConf + + return new PluginF(cb(this.value)); +>new PluginF(cb(this.value)) : PluginF +>PluginF : typeof PluginF +>cb(this.value) : T +>cb : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } + combine(plug: GroupThree<(conf: TConf) => T>): GroupThree { +>combine : (plug: GroupThree<(conf: TConf) => T>) => GroupThree +>plug : GroupThree<(conf: TConf) => T> +>conf : TConf + + return plug.configure(f => f(this.value)); +>plug.configure(f => f(this.value)) : GroupThree +>plug.configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupThree) | ((cb: (conf: (conf: TConf) => T) => T) => GroupThree) +>plug : GroupThree<(conf: TConf) => T> +>configure : ((cb: (conf: (conf: TConf) => T) => T) => GroupThree) | ((cb: (conf: (conf: TConf) => T) => T) => GroupThree) +>f => f(this.value) : (f: (conf: TConf) => T) => T +>f : (conf: TConf) => T +>f(this.value) : T +>f : (conf: TConf) => T +>this.value : TConf +>this : this +>value : TConf + } +} + diff --git a/tests/cases/compiler/mappedTypeAliasSubstitutability.ts b/tests/cases/compiler/mappedTypeAliasSubstitutability.ts new file mode 100644 index 0000000000000..c0c826104b365 --- /dev/null +++ b/tests/cases/compiler/mappedTypeAliasSubstitutability.ts @@ -0,0 +1,8 @@ +// repro from https://github.com/microsoft/TypeScript/issues/31616 + +const v = { test: { smth: 5 } }; +type Field = { [K in A]: R }; +const f = (x: { [K in A]: Field } ): R => ({} as any); +const g = (x: Field>): R => ({} as any); +const r1 = f(v); // number +const r2 = g(v); // unknown diff --git a/tests/cases/compiler/registryMonoidalPatternNoOOM.ts b/tests/cases/compiler/registryMonoidalPatternNoOOM.ts new file mode 100644 index 0000000000000..1bc3e738e785b --- /dev/null +++ b/tests/cases/compiler/registryMonoidalPatternNoOOM.ts @@ -0,0 +1,103 @@ +interface Plugins {} + +type PluginNames = keyof Plugins; + +interface MiddlewarePlugin { + readonly _group: TKind; + configure(cb: (conf: TPreviousConfig) => TConfig): Plugins[TKind]; + // combine(cb: Plugins<(conf: TPreviousConfig) => TConfig>[TKind]): Plugins[TKind]; + // The above "works", but the below _should_ result in less to check and is simpler (and is needed to trigger the OOM bug) + combine(cb: MiddlewarePlugin TConfig>): Plugins[TKind]; +} + +const GroupOneName = "GroupOne"; +type GroupOneName = typeof GroupOneName; +type GroupOne = PluginA | PluginB; +interface Plugins { + [GroupOneName]: GroupOne; +} +class PluginA implements MiddlewarePlugin { + readonly _kind = "PluginA"; + readonly _group = GroupOneName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupOne { + return new PluginA(cb(this.value)); + } + combine(plug: GroupOne<(conf: TConf) => T>): GroupOne { + return plug.configure(f => f(this.value)); + } +} + +class PluginB implements MiddlewarePlugin { + readonly _kind = "PluginB"; + readonly _group = GroupOneName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupOne { + return new PluginB(cb(this.value)); + } + combine(plug: GroupOne<(conf: TConf) => T>): GroupOne { + return plug.configure(f => f(this.value)); + } +} + +// One plugin group isn't quite enough to run OOM - we need a few more + +const GroupTwoName = "GroupTwo"; +type GroupTwoName = typeof GroupTwoName; +type GroupTwo = PluginC | PluginD; +interface Plugins { + [GroupTwoName]: GroupTwo; +} +class PluginC implements MiddlewarePlugin { + readonly _kind = "PluginC"; + readonly _group = GroupTwoName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupTwo { + return new PluginC(cb(this.value)); + } + combine(plug: GroupTwo<(conf: TConf) => T>): GroupTwo { + return plug.configure(f => f(this.value)); + } +} + +class PluginD implements MiddlewarePlugin { + readonly _kind = "PluginD"; + readonly _group = GroupTwoName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupTwo { + return new PluginD(cb(this.value)); + } + combine(plug: GroupTwo<(conf: TConf) => T>): GroupTwo { + return plug.configure(f => f(this.value)); + } +} + +const GroupThreeName = "GroupThree"; +type GroupThreeName = typeof GroupThreeName; +type GroupThree = PluginE | PluginF; +interface Plugins { + [GroupThreeName]: GroupThree; +} +class PluginE implements MiddlewarePlugin { + readonly _kind = "PluginC"; + readonly _group = GroupThreeName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupThree { + return new PluginE(cb(this.value)); + } + combine(plug: GroupThree<(conf: TConf) => T>): GroupThree { + return plug.configure(f => f(this.value)); + } +} + +class PluginF implements MiddlewarePlugin { + readonly _kind = "PluginD"; + readonly _group = GroupThreeName; + constructor(public value: TConf) {} + configure(cb: (conf: TConf) => T): GroupThree { + return new PluginF(cb(this.value)); + } + combine(plug: GroupThree<(conf: TConf) => T>): GroupThree { + return plug.configure(f => f(this.value)); + } +}