Accept new baselines

This commit is contained in:
Anders Hejlsberg
2016-12-02 14:50:21 -08:00
parent 1e2425ebfc
commit fe0b66a00c
6 changed files with 706 additions and 2 deletions

View File

@@ -118,7 +118,32 @@ function f10(foo: Foo) {
let x = validate(foo); // { a: number, readonly b: string }
let y = clone(foo); // { a?: number, b: string }
let z = validateAndClone(foo); // { a: number, b: string }
}
}
// Repro from #12606
type Func<T> = (...args: any[]) => T;
type Spec<T> = {
[P in keyof T]: Func<T[P]> | Spec<T[P]> ;
};
/**
* Given a spec object recursively mapping properties to functions, creates a function
* producing an object of the same structure, by mapping each property to the result
* of calling its associated function with the supplied arguments.
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
sum: (a: any) => 3,
nested: {
mul: (b: any) => "n"
}
});
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
//// [isomorphicMappedTypeInference.js]
function box(x) {
@@ -210,6 +235,15 @@ function f10(foo) {
var y = clone(foo); // { a?: number, b: string }
var z = validateAndClone(foo); // { a: number, b: string }
}
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
sum: function (a) { return 3; },
nested: {
mul: function (b) { return "n"; }
}
});
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: function (x) { return true; } } } });
//// [isomorphicMappedTypeInference.d.ts]
@@ -254,3 +288,26 @@ declare type Foo = {
readonly b: string;
};
declare function f10(foo: Foo): void;
declare type Func<T> = (...args: any[]) => T;
declare type Spec<T> = {
[P in keyof T]: Func<T[P]> | Spec<T[P]>;
};
/**
* Given a spec object recursively mapping properties to functions, creates a function
* producing an object of the same structure, by mapping each property to the result
* of calling its associated function with the supplied arguments.
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
declare var g1: (...args: any[]) => {
sum: number;
nested: {
mul: string;
};
};
declare var g2: (...args: any[]) => {
foo: {
bar: {
baz: boolean;
};
};
};

View File

@@ -393,3 +393,69 @@ function f10(foo: Foo) {
>validateAndClone : Symbol(validateAndClone, Decl(isomorphicMappedTypeInference.ts, 107, 69))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 115, 13))
}
// Repro from #12606
type Func<T> = (...args: any[]) => T;
>Func : Symbol(Func, Decl(isomorphicMappedTypeInference.ts, 119, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 123, 10))
>args : Symbol(args, Decl(isomorphicMappedTypeInference.ts, 123, 16))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 123, 10))
type Spec<T> = {
>Spec : Symbol(Spec, Decl(isomorphicMappedTypeInference.ts, 123, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 124, 10))
[P in keyof T]: Func<T[P]> | Spec<T[P]> ;
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 125, 5))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 124, 10))
>Func : Symbol(Func, Decl(isomorphicMappedTypeInference.ts, 119, 1))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 124, 10))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 125, 5))
>Spec : Symbol(Spec, Decl(isomorphicMappedTypeInference.ts, 123, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 124, 10))
>P : Symbol(P, Decl(isomorphicMappedTypeInference.ts, 125, 5))
};
/**
* Given a spec object recursively mapping properties to functions, creates a function
* producing an object of the same structure, by mapping each property to the result
* of calling its associated function with the supplied arguments.
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
>applySpec : Symbol(applySpec, Decl(isomorphicMappedTypeInference.ts, 126, 2))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 133, 27))
>obj : Symbol(obj, Decl(isomorphicMappedTypeInference.ts, 133, 30))
>Spec : Symbol(Spec, Decl(isomorphicMappedTypeInference.ts, 123, 37))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 133, 27))
>args : Symbol(args, Decl(isomorphicMappedTypeInference.ts, 133, 46))
>T : Symbol(T, Decl(isomorphicMappedTypeInference.ts, 133, 27))
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
>g1 : Symbol(g1, Decl(isomorphicMappedTypeInference.ts, 136, 3))
>applySpec : Symbol(applySpec, Decl(isomorphicMappedTypeInference.ts, 126, 2))
sum: (a: any) => 3,
>sum : Symbol(sum, Decl(isomorphicMappedTypeInference.ts, 136, 20))
>a : Symbol(a, Decl(isomorphicMappedTypeInference.ts, 137, 10))
nested: {
>nested : Symbol(nested, Decl(isomorphicMappedTypeInference.ts, 137, 23))
mul: (b: any) => "n"
>mul : Symbol(mul, Decl(isomorphicMappedTypeInference.ts, 138, 13))
>b : Symbol(b, Decl(isomorphicMappedTypeInference.ts, 139, 14))
}
});
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
>g2 : Symbol(g2, Decl(isomorphicMappedTypeInference.ts, 144, 3))
>applySpec : Symbol(applySpec, Decl(isomorphicMappedTypeInference.ts, 126, 2))
>foo : Symbol(foo, Decl(isomorphicMappedTypeInference.ts, 144, 20))
>bar : Symbol(bar, Decl(isomorphicMappedTypeInference.ts, 144, 27))
>baz : Symbol(baz, Decl(isomorphicMappedTypeInference.ts, 144, 34))
>x : Symbol(x, Decl(isomorphicMappedTypeInference.ts, 144, 41))

View File

@@ -467,3 +467,82 @@ function f10(foo: Foo) {
>validateAndClone : <T>(obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
}
// Repro from #12606
type Func<T> = (...args: any[]) => T;
>Func : Func<T>
>T : T
>args : any[]
>T : T
type Spec<T> = {
>Spec : Spec<T>
>T : T
[P in keyof T]: Func<T[P]> | Spec<T[P]> ;
>P : P
>T : T
>Func : Func<T>
>T : T
>P : P
>Spec : Spec<T>
>T : T
>P : P
};
/**
* Given a spec object recursively mapping properties to functions, creates a function
* producing an object of the same structure, by mapping each property to the result
* of calling its associated function with the supplied arguments.
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>T : T
>obj : Spec<T>
>Spec : Spec<T>
>T : T
>args : any[]
>T : T
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
>g1 : (...args: any[]) => { sum: number; nested: { mul: string; }; }
>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: number; nested: { mul: string; }; }
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>{ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }} : { sum: (a: any) => number; nested: { mul: (b: any) => string; }; }
sum: (a: any) => 3,
>sum : (a: any) => number
>(a: any) => 3 : (a: any) => number
>a : any
>3 : 3
nested: {
>nested : { mul: (b: any) => string; }
>{ mul: (b: any) => "n" } : { mul: (b: any) => string; }
mul: (b: any) => "n"
>mul : (b: any) => string
>(b: any) => "n" : (b: any) => string
>b : any
>"n" : "n"
}
});
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
>g2 : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; }
>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; }
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>{ foo: { bar: { baz: (x: any) => true } } } : { foo: { bar: { baz: (x: any) => boolean; }; }; }
>foo : { bar: { baz: (x: any) => boolean; }; }
>{ bar: { baz: (x: any) => true } } : { bar: { baz: (x: any) => boolean; }; }
>bar : { baz: (x: any) => boolean; }
>{ baz: (x: any) => true } : { baz: (x: any) => boolean; }
>baz : (x: any) => boolean
>(x: any) => true : (x: any) => boolean
>x : any
>true : true

View File

@@ -250,7 +250,48 @@ class OtherPerson {
return getProperty(this, "parts")
}
}
// Modified repro from #12544
function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1];
function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2];
function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
function path(obj: any, ...keys: (string | number)[]): any;
function path(obj: any, ...keys: (string | number)[]): any {
let result = obj;
for (let k of keys) {
result = result[k];
}
return result;
}
type Thing = {
a: { x: number, y: string },
b: boolean
};
function f1(thing: Thing) {
let x1 = path(thing, 'a'); // { x: number, y: string }
let x2 = path(thing, 'a', 'y'); // string
let x3 = path(thing, 'b'); // boolean
let x4 = path(thing, ...['a', 'x']); // any
}
// Repro from comment in #12114
const assignTo2 = <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) =>
(value: T[K1][K2]) => object[key1][key2] = value;
// Modified repro from #12573
declare function one<T>(handler: (t: T) => void): T
var empty = one(() => {}) // inferred as {}, expected
type Handlers<T> = { [K in keyof T]: (t: T[K]) => void }
declare function on<T>(handlerHash: Handlers<T>): T
var hashOfEmpty1 = on({ test: () => {} }); // {}
var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean }
//// [keyofAndIndexedAccess.js]
var __extends = (this && this.__extends) || function (d, b) {
@@ -430,6 +471,31 @@ var OtherPerson = (function () {
};
return OtherPerson;
}());
function path(obj) {
var keys = [];
for (var _i = 1; _i < arguments.length; _i++) {
keys[_i - 1] = arguments[_i];
}
var result = obj;
for (var _a = 0, keys_1 = keys; _a < keys_1.length; _a++) {
var k = keys_1[_a];
result = result[k];
}
return result;
}
function f1(thing) {
var x1 = path(thing, 'a'); // { x: number, y: string }
var x2 = path(thing, 'a', 'y'); // string
var x3 = path(thing, 'b'); // boolean
var x4 = path.apply(void 0, [thing].concat(['a', 'x'])); // any
}
// Repro from comment in #12114
var assignTo2 = function (object, key1, key2) {
return function (value) { return object[key1][key2] = value; };
};
var empty = one(function () { }); // inferred as {}, expected
var hashOfEmpty1 = on({ test: function () { } }); // {}
var hashOfEmpty2 = on({ test: function (x) { } }); // { test: boolean }
//// [keyofAndIndexedAccess.d.ts]
@@ -551,3 +617,26 @@ declare class OtherPerson {
constructor(parts: number);
getParts(): number;
}
declare function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1];
declare function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2];
declare function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
declare function path(obj: any, ...keys: (string | number)[]): any;
declare type Thing = {
a: {
x: number;
y: string;
};
b: boolean;
};
declare function f1(thing: Thing): void;
declare const assignTo2: <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => T[K1][K2];
declare function one<T>(handler: (t: T) => void): T;
declare var empty: {};
declare type Handlers<T> = {
[K in keyof T]: (t: T[K]) => void;
};
declare function on<T>(handlerHash: Handlers<T>): T;
declare var hashOfEmpty1: {};
declare var hashOfEmpty2: {
test: boolean;
};

View File

@@ -848,3 +848,196 @@ class OtherPerson {
}
}
// Modified repro from #12544
function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1];
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 254, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 254, 16))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 254, 14))
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 254, 37))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 254, 14))
>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 254, 44))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 254, 16))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 254, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 254, 16))
function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2];
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 255, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 255, 16))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 255, 14))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 255, 36))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 255, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 255, 16))
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 255, 61))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 255, 14))
>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 255, 68))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 255, 16))
>key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 255, 78))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 255, 36))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 255, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 255, 16))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 255, 36))
function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 256, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 256, 16))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 256, 14))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 256, 36))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 256, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 256, 16))
>K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 256, 60))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 256, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 256, 16))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 256, 36))
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 256, 89))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 256, 14))
>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 256, 96))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 256, 16))
>key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 256, 106))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 256, 36))
>key3 : Symbol(key3, Decl(keyofAndIndexedAccess.ts, 256, 116))
>K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 256, 60))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 256, 14))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 256, 16))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 256, 36))
>K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 256, 60))
function path(obj: any, ...keys: (string | number)[]): any;
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 257, 14))
>keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 257, 23))
function path(obj: any, ...keys: (string | number)[]): any {
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 258, 14))
>keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 258, 23))
let result = obj;
>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 259, 7))
>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 258, 14))
for (let k of keys) {
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 260, 12))
>keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 258, 23))
result = result[k];
>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 259, 7))
>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 259, 7))
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 260, 12))
}
return result;
>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 259, 7))
}
type Thing = {
>Thing : Symbol(Thing, Decl(keyofAndIndexedAccess.ts, 264, 1))
a: { x: number, y: string },
>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 266, 14))
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 267, 8))
>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 267, 19))
b: boolean
>b : Symbol(b, Decl(keyofAndIndexedAccess.ts, 267, 32))
};
function f1(thing: Thing) {
>f1 : Symbol(f1, Decl(keyofAndIndexedAccess.ts, 269, 2))
>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 272, 12))
>Thing : Symbol(Thing, Decl(keyofAndIndexedAccess.ts, 264, 1))
let x1 = path(thing, 'a'); // { x: number, y: string }
>x1 : Symbol(x1, Decl(keyofAndIndexedAccess.ts, 273, 7))
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 272, 12))
let x2 = path(thing, 'a', 'y'); // string
>x2 : Symbol(x2, Decl(keyofAndIndexedAccess.ts, 274, 7))
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 272, 12))
let x3 = path(thing, 'b'); // boolean
>x3 : Symbol(x3, Decl(keyofAndIndexedAccess.ts, 275, 7))
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 272, 12))
let x4 = path(thing, ...['a', 'x']); // any
>x4 : Symbol(x4, Decl(keyofAndIndexedAccess.ts, 276, 7))
>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 250, 1), Decl(keyofAndIndexedAccess.ts, 254, 62), Decl(keyofAndIndexedAccess.ts, 255, 100), Decl(keyofAndIndexedAccess.ts, 256, 142), Decl(keyofAndIndexedAccess.ts, 257, 59))
>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 272, 12))
}
// Repro from comment in #12114
const assignTo2 = <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) =>
>assignTo2 : Symbol(assignTo2, Decl(keyofAndIndexedAccess.ts, 281, 5))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 281, 19))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 281, 21))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 281, 19))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 281, 41))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 281, 19))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 281, 21))
>object : Symbol(object, Decl(keyofAndIndexedAccess.ts, 281, 66))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 281, 19))
>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 281, 76))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 281, 21))
>key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 281, 86))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 281, 41))
(value: T[K1][K2]) => object[key1][key2] = value;
>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 282, 5))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 281, 19))
>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 281, 21))
>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 281, 41))
>object : Symbol(object, Decl(keyofAndIndexedAccess.ts, 281, 66))
>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 281, 76))
>key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 281, 86))
>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 282, 5))
// Modified repro from #12573
declare function one<T>(handler: (t: T) => void): T
>one : Symbol(one, Decl(keyofAndIndexedAccess.ts, 282, 53))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 286, 21))
>handler : Symbol(handler, Decl(keyofAndIndexedAccess.ts, 286, 24))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 286, 34))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 286, 21))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 286, 21))
var empty = one(() => {}) // inferred as {}, expected
>empty : Symbol(empty, Decl(keyofAndIndexedAccess.ts, 287, 3))
>one : Symbol(one, Decl(keyofAndIndexedAccess.ts, 282, 53))
type Handlers<T> = { [K in keyof T]: (t: T[K]) => void }
>Handlers : Symbol(Handlers, Decl(keyofAndIndexedAccess.ts, 287, 25))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 289, 14))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 289, 22))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 289, 14))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 289, 38))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 289, 14))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 289, 22))
declare function on<T>(handlerHash: Handlers<T>): T
>on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 289, 56))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 290, 20))
>handlerHash : Symbol(handlerHash, Decl(keyofAndIndexedAccess.ts, 290, 23))
>Handlers : Symbol(Handlers, Decl(keyofAndIndexedAccess.ts, 287, 25))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 290, 20))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 290, 20))
var hashOfEmpty1 = on({ test: () => {} }); // {}
>hashOfEmpty1 : Symbol(hashOfEmpty1, Decl(keyofAndIndexedAccess.ts, 291, 3))
>on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 289, 56))
>test : Symbol(test, Decl(keyofAndIndexedAccess.ts, 291, 23))
var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean }
>hashOfEmpty2 : Symbol(hashOfEmpty2, Decl(keyofAndIndexedAccess.ts, 292, 3))
>on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 289, 56))
>test : Symbol(test, Decl(keyofAndIndexedAccess.ts, 292, 23))
>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 292, 31))

View File

@@ -982,3 +982,223 @@ class OtherPerson {
}
}
// Modified repro from #12544
function path<T, K1 extends keyof T>(obj: T, key1: K1): T[K1];
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>T : T
>K1 : K1
>T : T
>obj : T
>T : T
>key1 : K1
>K1 : K1
>T : T
>K1 : K1
function path<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2];
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>T : T
>K1 : K1
>T : T
>K2 : K2
>T : T
>K1 : K1
>obj : T
>T : T
>key1 : K1
>K1 : K1
>key2 : K2
>K2 : K2
>T : T
>K1 : K1
>K2 : K2
function path<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3];
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>T : T
>K1 : K1
>T : T
>K2 : K2
>T : T
>K1 : K1
>K3 : K3
>T : T
>K1 : K1
>K2 : K2
>obj : T
>T : T
>key1 : K1
>K1 : K1
>key2 : K2
>K2 : K2
>key3 : K3
>K3 : K3
>T : T
>K1 : K1
>K2 : K2
>K3 : K3
function path(obj: any, ...keys: (string | number)[]): any;
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>obj : any
>keys : (string | number)[]
function path(obj: any, ...keys: (string | number)[]): any {
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>obj : any
>keys : (string | number)[]
let result = obj;
>result : any
>obj : any
for (let k of keys) {
>k : string | number
>keys : (string | number)[]
result = result[k];
>result = result[k] : any
>result : any
>result[k] : any
>result : any
>k : string | number
}
return result;
>result : any
}
type Thing = {
>Thing : Thing
a: { x: number, y: string },
>a : { x: number; y: string; }
>x : number
>y : string
b: boolean
>b : boolean
};
function f1(thing: Thing) {
>f1 : (thing: Thing) => void
>thing : Thing
>Thing : Thing
let x1 = path(thing, 'a'); // { x: number, y: string }
>x1 : { x: number; y: string; }
>path(thing, 'a') : { x: number; y: string; }
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>thing : Thing
>'a' : "a"
let x2 = path(thing, 'a', 'y'); // string
>x2 : string
>path(thing, 'a', 'y') : string
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>thing : Thing
>'a' : "a"
>'y' : "y"
let x3 = path(thing, 'b'); // boolean
>x3 : boolean
>path(thing, 'b') : boolean
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>thing : Thing
>'b' : "b"
let x4 = path(thing, ...['a', 'x']); // any
>x4 : any
>path(thing, ...['a', 'x']) : any
>path : { <T, K1 extends keyof T>(obj: T, key1: K1): T[K1]; <T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2]; <T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; (obj: any, ...keys: (string | number)[]): any; }
>thing : Thing
>...['a', 'x'] : string
>['a', 'x'] : string[]
>'a' : "a"
>'x' : "x"
}
// Repro from comment in #12114
const assignTo2 = <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) =>
>assignTo2 : <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => T[K1][K2]
><T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => object[key1][key2] = value : <T, K1 extends keyof T, K2 extends keyof T[K1]>(object: T, key1: K1, key2: K2) => (value: T[K1][K2]) => T[K1][K2]
>T : T
>K1 : K1
>T : T
>K2 : K2
>T : T
>K1 : K1
>object : T
>T : T
>key1 : K1
>K1 : K1
>key2 : K2
>K2 : K2
(value: T[K1][K2]) => object[key1][key2] = value;
>(value: T[K1][K2]) => object[key1][key2] = value : (value: T[K1][K2]) => T[K1][K2]
>value : T[K1][K2]
>T : T
>K1 : K1
>K2 : K2
>object[key1][key2] = value : T[K1][K2]
>object[key1][key2] : T[K1][K2]
>object[key1] : T[K1]
>object : T
>key1 : K1
>key2 : K2
>value : T[K1][K2]
// Modified repro from #12573
declare function one<T>(handler: (t: T) => void): T
>one : <T>(handler: (t: T) => void) => T
>T : T
>handler : (t: T) => void
>t : T
>T : T
>T : T
var empty = one(() => {}) // inferred as {}, expected
>empty : {}
>one(() => {}) : {}
>one : <T>(handler: (t: T) => void) => T
>() => {} : () => void
type Handlers<T> = { [K in keyof T]: (t: T[K]) => void }
>Handlers : Handlers<T>
>T : T
>K : K
>T : T
>t : T[K]
>T : T
>K : K
declare function on<T>(handlerHash: Handlers<T>): T
>on : <T>(handlerHash: Handlers<T>) => T
>T : T
>handlerHash : Handlers<T>
>Handlers : Handlers<T>
>T : T
>T : T
var hashOfEmpty1 = on({ test: () => {} }); // {}
>hashOfEmpty1 : {}
>on({ test: () => {} }) : {}
>on : <T>(handlerHash: Handlers<T>) => T
>{ test: () => {} } : { test: () => void; }
>test : () => void
>() => {} : () => void
var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean }
>hashOfEmpty2 : { test: boolean; }
>on({ test: (x: boolean) => {} }) : { test: boolean; }
>on : <T>(handlerHash: Handlers<T>) => T
>{ test: (x: boolean) => {} } : { test: (x: boolean) => void; }
>test : (x: boolean) => void
>(x: boolean) => {} : (x: boolean) => void
>x : boolean