Skip to content

Commit 85c9d2c

Browse files
authored
Use faster, stricter prop type comparison when merging props in union prop creation (#43696)
* Use faster, stricter prop type comparison when merging props in union prop creation * Be better at determining this usage in methods, accept baselines * Small style change
1 parent 1a04b17 commit 85c9d2c

17 files changed

+326
-43
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11662,7 +11662,7 @@ namespace ts {
1166211662
// If the symbols are instances of one another with identical types - consider the symbols
1166311663
// equivalent and just use the first one, which thus allows us to avoid eliding private
1166411664
// members when intersecting a (this-)instantiations of a class with it's raw base or another instance
11665-
if (isInstantiation && isPropertyIdenticalTo(singleProp, prop)) {
11665+
if (isInstantiation && compareProperties(singleProp, prop, (a, b) => a === b ? Ternary.True : Ternary.False) === Ternary.True) {
1166611666
// If we merged instantiations of a generic type, we replicate the symbol parent resetting behavior we used
1166711667
// to do when we recorded multiple distinct symbols so that we still get, eg, `Array<T>.length` printed
1166811668
// back and not `Array<string>.length` when we're looking at a `.length` access on a `string[] | number[]`
@@ -15870,8 +15870,9 @@ namespace ts {
1587015870
outerTypeParameters = addRange(outerTypeParameters, templateTagParameters);
1587115871
}
1587215872
typeParameters = outerTypeParameters || emptyArray;
15873-
typeParameters = (target.objectFlags & ObjectFlags.Reference || target.symbol.flags & SymbolFlags.TypeLiteral) && !target.aliasTypeArguments ?
15874-
filter(typeParameters, tp => isTypeParameterPossiblyReferenced(tp, declaration)) :
15873+
const allDeclarations = type.objectFlags & ObjectFlags.Reference ? [declaration] : type.symbol.declarations!;
15874+
typeParameters = (target.objectFlags & ObjectFlags.Reference || target.symbol.flags & SymbolFlags.Method || target.symbol.flags & SymbolFlags.TypeLiteral) && !target.aliasTypeArguments ?
15875+
filter(typeParameters, tp => some(allDeclarations, d => isTypeParameterPossiblyReferenced(tp, d))) :
1587515876
typeParameters;
1587615877
links.outerTypeParameters = typeParameters;
1587715878
}
@@ -15918,7 +15919,7 @@ namespace ts {
1591815919
return true;
1591915920
}
1592015921
}
15921-
return !!forEachChild(node, containsReference);
15922+
return containsReference(node);
1592215923
}
1592315924
return true;
1592415925
function containsReference(node: Node): boolean {
@@ -15930,6 +15931,9 @@ namespace ts {
1593015931
getTypeFromTypeNodeWorker(<TypeNode>node) === tp; // use worker because we're looking for === equality
1593115932
case SyntaxKind.TypeQuery:
1593215933
return true;
15934+
case SyntaxKind.MethodDeclaration:
15935+
case SyntaxKind.MethodSignature:
15936+
return (!(node as FunctionLikeDeclaration).type && !!(node as FunctionLikeDeclaration).body) || !!forEachChild(node, containsReference);
1593315937
}
1593415938
return !!forEachChild(node, containsReference);
1593515939
}

tests/baselines/reference/bivariantInferences.symbols

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ declare const b: (string | number)[] | null[] | undefined[] | {}[];
2424

2525
let x = a.equalsShallow(b);
2626
>x : Symbol(x, Decl(bivariantInferences.ts, 9, 3))
27-
>a.equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20))
27+
>a.equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20))
2828
>a : Symbol(a, Decl(bivariantInferences.ts, 6, 13))
29-
>equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20))
29+
>equalsShallow : Symbol(Array.equalsShallow, Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20), Decl(bivariantInferences.ts, 2, 20))
3030
>b : Symbol(b, Decl(bivariantInferences.ts, 7, 13))
3131

tests/baselines/reference/bivariantInferences.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ declare const b: (string | number)[] | null[] | undefined[] | {}[];
1919
let x = a.equalsShallow(b);
2020
>x : boolean
2121
>a.equalsShallow(b) : boolean
22-
>a.equalsShallow : <T>(this: readonly T[], other: readonly T[]) => boolean
22+
>a.equalsShallow : (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean)
2323
>a : (string | number)[] | null[] | undefined[] | {}[]
24-
>equalsShallow : <T>(this: readonly T[], other: readonly T[]) => boolean
24+
>equalsShallow : (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean)
2525
>b : (string | number)[] | null[] | undefined[] | {}[]
2626

