Skip to content

Commit

Permalink
Cherry-pick PR #44126 into release-4.3 (#44189)
Browse files Browse the repository at this point in the history
Component commits:
99110e9 Consider inferences between mapped type templates lower priority

Co-authored-by: Wesley Wigham <t-weswig@microsoft.com>
  • Loading branch information
TypeScript Bot and weswigham authored Jun 16, 2021
1 parent 419f1e7 commit 89a171e
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21641,12 +21641,14 @@ namespace ts {
}

function inferFromIndexTypes(source: Type, target: Type) {
// Inferences across mapped type index signatures are pretty much the same a inferences to homomorphic variables
const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) ? InferencePriority.HomomorphicMappedType : 0;
const targetStringIndexType = getIndexTypeOfType(target, IndexKind.String);
if (targetStringIndexType) {
const sourceIndexType = getIndexTypeOfType(source, IndexKind.String) ||
getImplicitIndexTypeOfType(source, IndexKind.String);
if (sourceIndexType) {
inferFromTypes(sourceIndexType, targetStringIndexType);
inferWithPriority(sourceIndexType, targetStringIndexType, priority);
}
}
const targetNumberIndexType = getIndexTypeOfType(target, IndexKind.Number);
Expand All @@ -21655,7 +21657,7 @@ namespace ts {
getIndexTypeOfType(source, IndexKind.String) ||
getImplicitIndexTypeOfType(source, IndexKind.Number);
if (sourceIndexType) {
inferFromTypes(sourceIndexType, targetNumberIndexType);
inferWithPriority(sourceIndexType, targetNumberIndexType, priority);
}
}
}
Expand Down
58 changes: 58 additions & 0 deletions tests/baselines/reference/localTypeParameterInferencePriority.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//// [localTypeParameterInferencePriority.ts]
export type UnrollOnHover<O extends object> = O extends object ?
{ [K in keyof O]: O[K]; } :
never;


export type Schema = Record<string, unknown>;
class Table<S extends Schema> {
__schema!: S;

// Removing this line, removes the error
getRows<C extends keyof S>(): Array<UnrollOnHover<Pick<S, C>>> {
return null!
}
}

class ColumnSelectViewImp<S extends Schema> extends Table<S> { }


const ColumnSelectView1: new <S extends Schema>() => Table<UnrollOnHover<S>> = ColumnSelectViewImp;
const ColumnSelectView2: new <S extends Schema>() => Table<UnrollOnHover<S>> = Table;

//// [localTypeParameterInferencePriority.js]
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
exports.__esModule = true;
var Table = /** @class */ (function () {
function Table() {
}
// Removing this line, removes the error
Table.prototype.getRows = function () {
return null;
};
return Table;
}());
var ColumnSelectViewImp = /** @class */ (function (_super) {
__extends(ColumnSelectViewImp, _super);
function ColumnSelectViewImp() {
return _super !== null && _super.apply(this, arguments) || this;
}
return ColumnSelectViewImp;
}(Table));
var ColumnSelectView1 = ColumnSelectViewImp;
var ColumnSelectView2 = Table;
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
=== tests/cases/compiler/localTypeParameterInferencePriority.ts ===
export type UnrollOnHover<O extends object> = O extends object ?
>UnrollOnHover : Symbol(UnrollOnHover, Decl(localTypeParameterInferencePriority.ts, 0, 0))
>O : Symbol(O, Decl(localTypeParameterInferencePriority.ts, 0, 26))
>O : Symbol(O, Decl(localTypeParameterInferencePriority.ts, 0, 26))

{ [K in keyof O]: O[K]; } :
>K : Symbol(K, Decl(localTypeParameterInferencePriority.ts, 1, 7))
>O : Symbol(O, Decl(localTypeParameterInferencePriority.ts, 0, 26))
>O : Symbol(O, Decl(localTypeParameterInferencePriority.ts, 0, 26))
>K : Symbol(K, Decl(localTypeParameterInferencePriority.ts, 1, 7))

never;


export type Schema = Record<string, unknown>;
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))

class Table<S extends Schema> {
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 6, 12))
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))

__schema!: S;
>__schema : Symbol(Table.__schema, Decl(localTypeParameterInferencePriority.ts, 6, 32))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 6, 12))

