Combine keyof T inferences (#22525)

* Combine keyof T inferences

* Extract covariant inference derivation into function

* Test:keyof inference lower priority than return inference

for #22376

* Update 'expected' comment in keyofInferenceLowerPriorityThanReturn

* Update comment in test too, not just baselines

* Fix typo

* Move tests
This commit is contained in:
Wesley Wigham
2018-03-19 16:56:51 -07:00
committed by Daniel Rosenwasser
parent a11e54856a
commit 044cdbc85f
12 changed files with 552 additions and 28 deletions

View File

@@ -0,0 +1,11 @@
interface X {
a: string;
b: string;
}
declare function foo<T = X>(x: keyof T, y: keyof T): T;
declare function bar<T>(x: keyof T, y: keyof T): T;
const a = foo<X>('a', 'b'); // compiles cleanly
const b = foo('a', 'b'); // also clean
const c = bar('a', 'b'); // still clean

View File

@@ -0,0 +1,46 @@
// #22736
declare class Write {
protected dummy: Write;
}
declare class Col<s, a> {
protected dummy: [Col<s, a>, s, a];
}
declare class Table<Req, Def> {
protected dummy: [Table<Req, Def>, Req, Def];
}
type MakeTable<T1 extends object, T2 extends object> = {
[P in keyof T1]: Col<Write, T1[P]>;
} & {
[P in keyof T2]: Col<Write, T2[P]>;
};
declare class ConflictTarget<Cols> {
public static tableColumns<Cols>(cols: (keyof Cols)[]): ConflictTarget<Cols>;
protected dummy: [ConflictTarget<Cols>, Cols];
}
const bookTable: Table<BookReq, BookDef> = null as any
interface BookReq {
readonly title: string;
readonly serial: number;
}
interface BookDef {
readonly author: string;
readonly numPages: number | null;
}
function insertOnConflictDoNothing<Req extends object, Def extends object>(_table: Table<Req, Def>, _conflictTarget: ConflictTarget<Req & Def>): boolean {
throw new Error();
}
function f() {
insertOnConflictDoNothing(bookTable, ConflictTarget.tableColumns(["serial"])); // <-- No error here; should use the type inferred for the return type of `tableColumns`
}