tests/baselines/reference/completionEntryForUnionMethod.baseline

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
},
125125
{
126126
"text": "toString",
127-
"kind": "methodName"
127+
"kind": "propertyName"
128128
},
129129
{
130130
"text": "(",
@@ -198,7 +198,7 @@
198198
},
199199
{
200200
"text": "toLocaleString",
201-
"kind": "methodName"
201+
"kind": "propertyName"
202202
},
203203
{
204204
"text": "(",
@@ -981,7 +981,7 @@
981981
},
982982
{
983983
"text": "join",
984-
"kind": "methodName"
984+
"kind": "propertyName"
985985
},
986986
{
987987
"text": "(",

tests/baselines/reference/mixinAccessModifiers.symbols

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,13 +387,13 @@ function f9(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric<{a:void;b:void;}>
387387
>b : Symbol(b, Decl(mixinAccessModifiers.ts, 127, 71))
388388

389389
x.privateMethod(); // Error, private constituent makes method inaccessible
390-
>x.privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27))
390+
>x.privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27), Decl(mixinAccessModifiers.ts, 107, 27))
391391
>x : Symbol(x, Decl(mixinAccessModifiers.ts, 127, 12))
392-
>privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27))
392+
>privateMethod : Symbol(ProtectedGeneric.privateMethod, Decl(mixinAccessModifiers.ts, 107, 27), Decl(mixinAccessModifiers.ts, 107, 27))
393393

394394
x.protectedMethod(); // Error, protected when all constituents are protected
395-
>x.protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27))
395+
>x.protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27), Decl(mixinAccessModifiers.ts, 108, 27))
396396
>x : Symbol(x, Decl(mixinAccessModifiers.ts, 127, 12))
397-
>protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27))
397+
>protectedMethod : Symbol(ProtectedGeneric.protectedMethod, Decl(mixinAccessModifiers.ts, 108, 27), Decl(mixinAccessModifiers.ts, 108, 27))
398398
}
399399

tests/baselines/reference/mixinAccessModifiers.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,14 +373,14 @@ function f9(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric<{a:void;b:void;}>
373373

374374
x.privateMethod(); // Error, private constituent makes method inaccessible
375375
>x.privateMethod() : void
376-
>x.privateMethod : () => void
376+
>x.privateMethod : (() => void) & (() => void)
377377
>x : ProtectedGeneric<{ a: void; }> & ProtectedGeneric<{ a: void; b: void; }>
378-
>privateMethod : () => void
378+
>privateMethod : (() => void) & (() => void)
379379

380380
x.protectedMethod(); // Error, protected when all constituents are protected
381381
>x.protectedMethod() : void
382-
>x.protectedMethod : () => void
382+
>x.protectedMethod : (() => void) & (() => void)
383383
>x : ProtectedGeneric<{ a: void; }> & ProtectedGeneric<{ a: void; b: void; }>
384-
>protectedMethod : () => void
384+
>protectedMethod : (() => void) & (() => void)
385385
}
386386

tests/baselines/reference/sliceResultCast.symbols

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ declare var x: [number, string] | [number, string, string];
33
>x : Symbol(x, Decl(sliceResultCast.ts, 0, 11))
44

55
x.slice(1) as readonly string[];
6-
>x.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
6+
>x.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
77
>x : Symbol(x, Decl(sliceResultCast.ts, 0, 11))
8-
>slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --))
8+
>slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
99

