From 205653adde9dfe9ab57fe71a9e557b19bf03b03c 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 f1e282845d5..7cdc083874f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3715,7 +3715,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); } @@ -4363,28 +4363,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); } @@ -9145,7 +9140,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); } @@ -12092,7 +12087,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 { @@ -17620,7 +17615,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) { @@ -19261,7 +19256,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; @@ -25164,7 +25159,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 fb484c0d656d93054751db51ce122d9ed2eabed9 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 e48762d178f54bd664557ce4868042b5abb50861 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 7cdc083874f..ff65929d52a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4377,8 +4377,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); } @@ -6966,30 +6965,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 a581eae955a1d0ce4ada782f463c5648b23772e2 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 483ed8fb5049be4dcc89ef5e79b66e013139c21a 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 ff65929d52a..3ee66280aeb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -250,7 +250,7 @@ namespace ts { getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, - getConstraintFromTypeParameter, + getConstraintOfTypeParameter, getFirstIdentifier, ), getAmbientModules, @@ -6930,21 +6930,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 8738feacfd589854f3e73ace1cce0c1cd891a809 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 616a648b4b34c07c54342d1af2773b6bce88d128 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 2da65c20b0eccd2a92effa6b7a77ed686286a144 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 3ee66280aeb..c66d85beb93 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4379,7 +4379,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 @@ -7858,6 +7858,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) {