Skip to content

Commit 99110e9

Browse files
committed
Consider inferences between mapped type templates lower priority
1 parent 9eab334 commit 99110e9

5 files changed

+191
-2
lines changed

src/compiler/checker.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -21718,12 +21718,14 @@ namespace ts {
2171821718
}
2171921719

2172021720
function inferFromIndexTypes(source: Type, target: Type) {
21721+
// Inferences across mapped type index signatures are pretty much the same a inferences to homomorphic variables
21722+
const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) ? InferencePriority.HomomorphicMappedType : 0;
2172121723
const targetStringIndexType = getIndexTypeOfType(target, IndexKind.String);
2172221724
if (targetStringIndexType) {
2172321725
const sourceIndexType = getIndexTypeOfType(source, IndexKind.String) ||
2172421726
getImplicitIndexTypeOfType(source, IndexKind.String);
2172521727
if (sourceIndexType) {
21726-
inferFromTypes(sourceIndexType, targetStringIndexType);
21728+
inferWithPriority(sourceIndexType, targetStringIndexType, priority);
2172721729
}
2172821730
}
2172921731
const targetNumberIndexType = getIndexTypeOfType(target, IndexKind.Number);
@@ -21732,7 +21734,7 @@ namespace ts {
2173221734
getIndexTypeOfType(source, IndexKind.String) ||
2173321735
getImplicitIndexTypeOfType(source, IndexKind.Number);
2173421736
if (sourceIndexType) {
21735-
inferFromTypes(sourceIndexType, targetNumberIndexType);
21737+
inferWithPriority(sourceIndexType, targetNumberIndexType, priority);
2173621738
}
2173721739
}
2173821740
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//// [localTypeParameterInferencePriority.ts]
2+
export type UnrollOnHover<O extends object> = O extends object ?
3+
{ [K in keyof O]: O[K]; } :
4+
never;
5+
6+
7+
export type Schema = Record<string, unknown>;
8+
class Table<S extends Schema> {
9+
__schema!: S;
10+
11+
// Removing this line, removes the error
12+
getRows<C extends keyof S>(): Array<UnrollOnHover<Pick<S, C>>> {
13+
return null!
14+
}
15+
}
16+
17+
class ColumnSelectViewImp<S extends Schema> extends Table<S> { }
18+
19+
20+
const ColumnSelectView1: new <S extends Schema>() => Table<UnrollOnHover<S>> = ColumnSelectViewImp;
21+
const ColumnSelectView2: new <S extends Schema>() => Table<UnrollOnHover<S>> = Table;
22+
23+
//// [localTypeParameterInferencePriority.js]
24+
"use strict";
25+
var __extends = (this && this.__extends) || (function () {
26+
var extendStatics = function (d, b) {
27+
extendStatics = Object.setPrototypeOf ||
28+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
29+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
30+
return extendStatics(d, b);
31+
};
32+
return function (d, b) {
33+
if (typeof b !== "function" && b !== null)
34+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
35+
extendStatics(d, b);
36+
function __() { this.constructor = d; }
37+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
38+
};
39+
})();
40+
exports.__esModule = true;
41+
var Table = /** @class */ (function () {
42+
function Table() {
43+
}
44+
// Removing this line, removes the error
45+
Table.prototype.getRows = function () {
46+
return null;
47+
};
48+
return Table;
49+
}());
50+
var ColumnSelectViewImp = /** @class */ (function (_super) {
51+
__extends(ColumnSelectViewImp, _super);
52+
function ColumnSelectViewImp() {
53+
return _super !== null && _super.apply(this, arguments) || this;
54+
}
55+
return ColumnSelectViewImp;
56+
}(Table));
57+
var ColumnSelectView1 = ColumnSelectViewImp;
58+
var ColumnSelectView2 = Table;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
=== tests/cases/compiler/localTypeParameterInferencePriority.ts ===
2+
export type UnrollOnHover<O extends object> = O extends object ?
3+
>UnrollOnHover : Symbol(UnrollOnHover, Decl(localTypeParameterInferencePriority.ts, 0, 0))
4+
>O : Symbol(O, Decl(localTypeParameterInferencePriority.ts, 0, 26))
5+
>O : Symbol(O, Decl(localTypeParameterInferencePriority.ts, 0, 26))
6+
7+
{ [K in keyof O]: O[K]; } :
8+
>K : Symbol(K, Decl(localTypeParameterInferencePriority.ts, 1, 7))
9+
>O : Symbol(O, Decl(localTypeParameterInferencePriority.ts, 0, 26))
10+
>O : Symbol(O, Decl(localTypeParameterInferencePriority.ts, 0, 26))
11+
>K : Symbol(K, Decl(localTypeParameterInferencePriority.ts, 1, 7))
12+
13+
never;
14+
15+
16+
export type Schema = Record<string, unknown>;
17+
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
18+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
19+
20+
class Table<S extends Schema> {
21+
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
22+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 6, 12))
23+
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
24+
25+
__schema!: S;
26+
>__schema : Symbol(Table.__schema, Decl(localTypeParameterInferencePriority.ts, 6, 32))
27+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 6, 12))
28+
29+
// Removing this line, removes the error
30+
getRows<C extends keyof S>(): Array<UnrollOnHover<Pick<S, C>>> {
31+
>getRows : Symbol(Table.getRows, Decl(localTypeParameterInferencePriority.ts, 7, 17))
32+
>C : Symbol(C, Decl(localTypeParameterInferencePriority.ts, 10, 12))
33+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 6, 12))
34+
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
35+
>UnrollOnHover : Symbol(UnrollOnHover, Decl(localTypeParameterInferencePriority.ts, 0, 0))
36+
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
37+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 6, 12))
38+
>C : Symbol(C, Decl(localTypeParameterInferencePriority.ts, 10, 12))
39+
40+
return null!
41+
}
42+
}
43+
44+
class ColumnSelectViewImp<S extends Schema> extends Table<S> { }
45+
>ColumnSelectViewImp : Symbol(ColumnSelectViewImp, Decl(localTypeParameterInferencePriority.ts, 13, 1))
46+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 15, 26))
47+
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
48+
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
49+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 15, 26))
50+
51+
52+
const ColumnSelectView1: new <S extends Schema>() => Table<UnrollOnHover<S>> = ColumnSelectViewImp;
53+
>ColumnSelectView1 : Symbol(ColumnSelectView1, Decl(localTypeParameterInferencePriority.ts, 18, 5))
54+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 18, 30))
55+
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
56+
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
57+
>UnrollOnHover : Symbol(UnrollOnHover, Decl(localTypeParameterInferencePriority.ts, 0, 0))
58+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 18, 30))
59+
>ColumnSelectViewImp : Symbol(ColumnSelectViewImp, Decl(localTypeParameterInferencePriority.ts, 13, 1))
60+
61+
const ColumnSelectView2: new <S extends Schema>() => Table<UnrollOnHover<S>> = Table;
62+
>ColumnSelectView2 : Symbol(ColumnSelectView2, Decl(localTypeParameterInferencePriority.ts, 19, 5))
63+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 19, 30))
64+
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
65+
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
66+
>UnrollOnHover : Symbol(UnrollOnHover, Decl(localTypeParameterInferencePriority.ts, 0, 0))
67+
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 19, 30))
68+
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
69+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
=== tests/cases/compiler/localTypeParameterInferencePriority.ts ===
2+
export type UnrollOnHover<O extends object> = O extends object ?
3+
>UnrollOnHover : UnrollOnHover<O>
4+
5+
{ [K in keyof O]: O[K]; } :
6+
never;
7+
8+
9+
export type Schema = Record<string, unknown>;
10+
>Schema : Schema
11+
12+
class Table<S extends Schema> {
13+
>Table : Table<S>
14+
15+
__schema!: S;
16+
>__schema : S
17+
18+
// Removing this line, removes the error
19+
getRows<C extends keyof S>(): Array<UnrollOnHover<Pick<S, C>>> {
20+
>getRows : <C extends keyof S>() => Array<UnrollOnHover<Pick<S, C>>>
21+
22+
return null!
23+
>null! : null
24+
>null : null
25+
}
26+
}
27+
28+
class ColumnSelectViewImp<S extends Schema> extends Table<S> { }
29+
>ColumnSelectViewImp : ColumnSelectViewImp<S>
30+
>Table : Table<S>
31+
32+
33+
const ColumnSelectView1: new <S extends Schema>() => Table<UnrollOnHover<S>> = ColumnSelectViewImp;
34+
>ColumnSelectView1 : new <S extends Schema>() => Table<UnrollOnHover<S>>
35+
>ColumnSelectViewImp : typeof ColumnSelectViewImp
36+
37+
const ColumnSelectView2: new <S extends Schema>() => Table<UnrollOnHover<S>> = Table;
38+
>ColumnSelectView2 : new <S extends Schema>() => Table<UnrollOnHover<S>>
39+
>Table : typeof Table
40+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export type UnrollOnHover<O extends object> = O extends object ?
2+
{ [K in keyof O]: O[K]; } :
3+
never;
4+
5+
6+
export type Schema = Record<string, unknown>;
7+
class Table<S extends Schema> {
8+
__schema!: S;
9+
10+
// Removing this line, removes the error
11+
getRows<C extends keyof S>(): Array<UnrollOnHover<Pick<S, C>>> {
12+
return null!
13+
}
14+
}
15+
16+
class ColumnSelectViewImp<S extends Schema> extends Table<S> { }
17+
18+
19+
const ColumnSelectView1: new <S extends Schema>() => Table<UnrollOnHover<S>> = ColumnSelectViewImp;
20+
const ColumnSelectView2: new <S extends Schema>() => Table<UnrollOnHover<S>> = Table;

0 commit comments

Comments
 (0)