tests/baselines/reference/sliceResultCast.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ declare var x: [number, string] | [number, string, string];
55
x.slice(1) as readonly string[];
66
>x.slice(1) as readonly string[] : readonly string[]
77
>x.slice(1) : (string | number)[]
8-
>x.slice : (start?: number, end?: number) => (string | number)[]
8+
>x.slice : ((start?: number, end?: number) => (string | number)[]) | ((start?: number, end?: number) => (string | number)[])
99
>x : [number, string] | [number, string, string]
10-
>slice : (start?: number, end?: number) => (string | number)[]
10+
>slice : ((start?: number, end?: number) => (string | number)[]) | ((start?: number, end?: number) => (string | number)[])
1111
>1 : 1
1212

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//// [tests/cases/compiler/stackDepthLimitCastingType.ts] ////
2+
3+
//// [index.d.ts]
4+
declare global {
5+
interface JQueryXHR { }
6+
class Model<T = any, E = {}> {
7+
initialize(attributes?: T, options?: CombinedModelConstructorOptions<E, this>): void;
8+
fetch(options?: any): JQueryXHR;
9+
}
10+
interface ModelConstructorOptions<TModel extends Model = Model> {
11+
collection?: Collection<TModel>;
12+
}
13+
class Collection<TModel extends Model = Model> {
14+
without(...values: TModel[]): TModel[];
15+
}
16+
type CombinedModelConstructorOptions<E, M extends Model<any, E> = Model> = ModelConstructorOptions<M> & E;
17+
}
18+
19+
export {
20+
Model
21+
};
22+
export as namespace Backbone;
23+
24+
//// [index.d.ts]
25+
import * as Backbone from "backbone";
26+
declare module "backbone" {
27+
interface ModelWithCache extends Model {
28+
fetch(options?: any): JQueryXHR;
29+
}
30+
}
31+
export {};
32+
export as namespace BackboneFetchCache;
33+
34+
//// [index.ts]
35+
import * as Backbone from "backbone";
36+
import * as BackboneFetchCache from "backbone-fetch-cache";
37+
38+
39+
const hoge = new Backbone.Model() as Backbone.ModelWithCache;
40+
hoge.fetch(null as any);
41+
42+
//// [index.js]
43+
"use strict";
44+
exports.__esModule = true;
45+
var Backbone = require("backbone");
46+
var hoge = new Backbone.Model();
47+
hoge.fetch(null);
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
=== tests/cases/compiler/node_modules/backbone/index.d.ts ===
2+
declare global {
3+
>global : Symbol(global, Decl(index.d.ts, 0, 0))
4+
5+
interface JQueryXHR { }
6+
>JQueryXHR : Symbol(JQueryXHR, Decl(index.d.ts, 0, 16))
7+
8+
class Model<T = any, E = {}> {
9+
>Model : Symbol(Model, Decl(index.d.ts, 1, 27))
10+
>T : Symbol(T, Decl(index.d.ts, 2, 16))
11+
>E : Symbol(E, Decl(index.d.ts, 2, 24))
12+
13+
initialize(attributes?: T, options?: CombinedModelConstructorOptions<E, this>): void;
14+
>initialize : Symbol(Model.initialize, Decl(index.d.ts, 2, 34))
15+
>attributes : Symbol(attributes, Decl(index.d.ts, 3, 19))
16+
>T : Symbol(T, Decl(index.d.ts, 2, 16))
17+
>options : Symbol(options, Decl(index.d.ts, 3, 34))
18+
>CombinedModelConstructorOptions : Symbol(CombinedModelConstructorOptions, Decl(index.d.ts, 11, 5))
19+
>E : Symbol(E, Decl(index.d.ts, 2, 24))
20+
21+
fetch(options?: any): JQueryXHR;
22+
>fetch : Symbol(Model.fetch, Decl(index.d.ts, 3, 93))
23+
>options : Symbol(options, Decl(index.d.ts, 4, 14))
24+
>JQueryXHR : Symbol(JQueryXHR, Decl(index.d.ts, 0, 16))
25+
}
26+
interface ModelConstructorOptions<TModel extends Model = Model> {
27+
>ModelConstructorOptions : Symbol(ModelConstructorOptions, Decl(index.d.ts, 5, 5))
28+
>TModel : Symbol(TModel, Decl(index.d.ts, 6, 38))
29+
>Model : Symbol(Model, Decl(index.d.ts, 1, 27))
30+
>Model : Symbol(Model, Decl(index.d.ts, 1, 27))
31+
32+
collection?: Collection<TModel>;
33+
>collection : Symbol(ModelConstructorOptions.collection, Decl(index.d.ts, 6, 69))
34+
>Collection : Symbol(Collection, Decl(index.d.ts, 8, 5))
35+
>TModel : Symbol(TModel, Decl(index.d.ts, 6, 38))
36+
}
37+
class Collection<TModel extends Model = Model> {
38+
>Collection : Symbol(Collection, Decl(index.d.ts, 8, 5))
39+
>TModel : Symbol(TModel, Decl(index.d.ts, 9, 21))
40+
>Model : Symbol(Model, Decl(index.d.ts, 1, 27))
41+
>Model : Symbol(Model, Decl(index.d.ts, 1, 27))
42+
43+
without(...values: TModel[]): TModel[];
44+
>without : Symbol(Collection.without, Decl(index.d.ts, 9, 52))
45+
>values : Symbol(values, Decl(index.d.ts, 10, 16))
46+
>TModel : Symbol(TModel, Decl(index.d.ts, 9, 21))
47+
>TModel : Symbol(TModel, Decl(index.d.ts, 9, 21))
48+
}
49+
type CombinedModelConstructorOptions<E, M extends Model<any, E> = Model> = ModelConstructorOptions<M> & E;
50+
>CombinedModelConstructorOptions : Symbol(CombinedModelConstructorOptions, Decl(index.d.ts, 11, 5))
51+
>E : Symbol(E, Decl(index.d.ts, 12, 41))
52+
>M : Symbol(M, Decl(index.d.ts, 12, 43))
53+
>Model : Symbol(Model, Decl(index.d.ts, 1, 27))
54+
>E : Symbol(E, Decl(index.d.ts, 12, 41))
55+
>Model : Symbol(Model, Decl(index.d.ts, 1, 27))
56+
>ModelConstructorOptions : Symbol(ModelConstructorOptions, Decl(index.d.ts, 5, 5))
57+
>M : Symbol(M, Decl(index.d.ts, 12, 43))
58+
>E : Symbol(E, Decl(index.d.ts, 12, 41))
59+
}
60+
61+
export {
62+
Model
63+
>Model : Symbol(Model, Decl(index.d.ts, 15, 8))
64+
65+
};
66+
export as namespace Backbone;
67+
>Backbone : Symbol(Backbone, Decl(index.d.ts, 17, 2))
68+
69+
=== tests/cases/compiler/node_modules/backbone-fetch-cache/index.d.ts ===
70+
import * as Backbone from "backbone";
71+
>Backbone : Symbol(Backbone, Decl(index.d.ts, 0, 6))
72+
73+
declare module "backbone" {
74+
>"backbone" : Symbol(Backbone, Decl(index.d.ts, 0, 0), Decl(index.d.ts, 0, 37))
75+
76+
interface ModelWithCache extends Model {
77+
>ModelWithCache : Symbol(ModelWithCache, Decl(index.d.ts, 1, 27))
78+
>Model : Symbol(Backbone.Model, Decl(index.d.ts, 1, 27))
79+
80+
fetch(options?: any): JQueryXHR;
81+
>fetch : Symbol(ModelWithCache.fetch, Decl(index.d.ts, 2, 44))
82+
>options : Symbol(options, Decl(index.d.ts, 3, 14))
83+
>JQueryXHR : Symbol(JQueryXHR, Decl(index.d.ts, 0, 16))
84+
}
85+
}
86+
export {};
87+
export as namespace BackboneFetchCache;
88+
>BackboneFetchCache : Symbol(BackboneFetchCache, Decl(index.d.ts, 6, 10))
89+
90+
=== tests/cases/compiler/index.ts ===
91+
import * as Backbone from "backbone";
92+
>Backbone : Symbol(Backbone, Decl(index.ts, 0, 6))
93+
94+
import * as BackboneFetchCache from "backbone-fetch-cache";
95+
>BackboneFetchCache : Symbol(BackboneFetchCache, Decl(index.ts, 1, 6))
96+
97+
98+
const hoge = new Backbone.Model() as Backbone.ModelWithCache;
99+
>hoge : Symbol(hoge, Decl(index.ts, 4, 5))
100+
>Backbone.Model : Symbol(Backbone.Model, Decl(index.d.ts, 15, 8))
101+
>Backbone : Symbol(Backbone, Decl(index.ts, 0, 6))
102+
>Model : Symbol(Backbone.Model, Decl(index.d.ts, 15, 8))
103+
>Backbone : Symbol(Backbone, Decl(index.ts, 0, 6))
104+
>ModelWithCache : Symbol(Backbone.ModelWithCache, Decl(index.d.ts, 1, 27))
105+
106+
hoge.fetch(null as any);
107+
>hoge.fetch : Symbol(Backbone.ModelWithCache.fetch, Decl(index.d.ts, 2, 44))
108+
>hoge : Symbol(hoge, Decl(index.ts, 4, 5))
109+
>fetch : Symbol(Backbone.ModelWithCache.fetch, Decl(index.d.ts, 2, 44))
110+

0 commit comments

Comments
 (0)