From 8ddeb966f5f1a3624fd2dd0f304f64a07fdf3548 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 06:19:58 -0700 Subject: [PATCH 1/8] Consistently include circularity check in type parameter constraints --- src/compiler/checker.ts | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cdcf1448d2d..c56d39a9ffc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3708,7 +3708,7 @@ namespace ts { return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } - function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintFromTypeParameter(type)): TypeParameterDeclaration { + function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter(type)): TypeParameterDeclaration { const constraintNode = constraint && typeToTypeNodeHelper(constraint, context); return typeParameterToDeclarationWithConstraint(type, context, constraintNode); } @@ -4356,28 +4356,23 @@ namespace ts { return i; } } - return -1; } function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean { - if (propertyName === TypeSystemPropertyName.Type) { - return !!getSymbolLinks(target).type; + switch (propertyName) { + case TypeSystemPropertyName.Type: + return !!getSymbolLinks(target).type; + case TypeSystemPropertyName.DeclaredType: + return !!getSymbolLinks(target).declaredType; + case TypeSystemPropertyName.ResolvedBaseConstructorType: + return !!(target).resolvedBaseConstructorType; + case TypeSystemPropertyName.ResolvedReturnType: + return !!(target).resolvedReturnType; + case TypeSystemPropertyName.ImmediateBaseConstraint: + const bc = (target).immediateBaseConstraint; + return !!bc && bc !== circularConstraintType; } - if (propertyName === TypeSystemPropertyName.DeclaredType) { - return !!getSymbolLinks(target).declaredType; - } - if (propertyName === TypeSystemPropertyName.ResolvedBaseConstructorType) { - return !!(target).resolvedBaseConstructorType; - } - if (propertyName === TypeSystemPropertyName.ResolvedReturnType) { - return !!(target).resolvedReturnType; - } - if (propertyName === TypeSystemPropertyName.ImmediateBaseConstraint) { - const bc = (target).immediateBaseConstraint; - return !!bc && bc !== circularConstraintType; - } - return Debug.fail("Unhandled TypeSystemPropertyName " + propertyName); } @@ -9166,7 +9161,7 @@ namespace ts { return type.simplified = substituteIndexedMappedType(objectType, type); } if (objectType.flags & TypeFlags.TypeParameter) { - const constraint = getConstraintFromTypeParameter(objectType as TypeParameter); + const constraint = getConstraintOfTypeParameter(objectType as TypeParameter); if (constraint && isGenericMappedType(constraint)) { return type.simplified = substituteIndexedMappedType(constraint, type); } @@ -12113,7 +12108,7 @@ namespace ts { } function isUnconstrainedTypeParameter(type: Type) { - return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter(type); + return type.flags & TypeFlags.TypeParameter && !getConstraintOfTypeParameter(type); } function isTypeReferenceWithGenericArguments(type: Type): boolean { @@ -17642,7 +17637,7 @@ namespace ts { } const thisType = getTypeFromTypeNode(thisParameter.type); - enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintFromTypeParameter(thisType) : thisType) as InterfaceType; + enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintOfTypeParameter(thisType) : thisType) as InterfaceType; } // No further restrictions for static properties if (flags & ModifierFlags.Static) { @@ -19283,7 +19278,7 @@ namespace ts { typeArguments.pop(); } while (typeArguments.length < typeParameters.length) { - typeArguments.push(getConstraintFromTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node))); + typeArguments.push(getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node))); } const instantiated = createSignatureInstantiation(candidate, typeArguments); candidates[bestIndex] = instantiated; @@ -25185,7 +25180,7 @@ namespace ts { // If the type parameter node does not have an identical constraint as the resolved // type parameter at this position, we report an error. const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint); - const targetConstraint = getConstraintFromTypeParameter(target); + const targetConstraint = getConstraintOfTypeParameter(target); if (sourceConstraint) { // relax check if later interface augmentation has no constraint if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) { From 06a11456ccf114ac40e7c0baa72455302acf7995 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 06:21:12 -0700 Subject: [PATCH 2/8] Accept new baselines --- .../reference/circularIndexedAccessErrors.types | 2 +- .../incorrectRecursiveMappedTypeConstraint.types | 2 +- .../typeParameterDirectlyConstrainedToItself.types | 14 +++++++------- .../typeParameterHasSelfAsConstraint.types | 2 +- ...ypeParameterIndirectlyConstrainedToItself.types | 14 +++++++------- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/baselines/reference/circularIndexedAccessErrors.types b/tests/baselines/reference/circularIndexedAccessErrors.types index 6b2cf2c51be..aeaa460ab4a 100644 --- a/tests/baselines/reference/circularIndexedAccessErrors.types +++ b/tests/baselines/reference/circularIndexedAccessErrors.types @@ -86,7 +86,7 @@ interface Foo { } function foo() { ->foo : () => void +>foo : () => void >T : T >Foo : Foo >T : T diff --git a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types index a388d2b536b..bf636eaae80 100644 --- a/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types +++ b/tests/baselines/reference/incorrectRecursiveMappedTypeConstraint.types @@ -1,7 +1,7 @@ === tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts === // #17847 function sum(n: number, v: T, k: K) { ->sum : (n: number, v: T, k: K) => void +>sum : (n: number, v: T, k: K) => void >T : T >P : P >T : T diff --git a/tests/baselines/reference/typeParameterDirectlyConstrainedToItself.types b/tests/baselines/reference/typeParameterDirectlyConstrainedToItself.types index 0ef49d9767a..5efa4b5d19b 100644 --- a/tests/baselines/reference/typeParameterDirectlyConstrainedToItself.types +++ b/tests/baselines/reference/typeParameterDirectlyConstrainedToItself.types @@ -24,18 +24,18 @@ interface I2 { } >U : U function f() { } ->f : () => void +>f : () => void >T : T >T : T function f2() { } ->f2 : () => void +>f2 : () => void >T : T >U : U >U : U var a: { ->a : { (): void; (): void; } +>a : { (): void; (): void; } (): void; >T : T @@ -48,14 +48,14 @@ var a: { } var b = () => { } ->b : () => void ->() => { } : () => void +>b : () => void +>() => { } : () => void >T : T >T : T var b2 = () => { } ->b2 : () => void ->() => { } : () => void +>b2 : () => void +>() => { } : () => void >T : T >U : U >U : U diff --git a/tests/baselines/reference/typeParameterHasSelfAsConstraint.types b/tests/baselines/reference/typeParameterHasSelfAsConstraint.types index 2d489515faf..9d297dc9934 100644 --- a/tests/baselines/reference/typeParameterHasSelfAsConstraint.types +++ b/tests/baselines/reference/typeParameterHasSelfAsConstraint.types @@ -1,6 +1,6 @@ === tests/cases/compiler/typeParameterHasSelfAsConstraint.ts === function foo(x: T): number { ->foo : (x: T) => number +>foo : (x: T) => number >T : T >T : T >x : T diff --git a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.types b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.types index ef5773a81a9..e5266083db2 100644 --- a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.types +++ b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.types @@ -32,14 +32,14 @@ interface I2 { } >T : T function f() { } ->f : () => void +>f : () => void >U : U >T : T >T : T >U : U function f2() { } ->f2 : () => void +>f2 : () => void >T : T >U : U >U : U @@ -48,7 +48,7 @@ function f2() { } >T : T var a: { ->a : { (): void; (): void; } +>a : { (): void; (): void; } (): void; >U : U @@ -66,16 +66,16 @@ var a: { } var b = () => { } ->b : () => void ->() => { } : () => void +>b : () => void +>() => { } : () => void >U : U >T : T >T : T >U : U var b2 = () => { } ->b2 : () => void ->() => { } : () => void +>b2 : () => void +>() => { } : () => void >T : T >U : U >U : U From 7233cde0dc61156a98b8d290449a183e986dc22b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 14:49:22 -0700 Subject: [PATCH 3/8] Simplify logic in getBaseConstraint --- src/compiler/checker.ts | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c56d39a9ffc..c1366745c39 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4370,8 +4370,7 @@ namespace ts { case TypeSystemPropertyName.ResolvedReturnType: return !!(target).resolvedReturnType; case TypeSystemPropertyName.ImmediateBaseConstraint: - const bc = (target).immediateBaseConstraint; - return !!bc && bc !== circularConstraintType; + return !!(target).immediateBaseConstraint; } return Debug.fail("Unhandled TypeSystemPropertyName " + propertyName); } @@ -6987,30 +6986,26 @@ namespace ts { * circularly references the type variable. */ function getResolvedBaseConstraint(type: InstantiableType | UnionOrIntersectionType): Type { - let circular: boolean | undefined; - if (!type.resolvedBaseConstraint) { - const constraint = getBaseConstraint(type); - type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type); + return type.resolvedBaseConstraint || + (type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type)); + + function getImmediateBaseConstraint(t: Type): Type { + if (!t.immediateBaseConstraint) { + if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) { + return circularConstraintType; + } + let result = computeBaseConstraint(getSimplifiedType(t)); + if (!popTypeResolution()) { + result = circularConstraintType; + } + t.immediateBaseConstraint = result || noConstraintType; + } + return t.immediateBaseConstraint; } - return type.resolvedBaseConstraint; function getBaseConstraint(t: Type): Type | undefined { - if (t.immediateBaseConstraint) { - return t.immediateBaseConstraint === noConstraintType ? undefined : t.immediateBaseConstraint; - } - if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) { - circular = true; - t.immediateBaseConstraint = circularConstraintType; - return undefined; - } - const result = computeBaseConstraint(getSimplifiedType(t)); - if (!popTypeResolution()) { - circular = true; - t.immediateBaseConstraint = circularConstraintType; - return undefined; - } - t.immediateBaseConstraint = !result ? noConstraintType : result; - return result; + const c = getImmediateBaseConstraint(t); + return c !== noConstraintType && c !== circularConstraintType ? c : undefined; } function computeBaseConstraint(t: Type): Type | undefined { From 0fd89399cced8b170e73777ee1efa4bef2176bd1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 14:49:45 -0700 Subject: [PATCH 4/8] Accept new baselines --- .../typeParameterIndirectlyConstrainedToItself.errors.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.errors.txt b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.errors.txt index ac7b58bb846..4cfa9da2133 100644 --- a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.errors.txt +++ b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.errors.txt @@ -23,12 +23,11 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterInd tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(16,21): error TS2313: Type parameter 'T' has a circular constraint. tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(16,34): error TS2313: Type parameter 'U' has a circular constraint. tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(16,47): error TS2313: Type parameter 'V' has a circular constraint. -tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(18,19): error TS2313: Type parameter 'U' has a circular constraint. tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(18,32): error TS2313: Type parameter 'T' has a circular constraint. tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(18,45): error TS2313: Type parameter 'V' has a circular constraint. -==== tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts (28 errors) ==== +==== tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts (27 errors) ==== class C { } ~ !!! error TS2313: Type parameter 'U' has a circular constraint. @@ -97,8 +96,6 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterInd !!! error TS2313: Type parameter 'V' has a circular constraint. class D { } - ~ -!!! error TS2313: Type parameter 'U' has a circular constraint. ~ !!! error TS2313: Type parameter 'T' has a circular constraint. ~ From 1fd1de962561583c63460b1a6ec7ee262527abcf Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 15:27:39 -0700 Subject: [PATCH 5/8] More simplification + consistent use of getConstraintOfTypeParameter --- src/compiler/checker.ts | 17 ++++------------- src/compiler/symbolWalker.ts | 4 ++-- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c1366745c39..e7d26d1eab6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -249,7 +249,7 @@ namespace ts { getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, - getConstraintFromTypeParameter, + getConstraintOfTypeParameter, getFirstIdentifier, ), getAmbientModules, @@ -6951,21 +6951,12 @@ namespace ts { return undefined; } - function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type: Type) { + function getBaseConstraintOfType(type: Type): Type | undefined { if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) { const constraint = getResolvedBaseConstraint(type); - if (constraint !== noConstraintType && constraint !== circularConstraintType) { - return constraint; - } + return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined; } - } - - function getBaseConstraintOfType(type: Type): Type | undefined { - const constraint = getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type); - if (!constraint && type.flags & TypeFlags.Index) { - return keyofConstraintType; - } - return constraint; + return type.flags & TypeFlags.Index ? keyofConstraintType : undefined; } /** diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index cce6739d359..1f6930076be 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -9,7 +9,7 @@ namespace ts { getTypeOfSymbol: (sym: Symbol) => Type, getResolvedSymbol: (node: Node) => Symbol, getIndexTypeOfStructuredType: (type: Type, kind: IndexKind) => Type | undefined, - getConstraintFromTypeParameter: (typeParameter: TypeParameter) => Type | undefined, + getConstraintOfTypeParameter: (typeParameter: TypeParameter) => Type | undefined, getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier) { return getSymbolWalker; @@ -93,7 +93,7 @@ namespace ts { } function visitTypeParameter(type: TypeParameter): void { - visitType(getConstraintFromTypeParameter(type)); + visitType(getConstraintOfTypeParameter(type)); } function visitUnionOrIntersectionType(type: UnionOrIntersectionType): void { From aeae05eaf5fab45fa30c365860c28a83320d0a55 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 15:33:02 -0700 Subject: [PATCH 6/8] Add regression test --- .../typeParameterIndirectlyConstrainedToItself.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts index d5e5ae9208e..63ed22d4865 100644 --- a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts +++ b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts @@ -15,4 +15,9 @@ var a: { var b = () => { } var b2 = () => { } -class D { } \ No newline at end of file +class D { } + +// Repro from #25740 + +type Foo = [T] extends [number] ? {} : {}; +function foo>() {} From fe9ca725b92a2ca94e430abfe1c08efcb23c2627 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 15:33:10 -0700 Subject: [PATCH 7/8] Accept new baselines --- ...arameterIndirectlyConstrainedToItself.errors.txt | 13 +++++++++++-- .../typeParameterIndirectlyConstrainedToItself.js | 9 ++++++++- ...peParameterIndirectlyConstrainedToItself.symbols | 13 +++++++++++++ ...typeParameterIndirectlyConstrainedToItself.types | 13 +++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.errors.txt b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.errors.txt index 4cfa9da2133..8ca5c51ea2d 100644 --- a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.errors.txt +++ b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.errors.txt @@ -25,9 +25,10 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterInd tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(16,47): error TS2313: Type parameter 'V' has a circular constraint. tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(18,32): error TS2313: Type parameter 'T' has a circular constraint. tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(18,45): error TS2313: Type parameter 'V' has a circular constraint. +tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(23,24): error TS2313: Type parameter 'S' has a circular constraint. -==== tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts (27 errors) ==== +==== tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts (28 errors) ==== class C { } ~ !!! error TS2313: Type parameter 'U' has a circular constraint. @@ -99,4 +100,12 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterInd ~ !!! error TS2313: Type parameter 'T' has a circular constraint. ~ -!!! error TS2313: Type parameter 'V' has a circular constraint. \ No newline at end of file +!!! error TS2313: Type parameter 'V' has a circular constraint. + + // Repro from #25740 + + type Foo = [T] extends [number] ? {} : {}; + function foo>() {} + ~~~~~~ +!!! error TS2313: Type parameter 'S' has a circular constraint. + \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.js b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.js index 58d559d7fee..b6332f8011b 100644 --- a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.js +++ b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.js @@ -16,7 +16,13 @@ var a: { var b = () => { } var b2 = () => { } -class D { } +class D { } + +// Repro from #25740 + +type Foo = [T] extends [number] ? {} : {}; +function foo>() {} + //// [typeParameterIndirectlyConstrainedToItself.js] var C = /** @class */ (function () { @@ -39,3 +45,4 @@ var D = /** @class */ (function () { } return D; }()); +function foo() { } diff --git a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.symbols b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.symbols index f120f7251c6..3a8305e4012 100644 --- a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.symbols +++ b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.symbols @@ -90,3 +90,16 @@ class D { } >V : Symbol(V, Decl(typeParameterIndirectlyConstrainedToItself.ts, 17, 33)) >T : Symbol(T, Decl(typeParameterIndirectlyConstrainedToItself.ts, 17, 20)) +// Repro from #25740 + +type Foo = [T] extends [number] ? {} : {}; +>Foo : Symbol(Foo, Decl(typeParameterIndirectlyConstrainedToItself.ts, 17, 50)) +>T : Symbol(T, Decl(typeParameterIndirectlyConstrainedToItself.ts, 21, 9)) +>T : Symbol(T, Decl(typeParameterIndirectlyConstrainedToItself.ts, 21, 9)) + +function foo>() {} +>foo : Symbol(foo, Decl(typeParameterIndirectlyConstrainedToItself.ts, 21, 45)) +>S : Symbol(S, Decl(typeParameterIndirectlyConstrainedToItself.ts, 22, 13)) +>Foo : Symbol(Foo, Decl(typeParameterIndirectlyConstrainedToItself.ts, 17, 50)) +>S : Symbol(S, Decl(typeParameterIndirectlyConstrainedToItself.ts, 22, 13)) + diff --git a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.types b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.types index e5266083db2..00ef88dc52b 100644 --- a/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.types +++ b/tests/baselines/reference/typeParameterIndirectlyConstrainedToItself.types @@ -92,3 +92,16 @@ class D { } >V : V >T : T +// Repro from #25740 + +type Foo = [T] extends [number] ? {} : {}; +>Foo : Foo +>T : T +>T : T + +function foo>() {} +>foo : () => void +>S : S +>Foo : Foo +>S : S + From ff6059abf69e6303675e54eae1fae6476ae8b19c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jul 2018 17:58:03 -0700 Subject: [PATCH 8/8] Address CR feedback --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e7d26d1eab6..978fab5bfa2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4372,7 +4372,7 @@ namespace ts { case TypeSystemPropertyName.ImmediateBaseConstraint: return !!(target).immediateBaseConstraint; } - return Debug.fail("Unhandled TypeSystemPropertyName " + propertyName); + return Debug.assertNever(propertyName); } // Pop an entry from the type resolution stack and return its associated result value. The result value will @@ -7879,6 +7879,7 @@ namespace ts { return inferences && getIntersectionType(inferences); } + /** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */ function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type | undefined { if (!typeParameter.constraint) { if (typeParameter.target) {