Skip to content

Commit 4ae62c3

Browse files
committed
getConstraintDeclaration gets the first declaration with a constraint, rather than just the first declaration
1 parent 038d951 commit 4ae62c3

6 files changed

+131
-14
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8972,8 +8972,7 @@ namespace ts {
89728972
}
89738973

89748974
function getConstraintDeclaration(type: TypeParameter) {
8975-
const decl = type.symbol && getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter);
8976-
return decl && getEffectiveConstraintOfTypeParameter(decl);
8975+
return mapDefined(filter(type.symbol && type.symbol.declarations, isTypeParameterDeclaration), getEffectiveConstraintOfTypeParameter)[0];
89778976
}
89788977

89798978
function getInferredTypeParameterConstraint(typeParameter: TypeParameter) {
@@ -29233,11 +29232,10 @@ namespace ts {
2923329232
const constraint = getEffectiveConstraintOfTypeParameter(source);
2923429233
const sourceConstraint = constraint && getTypeFromTypeNode(constraint);
2923529234
const targetConstraint = getConstraintOfTypeParameter(target);
29236-
if (sourceConstraint) {
29237-
// relax check if later interface augmentation has no constraint
29238-
if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
29239-
return false;
29240-
}
29235+
// relax check if later interface augmentation has no constraint, it's more broad and is OK to merge with
29236+
// a more constrained interface (this could be generalized to a full heirarchy check, but that's maybe overkill)
29237+
if (sourceConstraint && targetConstraint && !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
29238+
return false;
2924129239
}
2924229240

2924329241
// If the type parameter node has a default and it is not identical to the default
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [tests/cases/compiler/interfaceMergedUnconstrainedNoErrorIrrespectiveOfOrder.ts] ////
2+
3+
//// [working.ts]
4+
// minmal samples from #33395
5+
export namespace ns {
6+
interface Function<T extends (...args: any) => any> {
7+
throttle(): Function<T>;
8+
}
9+
interface Function<T> {
10+
unary(): Function<() => ReturnType<T>>;
11+
}
12+
}
13+
//// [regression.ts]
14+
export namespace ns {
15+
interface Function<T> {
16+
unary(): Function<() => ReturnType<T>>;
17+
}
18+
interface Function<T extends (...args: any) => any> {
19+
throttle(): Function<T>;
20+
}
21+
}
22+
23+
//// [working.js]
24+
"use strict";
25+
exports.__esModule = true;
26+
//// [regression.js]
27+
"use strict";
28+
exports.__esModule = true;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
=== tests/cases/compiler/working.ts ===
2+
// minmal samples from #33395
3+
export namespace ns {
4+
>ns : Symbol(ns, Decl(working.ts, 0, 0))
5+
6+
interface Function<T extends (...args: any) => any> {
7+
>Function : Symbol(Function, Decl(working.ts, 1, 21), Decl(working.ts, 4, 5))
8+
>T : Symbol(T, Decl(working.ts, 2, 23), Decl(working.ts, 5, 23))
9+
>args : Symbol(args, Decl(working.ts, 2, 34))
10+
11+
throttle(): Function<T>;
12+
>throttle : Symbol(Function.throttle, Decl(working.ts, 2, 57))
13+
>Function : Symbol(Function, Decl(working.ts, 1, 21), Decl(working.ts, 4, 5))
14+
>T : Symbol(T, Decl(working.ts, 2, 23), Decl(working.ts, 5, 23))
15+
}
16+
interface Function<T> {
17+
>Function : Symbol(Function, Decl(working.ts, 1, 21), Decl(working.ts, 4, 5))
18+
>T : Symbol(T, Decl(working.ts, 2, 23), Decl(working.ts, 5, 23))
19+
20+
unary(): Function<() => ReturnType<T>>;
21+
>unary : Symbol(Function.unary, Decl(working.ts, 5, 27))
22+
>Function : Symbol(Function, Decl(working.ts, 1, 21), Decl(working.ts, 4, 5))
23+
>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --))
24+
>T : Symbol(T, Decl(working.ts, 2, 23), Decl(working.ts, 5, 23))
25+
}
26+
}
27+
=== tests/cases/compiler/regression.ts ===
28+
export namespace ns {
29+
>ns : Symbol(ns, Decl(regression.ts, 0, 0))
30+
31+
interface Function<T> {
32+
>Function : Symbol(Function, Decl(regression.ts, 0, 21), Decl(regression.ts, 3, 5))
33+
>T : Symbol(T, Decl(regression.ts, 1, 23), Decl(regression.ts, 4, 23))
34+
35+
unary(): Function<() => ReturnType<T>>;
36+
>unary : Symbol(Function.unary, Decl(regression.ts, 1, 27))
37+
>Function : Symbol(Function, Decl(regression.ts, 0, 21), Decl(regression.ts, 3, 5))
38+
>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --))
39+
>T : Symbol(T, Decl(regression.ts, 1, 23), Decl(regression.ts, 4, 23))
40+
}
41+
interface Function<T extends (...args: any) => any> {
42+
>Function : Symbol(Function, Decl(regression.ts, 0, 21), Decl(regression.ts, 3, 5))
43+
>T : Symbol(T, Decl(regression.ts, 1, 23), Decl(regression.ts, 4, 23))
44+
>args : Symbol(args, Decl(regression.ts, 4, 34))
45+
46+
throttle(): Function<T>;
47+
>throttle : Symbol(Function.throttle, Decl(regression.ts, 4, 57))
48+
>Function : Symbol(Function, Decl(regression.ts, 0, 21), Decl(regression.ts, 3, 5))
49+
>T : Symbol(T, Decl(regression.ts, 1, 23), Decl(regression.ts, 4, 23))
50+
}
51+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/compiler/working.ts ===
2+
// minmal samples from #33395
3+
export namespace ns {
4+
interface Function<T extends (...args: any) => any> {
5+
>args : any
6+
7+
throttle(): Function<T>;
8+
>throttle : () => Function<T>
9+
}
10+
interface Function<T> {
11+
unary(): Function<() => ReturnType<T>>;
12+
>unary : () => Function<() => ReturnType<T>>
13+
}
14+
}
15+
=== tests/cases/compiler/regression.ts ===
16+
export namespace ns {
17+
interface Function<T> {
18+
unary(): Function<() => ReturnType<T>>;
19+
>unary : () => Function<() => ReturnType<T>>
20+
}
21+
interface Function<T extends (...args: any) => any> {
22+
>args : any
23+
24+
throttle(): Function<T>;
25+
>throttle : () => Function<T>
26+
}
27+
}