// Removing this line, removes the error
getRows<C extends keyof S>(): Array<UnrollOnHover<Pick<S, C>>> {
>getRows : Symbol(Table.getRows, Decl(localTypeParameterInferencePriority.ts, 7, 17))
>C : Symbol(C, Decl(localTypeParameterInferencePriority.ts, 10, 12))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 6, 12))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>UnrollOnHover : Symbol(UnrollOnHover, Decl(localTypeParameterInferencePriority.ts, 0, 0))
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 6, 12))
>C : Symbol(C, Decl(localTypeParameterInferencePriority.ts, 10, 12))

return null!
}
}

class ColumnSelectViewImp<S extends Schema> extends Table<S> { }
>ColumnSelectViewImp : Symbol(ColumnSelectViewImp, Decl(localTypeParameterInferencePriority.ts, 13, 1))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 15, 26))
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 15, 26))


const ColumnSelectView1: new <S extends Schema>() => Table<UnrollOnHover<S>> = ColumnSelectViewImp;
>ColumnSelectView1 : Symbol(ColumnSelectView1, Decl(localTypeParameterInferencePriority.ts, 18, 5))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 18, 30))
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
>UnrollOnHover : Symbol(UnrollOnHover, Decl(localTypeParameterInferencePriority.ts, 0, 0))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 18, 30))
>ColumnSelectViewImp : Symbol(ColumnSelectViewImp, Decl(localTypeParameterInferencePriority.ts, 13, 1))

const ColumnSelectView2: new <S extends Schema>() => Table<UnrollOnHover<S>> = Table;
>ColumnSelectView2 : Symbol(ColumnSelectView2, Decl(localTypeParameterInferencePriority.ts, 19, 5))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 19, 30))
>Schema : Symbol(Schema, Decl(localTypeParameterInferencePriority.ts, 2, 10))
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))
>UnrollOnHover : Symbol(UnrollOnHover, Decl(localTypeParameterInferencePriority.ts, 0, 0))
>S : Symbol(S, Decl(localTypeParameterInferencePriority.ts, 19, 30))
>Table : Symbol(Table, Decl(localTypeParameterInferencePriority.ts, 5, 45))

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
=== tests/cases/compiler/localTypeParameterInferencePriority.ts ===
export type UnrollOnHover<O extends object> = O extends object ?
>UnrollOnHover : UnrollOnHover<O>

{ [K in keyof O]: O[K]; } :
never;


export type Schema = Record<string, unknown>;
>Schema : Schema

class Table<S extends Schema> {
>Table : Table<S>

__schema!: S;
>__schema : S

// Removing this line, removes the error
getRows<C extends keyof S>(): Array<UnrollOnHover<Pick<S, C>>> {
>getRows : <C extends keyof S>() => Array<UnrollOnHover<Pick<S, C>>>

return null!
>null! : null
>null : null
}
}

class ColumnSelectViewImp<S extends Schema> extends Table<S> { }
>ColumnSelectViewImp : ColumnSelectViewImp<S>
>Table : Table<S>


const ColumnSelectView1: new <S extends Schema>() => Table<UnrollOnHover<S>> = ColumnSelectViewImp;
>ColumnSelectView1 : new <S extends Schema>() => Table<UnrollOnHover<S>>
>ColumnSelectViewImp : typeof ColumnSelectViewImp

const ColumnSelectView2: new <S extends Schema>() => Table<UnrollOnHover<S>> = Table;
>ColumnSelectView2 : new <S extends Schema>() => Table<UnrollOnHover<S>>
>Table : typeof Table

20 changes: 20 additions & 0 deletions tests/cases/compiler/localTypeParameterInferencePriority.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export type UnrollOnHover<O extends object> = O extends object ?
{ [K in keyof O]: O[K]; } :
never;


export type Schema = Record<string, unknown>;
class Table<S extends Schema> {
__schema!: S;

// Removing this line, removes the error
getRows<C extends keyof S>(): Array<UnrollOnHover<Pick<S, C>>> {
return null!
}
}

class ColumnSelectViewImp<S extends Schema> extends Table<S> { }


const ColumnSelectView1: new <S extends Schema>() => Table<UnrollOnHover<S>> = ColumnSelectViewImp;
const ColumnSelectView2: new <S extends Schema>() => Table<UnrollOnHover<S>> = Table;

0 comments on commit 89a171e

Please sign in to comment.