//// [isomorphicMappedTypeInference.ts] type Box = { value: T; } type Boxified = { [P in keyof T]: Box; } function box(x: T): Box { return { value: x }; } function unbox(x: Box): T { return x.value; } function boxify(obj: T): Boxified { let result = {} as Boxified; for (let k in obj) { result[k] = box(obj[k]); } return result; } function unboxify(obj: Boxified): T { let result = {} as T; for (let k in obj) { result[k] = unbox(obj[k]); } return result; } function assignBoxified(obj: Boxified, values: T) { for (let k in values) { obj[k].value = values[k]; } } function f1() { let v = { a: 42, b: "hello", c: true }; let b = boxify(v); let x: number = b.a.value; } function f2() { let b = { a: box(42), b: box("hello"), c: box(true) }; let v = unboxify(b); let x: number = v.a; } function f3() { let b = { a: box(42), b: box("hello"), c: box(true) }; assignBoxified(b, { c: false }); } function f4() { let b = { a: box(42), b: box("hello"), c: box(true) }; b = boxify(unboxify(b)); b = unboxify(boxify(b)); } function makeRecord(obj: { [P in K]: T }) { return obj; } function f5(s: string) { let b = makeRecord({ a: box(42), b: box("hello"), c: box(true) }); let v = unboxify(b); let x: string | number | boolean = v.a; } function makeDictionary(obj: { [x: string]: T }) { return obj; } function f6(s: string) { let b = makeDictionary({ a: box(42), b: box("hello"), c: box(true) }); let v = unboxify(b); let x: string | number | boolean = v[s]; } declare function validate(obj: { [P in keyof T]?: T[P] }): T; declare function clone(obj: { readonly [P in keyof T]: T[P] }): T; declare function validateAndClone(obj: { readonly [P in keyof T]?: T[P] }): T; type Foo = { a?: number; readonly b: string; } 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 = (...args: any[]) => T; type Spec = { [P in keyof T]: Func | Spec ; }; /** * 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(obj: Spec): (...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 } } }); // Repro from #12633 const foo = (object: T, partial: Partial) => object; let o = {a: 5, b: 7}; foo(o, {b: 9}); o = foo(o, {b: 9}); // Inferring to { [P in K]: X }, where K extends keyof T, produces same inferences as // inferring to { [P in keyof T]: X }. declare function f20(obj: Pick): T; declare function f21(obj: Pick): K; declare function f22(obj: Boxified>): T; declare function f23(obj: Pick): T; declare function f24(obj: Pick): T & U; let x0 = f20({ foo: 42, bar: "hello" }); let x1 = f21({ foo: 42, bar: "hello" }); let x2 = f22({ foo: { value: 42} , bar: { value: "hello" } }); let x3 = f23({ foo: 42, bar: "hello" }); let x4 = f24({ foo: 42, bar: "hello" }); // Repro from #29765 function getProps(obj: T, list: K[]): Pick { return {} as any; } const myAny: any = {}; const o1 = getProps(myAny, ['foo', 'bar']); const o2: { foo: any; bar: any } = getProps(myAny, ['foo', 'bar']); //// [isomorphicMappedTypeInference.js] function box(x) { return { value: x }; } function unbox(x) { return x.value; } function boxify(obj) { var result = {}; for (var k in obj) { result[k] = box(obj[k]); } return result; } function unboxify(obj) { var result = {}; for (var k in obj) { result[k] = unbox(obj[k]); } return result; } function assignBoxified(obj, values) { for (var k in values) { obj[k].value = values[k]; } } function f1() { var v = { a: 42, b: "hello", c: true }; var b = boxify(v); var x = b.a.value; } function f2() { var b = { a: box(42), b: box("hello"), c: box(true) }; var v = unboxify(b); var x = v.a; } function f3() { var b = { a: box(42), b: box("hello"), c: box(true) }; assignBoxified(b, { c: false }); } function f4() { var b = { a: box(42), b: box("hello"), c: box(true) }; b = boxify(unboxify(b)); b = unboxify(boxify(b)); } function makeRecord(obj) { return obj; } function f5(s) { var b = makeRecord({ a: box(42), b: box("hello"), c: box(true) }); var v = unboxify(b); var x = v.a; } function makeDictionary(obj) { return obj; } function f6(s) { var b = makeDictionary({ a: box(42), b: box("hello"), c: box(true) }); var v = unboxify(b); var x = v[s]; } function f10(foo) { var x = validate(foo); // { a: number, readonly b: string } 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; } } } }); // Repro from #12633 var foo = function (object, partial) { return object; }; var o = { a: 5, b: 7 }; foo(o, { b: 9 }); o = foo(o, { b: 9 }); var x0 = f20({ foo: 42, bar: "hello" }); var x1 = f21({ foo: 42, bar: "hello" }); var x2 = f22({ foo: { value: 42 }, bar: { value: "hello" } }); var x3 = f23({ foo: 42, bar: "hello" }); var x4 = f24({ foo: 42, bar: "hello" }); // Repro from #29765 function getProps(obj, list) { return {}; } var myAny = {}; var o1 = getProps(myAny, ['foo', 'bar']); var o2 = getProps(myAny, ['foo', 'bar']); //// [isomorphicMappedTypeInference.d.ts] declare type Box = { value: T; }; declare type Boxified = { [P in keyof T]: Box; }; declare function box(x: T): Box; declare function unbox(x: Box): T; declare function boxify(obj: T): Boxified; declare function unboxify(obj: Boxified): T; declare function assignBoxified(obj: Boxified, values: T): void; declare function f1(): void; declare function f2(): void; declare function f3(): void; declare function f4(): void; declare function makeRecord(obj: { [P in K]: T; }): { [P in K]: T; }; declare function f5(s: string): void; declare function makeDictionary(obj: { [x: string]: T; }): { [x: string]: T; }; declare function f6(s: string): void; declare function validate(obj: { [P in keyof T]?: T[P]; }): T; declare function clone(obj: { readonly [P in keyof T]: T[P]; }): T; declare function validateAndClone(obj: { readonly [P in keyof T]?: T[P]; }): T; declare type Foo = { a?: number; readonly b: string; }; declare function f10(foo: Foo): void; declare type Func = (...args: any[]) => T; declare type Spec = { [P in keyof T]: Func | Spec; }; /** * 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(obj: Spec): (...args: any[]) => T; declare var g1: (...args: any[]) => { sum: number; nested: { mul: string; }; }; declare var g2: (...args: any[]) => { foo: { bar: { baz: boolean; }; }; }; declare const foo: (object: T, partial: Partial) => T; declare let o: { a: number; b: number; }; declare function f20(obj: Pick): T; declare function f21(obj: Pick): K; declare function f22(obj: Boxified>): T; declare function f23(obj: Pick): T; declare function f24(obj: Pick): T & U; declare let x0: { foo: number; bar: string; }; declare let x1: "foo" | "bar"; declare let x2: { foo: number; bar: string; }; declare let x3: { foo: number; bar: string; }; declare let x4: { foo: number; bar: string; } & { foo: number; bar: string; }; declare function getProps(obj: T, list: K[]): Pick; declare const myAny: any; declare const o1: Pick; declare const o2: { foo: any; bar: any; };