tests/baselines/reference/twoGenericInterfacesWithDifferentConstraints.errors.txt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi
44
tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(14,15): error TS2428: All declarations of 'B' must have identical type parameters.
55
tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(32,22): error TS2428: All declarations of 'A' must have identical type parameters.
66
tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(38,22): error TS2428: All declarations of 'A' must have identical type parameters.
7-
tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(53,11): error TS2428: All declarations of 'C' must have identical type parameters.
8-
tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts(57,11): error TS2428: All declarations of 'C' must have identical type parameters.
97

108

11-
==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (8 errors) ====
9+
==== tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDifferentConstraints.ts (6 errors) ====
1210
interface A<T extends Date> {
1311
~
1412
!!! error TS2428: All declarations of 'A' must have identical type parameters.
@@ -74,14 +72,10 @@ tests/cases/conformance/interfaces/declarationMerging/twoGenericInterfacesWithDi
7472
}
7573

7674
interface C<T> {
77-
~
78-
!!! error TS2428: All declarations of 'C' must have identical type parameters.
7975
x: T;
8076
}
8177

8278
interface C<T extends number> { // error
83-
~
84-
!!! error TS2428: All declarations of 'C' must have identical type parameters.
8579
y: T;
8680
}
8781

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @filename: working.ts
2+
// minmal samples from #33395
3+
export namespace ns {
4+
interface Function<T extends (...args: any) => any> {
5+
throttle(): Function<T>;
6+
}
7+
interface Function<T> {
8+
unary(): Function<() => ReturnType<T>>;
9+
}
10+
}
11+
// @filename: regression.ts
12+
export namespace ns {
13+
interface Function<T> {
14+
unary(): Function<() => ReturnType<T>>;
15+
}
16+
interface Function<T extends (...args: any) => any> {
17+
throttle(): Function<T>;
18+
}
19+
}

0 commit comments

Comments
 (0)