TypeScript/tests/baselines/reference/isomorphicMappedTypeInference.js
Wesley Wigham d1b43429c2
Allow nested reverse mapped type printback (#42485)
* Optimize interning of reverse mapped types

* Style feedback

* Whitespace

* Update baseline
2021-04-05 11:37:51 -07:00

400 lines
9.5 KiB
TypeScript

//// [isomorphicMappedTypeInference.ts]
type Box<T> = {
value: T;
}
type Boxified<T> = {
[P in keyof T]: Box<T[P]>;
}
function box<T>(x: T): Box<T> {
return { value: x };
}
function unbox<T>(x: Box<T>): T {
return x.value;
}
function boxify<T>(obj: T): Boxified<T> {
let result = {} as Boxified<T>;
for (let k in obj) {
result[k] = box(obj[k]);
}
return result;
}
function unboxify<T>(obj: Boxified<T>): T {
let result = {} as T;
for (let k in obj) {
result[k] = unbox(obj[k]);
}
return result;
}
function assignBoxified<T>(obj: Boxified<T>, 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<T, K extends string>(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<T>(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<T>(obj: { [P in keyof T]?: T[P] }): T;
declare function clone<T>(obj: { readonly [P in keyof T]: T[P] }): T;
declare function validateAndClone<T>(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<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 } } });
// Repro from #12633
const foo = <T>(object: T, partial: Partial<T>) => 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<T, K extends keyof T>(obj: Pick<T, K>): T;
declare function f21<T, K extends keyof T>(obj: Pick<T, K>): K;
declare function f22<T, K extends keyof T>(obj: Boxified<Pick<T, K>>): T;
declare function f23<T, U extends keyof T, K extends U>(obj: Pick<T, K>): T;
declare function f24<T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>): 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<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K> {
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<T> = {
value: T;
};
declare type Boxified<T> = {
[P in keyof T]: Box<T[P]>;
};
declare function box<T>(x: T): Box<T>;
declare function unbox<T>(x: Box<T>): T;
declare function boxify<T>(obj: T): Boxified<T>;
declare function unboxify<T>(obj: Boxified<T>): T;
declare function assignBoxified<T>(obj: Boxified<T>, values: T): void;
declare function f1(): void;
declare function f2(): void;
declare function f3(): void;
declare function f4(): void;
declare function makeRecord<T, K extends string>(obj: {
[P in K]: T;
}): { [P in K]: T; };
declare function f5(s: string): void;
declare function makeDictionary<T>(obj: {
[x: string]: T;
}): {
[x: string]: T;
};
declare function f6(s: string): void;
declare function validate<T>(obj: {
[P in keyof T]?: T[P];
}): T;
declare function clone<T>(obj: {
readonly [P in keyof T]: T[P];
}): T;
declare function validateAndClone<T>(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<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;
};
};
};
declare const foo: <T>(object: T, partial: Partial<T>) => T;
declare let o: {
a: number;
b: number;
};
declare function f20<T, K extends keyof T>(obj: Pick<T, K>): T;
declare function f21<T, K extends keyof T>(obj: Pick<T, K>): K;
declare function f22<T, K extends keyof T>(obj: Boxified<Pick<T, K>>): T;
declare function f23<T, U extends keyof T, K extends U>(obj: Pick<T, K>): T;
declare function f24<T, U, K extends keyof T | keyof U>(obj: Pick<T & U, K>): 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<T, K extends keyof T>(obj: T, list: K[]): Pick<T, K>;
declare const myAny: any;
declare const o1: Pick<any, "foo" | "bar">;
declare const o2: {
foo: any;
bar: any;
};