Skip to content

Commit 15796c9

Browse files
committed
Generalize performance enhancement
1 parent 49f6b02 commit 15796c9

17 files changed

+94
-62
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18219,18 +18219,18 @@ namespace ts {
1821918219
return result;
1822018220
}
1822118221

18222-
if (isNonAugmentingArraySubtype(source) && isArrayType(target)) {
18223-
let sourceBase = getBaseTypes((source as TypeReference).target as InterfaceType)[0];
18224-
if (length(target.resolvedTypeArguments) === 2) {
18225-
sourceBase = getTypeWithThisArgument(sourceBase, ((source as TypeReference).target as InterfaceType).thisType);
18222+
let sourceBase = getSingleBaseForNonAugmentingSubtype(source);
18223+
if (sourceBase) {
18224+
if (getObjectFlags(target) & ObjectFlags.Reference && length(getTypeArguments((target as TypeReference))) > length((target as TypeReference).target.typeParameters)) {
18225+
sourceBase = getTypeWithThisArgument(sourceBase, last(getTypeArguments(source as TypeReference)));
1822618226
}
1822718227
return isRelatedTo(sourceBase, target, reportErrors);
1822818228
}
1822918229

18230-
if (isArrayType(source) && isNonAugmentingArraySubtype(target)) {
18231-
let targetBase = getBaseTypes((target as TypeReference).target as InterfaceType)[0];
18232-
if (length(source.resolvedTypeArguments) === 2) {
18233-
targetBase = getTypeWithThisArgument(targetBase, ((target as TypeReference).target as InterfaceType).thisType);
18230+
let targetBase = getSingleBaseForNonAugmentingSubtype(target);
18231+
if (targetBase) {
18232+
if (getObjectFlags(source) & ObjectFlags.Reference && length(getTypeArguments((source as TypeReference))) > length((source as TypeReference).target.typeParameters)) {
18233+
targetBase = getTypeWithThisArgument(targetBase, last(getTypeArguments(target as TypeReference)));
1823418234
}
1823518235
return isRelatedTo(source, targetBase, reportErrors);
1823618236
}
@@ -19917,22 +19917,19 @@ namespace ts {
1991719917
return isArrayType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
1991819918
}
1991919919

19920-
function isNonAugmentingArraySubtype(type: Type) {
19920+
function getSingleBaseForNonAugmentingSubtype(type: Type) {
1992119921
if (!(getObjectFlags(type) & ObjectFlags.Reference) || !(getObjectFlags((type as TypeReference).target) & ObjectFlags.ClassOrInterface)) {
19922-
return false;
19922+
return undefined;
1992319923
}
1992419924
const target = (type as TypeReference).target as InterfaceType;
1992519925
const bases = getBaseTypes(target);
1992619926
if (bases.length !== 1) {
19927-
return false;
19928-
}
19929-
if (!isArrayType(bases[0])) {
19930-
return false;
19927+
return undefined;
1993119928
}
1993219929
if (getMembersOfSymbol(type.symbol).size) {
19933-
return false; // If the interface has any members, they may subtype members in the base, so we should do a full structural comparison
19930+
return undefined; // If the interface has any members, they may subtype members in the base, so we should do a full structural comparison
1993419931
}
19935-
return true;
19932+
return !length(target.typeParameters) ? bases[0] : instantiateType(bases[0], createTypeMapper(target.typeParameters!, getTypeArguments(type as TypeReference).slice(0, target.typeParameters!.length)));
1993619933
}
1993719934

1993819935
function isEmptyArrayLiteralType(type: Type): boolean {

tests/baselines/reference/assignmentCompatWithObjectMembersAccessibility.errors.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
1717
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(81,5): error TS2322: Type 'Base' is not assignable to type '{ foo: string; }'.
1818
Property 'foo' is private in type 'Base' but not in type '{ foo: string; }'.
1919
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(82,5): error TS2322: Type 'I' is not assignable to type '{ foo: string; }'.
20-
Property 'foo' is private in type 'I' but not in type '{ foo: string; }'.
20+
Type 'Base' is not assignable to type '{ foo: string; }'.
2121
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(84,5): error TS2322: Type 'E' is not assignable to type '{ foo: string; }'.
2222
Property 'foo' is private in type 'E' but not in type '{ foo: string; }'.
2323
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(86,5): error TS2322: Type '{ foo: string; }' is not assignable to type 'Base'.
@@ -27,23 +27,23 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
2727
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(89,5): error TS2322: Type 'E' is not assignable to type 'Base'.
2828
Types have separate declarations of a private property 'foo'.
2929
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(92,5): error TS2322: Type '{ foo: string; }' is not assignable to type 'I'.
30-
Property 'foo' is private in type 'I' but not in type '{ foo: string; }'.
30+
Type '{ foo: string; }' is not assignable to type 'Base'.
3131
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(94,5): error TS2322: Type 'D' is not assignable to type 'I'.
32-
Property 'foo' is private in type 'I' but not in type 'D'.
32+
Type 'D' is not assignable to type 'Base'.
3333
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(95,5): error TS2322: Type 'E' is not assignable to type 'I'.
34-
Types have separate declarations of a private property 'foo'.
34+
Type 'E' is not assignable to type 'Base'.
3535
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(99,5): error TS2322: Type 'Base' is not assignable to type 'D'.
3636
Property 'foo' is private in type 'Base' but not in type 'D'.
3737
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(100,5): error TS2322: Type 'I' is not assignable to type 'D'.
38-
Property 'foo' is private in type 'I' but not in type 'D'.
38+
Type 'Base' is not assignable to type 'D'.
3939
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(101,5): error TS2322: Type 'E' is not assignable to type 'D'.
4040
Property 'foo' is private in type 'E' but not in type 'D'.
4141
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(103,5): error TS2322: Type '{ foo: string; }' is not assignable to type 'E'.
4242
Property 'foo' is private in type 'E' but not in type '{ foo: string; }'.
4343
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(104,5): error TS2322: Type 'Base' is not assignable to type 'E'.
4444
Types have separate declarations of a private property 'foo'.
4545
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(105,5): error TS2322: Type 'I' is not assignable to type 'E'.
46-
Types have separate declarations of a private property 'foo'.
46+
Type 'Base' is not assignable to type 'E'.
4747
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithObjectMembersAccessibility.ts(106,5): error TS2322: Type 'D' is not assignable to type 'E'.
4848
Property 'foo' is private in type 'E' but not in type 'D'.
4949

@@ -160,7 +160,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
160160
a = i; // error
161161
~
162162
!!! error TS2322: Type 'I' is not assignable to type '{ foo: string; }'.
163-
!!! error TS2322: Property 'foo' is private in type 'I' but not in type '{ foo: string; }'.
163+
!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; }'.
164164
a = d;
165165
a = e; // error
166166
~
@@ -185,16 +185,16 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
185185
i = a; // error
186186
~
187187
!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'I'.
188-
!!! error TS2322: Property 'foo' is private in type 'I' but not in type '{ foo: string; }'.
188+
!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'Base'.
189189
i = b;
190190
i = d; // error
191191
~
192192
!!! error TS2322: Type 'D' is not assignable to type 'I'.
193-
!!! error TS2322: Property 'foo' is private in type 'I' but not in type 'D'.
193+
!!! error TS2322: Type 'D' is not assignable to type 'Base'.
194194
i = e; // error
195195
~
196196
!!! error TS2322: Type 'E' is not assignable to type 'I'.
197-
!!! error TS2322: Types have separate declarations of a private property 'foo'.
197+
!!! error TS2322: Type 'E' is not assignable to type 'Base'.
198198
i = i;
199199

200200
d = a;
@@ -205,7 +205,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
205205
d = i; // error
206206
~
207207
!!! error TS2322: Type 'I' is not assignable to type 'D'.
208-
!!! error TS2322: Property 'foo' is private in type 'I' but not in type 'D'.
208+
!!! error TS2322: Type 'Base' is not assignable to type 'D'.
209209
d = e; // error
210210
~
211211
!!! error TS2322: Type 'E' is not assignable to type 'D'.
@@ -222,7 +222,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
222222
e = i; // errror
223223
~
224224
!!! error TS2322: Type 'I' is not assignable to type 'E'.
225-
!!! error TS2322: Types have separate declarations of a private property 'foo'.
225+
!!! error TS2322: Type 'Base' is not assignable to type 'E'.
226226
e = d; // errror
227227
~
228228
!!! error TS2322: Type 'D' is not assignable to type 'E'.

tests/baselines/reference/checkJsxChildrenProperty5.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
tests/cases/conformance/jsx/file.tsx(20,10): error TS2741: Property 'children' is missing in type '{ a: number; b: string; }' but required in type 'Prop'.
2-
tests/cases/conformance/jsx/file.tsx(25,9): error TS2740: Type 'Element' is missing the following properties from type 'Button': render, setState, forceUpdate, state, and 2 more.
2+
tests/cases/conformance/jsx/file.tsx(25,9): error TS2322: Type 'Element' is not assignable to type 'Button'.
3+
Type 'ReactElement<any>' is missing the following properties from type 'Button': render, setState, forceUpdate, state, and 2 more.
34
tests/cases/conformance/jsx/file.tsx(29,10): error TS2740: Type 'typeof Button' is missing the following properties from type 'Button': render, setState, forceUpdate, props, and 3 more.
45

56

@@ -33,7 +34,8 @@ tests/cases/conformance/jsx/file.tsx(29,10): error TS2740: Type 'typeof Button'
3334
<Comp a={10} b="hi">
3435
<Button />
3536
~~~~~~~~~~
36-
!!! error TS2740: Type 'Element' is missing the following properties from type 'Button': render, setState, forceUpdate, state, and 2 more.
37+
!!! error TS2322: Type 'Element' is not assignable to type 'Button'.
38+
!!! error TS2322: Type 'ReactElement<any>' is missing the following properties from type 'Button': render, setState, forceUpdate, state, and 2 more.
3739
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:6:5: The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & Prop'
3840
</Comp>;
3941
let k2 =

tests/baselines/reference/checkJsxChildrenProperty7.errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
tests/cases/conformance/jsx/file.tsx(24,40): error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
2+
Type 'string' is not assignable to type 'ReactElement<any>'.
23
tests/cases/conformance/jsx/file.tsx(26,22): error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
34
tests/cases/conformance/jsx/file.tsx(27,30): error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
45

@@ -30,6 +31,7 @@ tests/cases/conformance/jsx/file.tsx(27,30): error TS2747: 'Comp' components don
3031
let k1 = <Comp a={10} b="hi"><Button /> <AnotherButton /></Comp>;
3132
~~
3233
!!! error TS2747: 'Comp' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'Element | Element[]'.
34+
!!! error TS2747: Type 'string' is not assignable to type 'ReactElement<any>'.
3335
let k2 = <Comp a={10} b="hi"><Button />
3436
<AnotherButton /> </Comp>;
3537
~~

tests/baselines/reference/classImplementsClass4.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
tests/cases/compiler/classImplementsClass4.ts(5,7): error TS2720: Class 'C' incorrectly implements class 'A'. Did you mean to extend 'A' and inherit its members as a subclass?
22
Property 'x' is missing in type 'C' but required in type 'A'.
3-
tests/cases/compiler/classImplementsClass4.ts(16,1): error TS2741: Property 'x' is missing in type 'C' but required in type 'C2'.
3+
tests/cases/compiler/classImplementsClass4.ts(16,1): error TS2322: Type 'C' is not assignable to type 'C2'.
4+
Property 'x' is missing in type 'C' but required in type 'A'.
45

56

67
==== tests/cases/compiler/classImplementsClass4.ts (2 errors) ====
@@ -25,5 +26,6 @@ tests/cases/compiler/classImplementsClass4.ts(16,1): error TS2741: Property 'x'
2526
c = c2;
2627
c2 = c;
2728
~~
28-
!!! error TS2741: Property 'x' is missing in type 'C' but required in type 'C2'.
29+
!!! error TS2322: Type 'C' is not assignable to type 'C2'.
30+
!!! error TS2322: Property 'x' is missing in type 'C' but required in type 'A'.
2931
!!! related TS2728 tests/cases/compiler/classImplementsClass4.ts:2:13: 'x' is declared here.

tests/baselines/reference/classImplementsClass5.errors.txt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
tests/cases/compiler/classImplementsClass5.ts(5,7): error TS2720: Class 'C' incorrectly implements class 'A'. Did you mean to extend 'A' and inherit its members as a subclass?
22
Types have separate declarations of a private property 'x'.
33
tests/cases/compiler/classImplementsClass5.ts(16,1): error TS2322: Type 'C2' is not assignable to type 'C'.
4-
Types have separate declarations of a private property 'x'.
4+
Type 'A' is not assignable to type 'C'.
5+
Types have separate declarations of a private property 'x'.
56
tests/cases/compiler/classImplementsClass5.ts(17,1): error TS2322: Type 'C' is not assignable to type 'C2'.
6-
Types have separate declarations of a private property 'x'.
7+
Type 'C' is not assignable to type 'A'.
8+
Types have separate declarations of a private property 'x'.
79

810

911
==== tests/cases/compiler/classImplementsClass5.ts (3 errors) ====
@@ -28,8 +30,10 @@ tests/cases/compiler/classImplementsClass5.ts(17,1): error TS2322: Type 'C' is n
2830
c = c2;
2931
~
3032
!!! error TS2322: Type 'C2' is not assignable to type 'C'.
31-
!!! error TS2322: Types have separate declarations of a private property 'x'.
33+
!!! error TS2322: Type 'A' is not assignable to type 'C'.
34+
!!! error TS2322: Types have separate declarations of a private property 'x'.
3235
c2 = c;
3336
~~
3437
!!! error TS2322: Type 'C' is not assignable to type 'C2'.
35-
!!! error TS2322: Types have separate declarations of a private property 'x'.
38+
!!! error TS2322: Type 'C' is not assignable to type 'A'.
39+
!!! error TS2322: Types have separate declarations of a private property 'x'.

tests/baselines/reference/crashInsourcePropertyIsRelatableToTargetProperty.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
tests/cases/compiler/crashInsourcePropertyIsRelatableToTargetProperty.ts(9,5): error TS2741: Property 'x' is missing in type '(x: "hi", items: string[]) => typeof foo' but required in type 'D'.
1+
tests/cases/compiler/crashInsourcePropertyIsRelatableToTargetProperty.ts(9,5): error TS2322: Type '(x: "hi", items: string[]) => typeof foo' is not assignable to type 'D'.
2+
Property 'x' is missing in type '(x: "hi", items: string[]) => typeof foo' but required in type 'C'.
23

34

45
==== tests/cases/compiler/crashInsourcePropertyIsRelatableToTargetProperty.ts (1 errors) ====
@@ -12,6 +13,7 @@ tests/cases/compiler/crashInsourcePropertyIsRelatableToTargetProperty.ts(9,5): e
1213
}
1314
var a: D = foo("hi", []);
1415
~
15-
!!! error TS2741: Property 'x' is missing in type '(x: "hi", items: string[]) => typeof foo' but required in type 'D'.
16+
!!! error TS2322: Type '(x: "hi", items: string[]) => typeof foo' is not assignable to type 'D'.
17+
!!! error TS2322: Property 'x' is missing in type '(x: "hi", items: string[]) => typeof foo' but required in type 'C'.
1618
!!! related TS2728 tests/cases/compiler/crashInsourcePropertyIsRelatableToTargetProperty.ts:2:13: 'x' is declared here.
1719

tests/baselines/reference/implementingAnInterfaceExtendingClassWithProtecteds.errors.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ tests/cases/conformance/interfaces/interfacesExtendingClasses/implementingAnInte
77
tests/cases/conformance/interfaces/interfacesExtendingClasses/implementingAnInterfaceExtendingClassWithProtecteds.ts(21,7): error TS2420: Class 'Bar4' incorrectly implements interface 'I'.
88
Property 'x' is protected but type 'Bar4' is not a class derived from 'Foo'.
99
tests/cases/conformance/interfaces/interfacesExtendingClasses/implementingAnInterfaceExtendingClassWithProtecteds.ts(26,7): error TS2420: Class 'Bar5' incorrectly implements interface 'I'.
10-
Property 'y' is missing in type 'Bar5' but required in type 'I'.
10+
Type 'Foo' is not assignable to type 'I'.
11+
Property 'y' is missing in type 'Foo' but required in type 'I'.
1112
tests/cases/conformance/interfaces/interfacesExtendingClasses/implementingAnInterfaceExtendingClassWithProtecteds.ts(29,7): error TS2420: Class 'Bar6' incorrectly implements interface 'I'.
1213
Property 'y' is protected in type 'Bar6' but public in type 'I'.
1314

@@ -54,7 +55,8 @@ tests/cases/conformance/interfaces/interfacesExtendingClasses/implementingAnInte
5455
class Bar5 extends Foo implements I { // error
5556
~~~~
5657
!!! error TS2420: Class 'Bar5' incorrectly implements interface 'I'.
57-
!!! error TS2420: Property 'y' is missing in type 'Bar5' but required in type 'I'.
58+
!!! error TS2420: Type 'Foo' is not assignable to type 'I'.
59+
!!! error TS2420: Property 'y' is missing in type 'Foo' but required in type 'I'.
5860
!!! related TS2728 tests/cases/conformance/interfaces/interfacesExtendingClasses/implementingAnInterfaceExtendingClassWithProtecteds.ts:6:5: 'y' is declared here.
5961
}
6062

0 commit comments

Comments
 (0)