Accept new baselines

This commit is contained in:
Anders Hejlsberg 2017-10-26 14:57:03 -07:00
parent 14b7e755ef
commit 2669061693
4 changed files with 863 additions and 0 deletions

View file

@ -0,0 +1,92 @@
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(7,1): error TS2322: Type '{ a: number; b: number; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
Type '{ a: number; b: number; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
Property 'c' is missing in type '{ a: number; b: number; }'.
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(8,1): error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
Type '{ b: string; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
Property 'a' is missing in type '{ b: string; }'.
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(9,1): error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
Type '{ c: true; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
Property 'a' is missing in type '{ c: true; }'.
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(17,1): error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'.
Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'.
Types of property 'a' are incompatible.
Type 'string' is not assignable to type 'undefined'.
tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(18,1): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'.
Type '{ a: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'.
Types of property 'a' are incompatible.
Type 'number' is not assignable to type 'undefined'.
==== tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts (5 errors) ====
// Object literals in unions are normalized upon widening
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
a1.a; // number
a1.b; // string | undefined
a1.c; // boolean | undefined
a1 = { a: 1 };
a1 = { a: 0, b: 0 }; // Error
~~
!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
!!! error TS2322: Property 'c' is missing in type '{ a: number; b: number; }'.
a1 = { b: "y" }; // Error
~~
!!! error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
!!! error TS2322: Type '{ b: string; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
!!! error TS2322: Property 'a' is missing in type '{ b: string; }'.
a1 = { c: true }; // Error
~~
!!! error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'.
!!! error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b: string; c: boolean; }'.
!!! error TS2322: Property 'a' is missing in type '{ c: true; }'.
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
a2.a; // string | number | undefined
a2.b; // number | undefined
a2 = { a: 10, b: 20 };
a2 = { a: "def" };
a2 = {};
a2 = { a: "def", b: 20 }; // Error
~~
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'.
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'undefined'.
a2 = { a: 1 }; // Error
~~
!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'.
!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'undefined'.
// Object literals containing spreads are not normalized
declare let b1: { a: string, b: string } | { b: string, c: string };
let b2 = { ...b1, z: 55 };
let b3 = { ...b2 };
// Before widening {} acts like { [x: string]: undefined }, which is a
// subtype of types with all optional properties
declare let opts: { foo?: string, bar?: string, baz?: boolean };
let c1 = !true ? {} : opts;
let c2 = !true ? opts : {};
let c3 = !true ? { a: 0, b: 0 } : {};
let c4 = !true ? {} : { a: 0, b: 0 };
// Normalization applies to nested properties
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
d1.kind;
d1.pos;
d1.pos.x;
d1.pos.y;
d1.pos.a;
d1.pos.b;
declare function f<T>(...items: T[]): T;
declare let data: { a: 1, b: "abc", c: true };
// Object literals are inferred as a single normalized union type
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
let e3 = f(data, { a: 2 });
let e4 = f({ a: 2 }, data);

View file

@ -0,0 +1,232 @@
//// [objectLiteralNormalization.ts]
// Object literals in unions are normalized upon widening
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
a1.a; // number
a1.b; // string | undefined
a1.c; // boolean | undefined
a1 = { a: 1 };
a1 = { a: 0, b: 0 }; // Error
a1 = { b: "y" }; // Error
a1 = { c: true }; // Error
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
a2.a; // string | number | undefined
a2.b; // number | undefined
a2 = { a: 10, b: 20 };
a2 = { a: "def" };
a2 = {};
a2 = { a: "def", b: 20 }; // Error
a2 = { a: 1 }; // Error
// Object literals containing spreads are not normalized
declare let b1: { a: string, b: string } | { b: string, c: string };
let b2 = { ...b1, z: 55 };
let b3 = { ...b2 };
// Before widening {} acts like { [x: string]: undefined }, which is a
// subtype of types with all optional properties
declare let opts: { foo?: string, bar?: string, baz?: boolean };
let c1 = !true ? {} : opts;
let c2 = !true ? opts : {};
let c3 = !true ? { a: 0, b: 0 } : {};
let c4 = !true ? {} : { a: 0, b: 0 };
// Normalization applies to nested properties
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
d1.kind;
d1.pos;
d1.pos.x;
d1.pos.y;
d1.pos.a;
d1.pos.b;
declare function f<T>(...items: T[]): T;
declare let data: { a: 1, b: "abc", c: true };
// Object literals are inferred as a single normalized union type
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
let e3 = f(data, { a: 2 });
let e4 = f({ a: 2 }, data);
//// [objectLiteralNormalization.js]
"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
// Object literals in unions are normalized upon widening
var a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
a1.a; // number
a1.b; // string | undefined
a1.c; // boolean | undefined
a1 = { a: 1 };
a1 = { a: 0, b: 0 }; // Error
a1 = { b: "y" }; // Error
a1 = { c: true }; // Error
var a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
a2.a; // string | number | undefined
a2.b; // number | undefined
a2 = { a: 10, b: 20 };
a2 = { a: "def" };
a2 = {};
a2 = { a: "def", b: 20 }; // Error
a2 = { a: 1 }; // Error
var b2 = __assign({}, b1, { z: 55 });
var b3 = __assign({}, b2);
var c1 = !true ? {} : opts;
var c2 = !true ? opts : {};
var c3 = !true ? { a: 0, b: 0 } : {};
var c4 = !true ? {} : { a: 0, b: 0 };
// Normalization applies to nested properties
var d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
d1.kind;
d1.pos;
d1.pos.x;
d1.pos.y;
d1.pos.a;
d1.pos.b;
// Object literals are inferred as a single normalized union type
var e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
var e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
var e3 = f(data, { a: 2 });
var e4 = f({ a: 2 }, data);
//// [objectLiteralNormalization.d.ts]
declare let a1: {
a: number;
b?: undefined;
c?: undefined;
} | {
a: number;
b: string;
c?: undefined;
} | {
a: number;
b: string;
c: boolean;
};
declare let a2: {
a: number;
b: number;
} | {
a: string;
b?: undefined;
} | {
a?: undefined;
b?: undefined;
};
declare let b1: {
a: string;
b: string;
} | {
b: string;
c: string;
};
declare let b2: {
z: number;
a: string;
b: string;
} | {
z: number;
b: string;
c: string;
};
declare let b3: {
z: number;
a: string;
b: string;
} | {
z: number;
b: string;
c: string;
};
declare let opts: {
foo?: string;
bar?: string;
baz?: boolean;
};
declare let c1: {
foo?: string | undefined;
bar?: string | undefined;
baz?: boolean | undefined;
};
declare let c2: {
foo?: string | undefined;
bar?: string | undefined;
baz?: boolean | undefined;
};
declare let c3: {
a: number;
b: number;
} | {
a?: undefined;
b?: undefined;
};
declare let c4: {
a?: undefined;
b?: undefined;
} | {
a: number;
b: number;
};
declare let d1: {
kind: string;
pos: {
x: number;
y: number;
a?: undefined;
b?: undefined;
};
} | {
kind: string;
pos: {
a: string;
x?: undefined;
y?: undefined;
b?: undefined;
} | {
b: number;
x?: undefined;
y?: undefined;
a?: undefined;
};
};
declare function f<T>(...items: T[]): T;
declare let data: {
a: 1;
b: "abc";
c: true;
};
declare let e1: {
a: number;
b: number;
} | {
a: string;
b?: undefined;
} | {
a?: undefined;
b?: undefined;
};
declare let e2: {
a?: undefined;
b?: undefined;
} | {
a: string;
b?: undefined;
} | {
a: number;
b: number;
};
declare let e3: {
a: number;
};
declare let e4: {
a: number;
};

View file

@ -0,0 +1,213 @@
=== tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts ===
// Object literals in unions are normalized upon widening
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 11))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 21))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 27))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 39))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 45))
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53))
a1.a; // number
>a1.a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 11), Decl(objectLiteralNormalization.ts, 1, 21), Decl(objectLiteralNormalization.ts, 1, 39))
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 11), Decl(objectLiteralNormalization.ts, 1, 21), Decl(objectLiteralNormalization.ts, 1, 39))
a1.b; // string | undefined
>a1.b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 27), Decl(objectLiteralNormalization.ts, 1, 45))
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 27), Decl(objectLiteralNormalization.ts, 1, 45))
a1.c; // boolean | undefined
>a1.c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53))
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53))
a1 = { a: 1 };
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 5, 6))
a1 = { a: 0, b: 0 }; // Error
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 6, 6))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 6, 12))
a1 = { b: "y" }; // Error
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 7, 6))
a1 = { c: true }; // Error
>a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3))
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 8, 6))
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 27))
a2.a; // string | number | undefined
>a2.a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27))
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27))
a2.b; // number | undefined
>a2.b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17))
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17))
a2 = { a: 10, b: 20 };
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 13, 6))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 13, 13))
a2 = { a: "def" };
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 14, 6))
a2 = {};
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
a2 = { a: "def", b: 20 }; // Error
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 16, 6))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 16, 16))
a2 = { a: 1 }; // Error
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 17, 6))
// Object literals containing spreads are not normalized
declare let b1: { a: string, b: string } | { b: string, c: string };
>b1 : Symbol(b1, Decl(objectLiteralNormalization.ts, 20, 11))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 20, 17))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 20, 28))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 20, 44))
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 20, 55))
let b2 = { ...b1, z: 55 };
>b2 : Symbol(b2, Decl(objectLiteralNormalization.ts, 21, 3))
>b1 : Symbol(b1, Decl(objectLiteralNormalization.ts, 20, 11))
>z : Symbol(z, Decl(objectLiteralNormalization.ts, 21, 17))
let b3 = { ...b2 };
>b3 : Symbol(b3, Decl(objectLiteralNormalization.ts, 22, 3))
>b2 : Symbol(b2, Decl(objectLiteralNormalization.ts, 21, 3))
// Before widening {} acts like { [x: string]: undefined }, which is a
// subtype of types with all optional properties
declare let opts: { foo?: string, bar?: string, baz?: boolean };
>opts : Symbol(opts, Decl(objectLiteralNormalization.ts, 26, 11))
>foo : Symbol(foo, Decl(objectLiteralNormalization.ts, 26, 19))
>bar : Symbol(bar, Decl(objectLiteralNormalization.ts, 26, 33))
>baz : Symbol(baz, Decl(objectLiteralNormalization.ts, 26, 47))
let c1 = !true ? {} : opts;
>c1 : Symbol(c1, Decl(objectLiteralNormalization.ts, 27, 3))
>opts : Symbol(opts, Decl(objectLiteralNormalization.ts, 26, 11))
let c2 = !true ? opts : {};
>c2 : Symbol(c2, Decl(objectLiteralNormalization.ts, 28, 3))
>opts : Symbol(opts, Decl(objectLiteralNormalization.ts, 26, 11))
let c3 = !true ? { a: 0, b: 0 } : {};
>c3 : Symbol(c3, Decl(objectLiteralNormalization.ts, 29, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 29, 18))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 29, 24))
let c4 = !true ? {} : { a: 0, b: 0 };
>c4 : Symbol(c4, Decl(objectLiteralNormalization.ts, 30, 3))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 30, 23))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 30, 29))
// Normalization applies to nested properties
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
>kind : Symbol(kind, Decl(objectLiteralNormalization.ts, 33, 11))
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22))
>x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29))
>y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35))
>kind : Symbol(kind, Decl(objectLiteralNormalization.ts, 33, 47))
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 58))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86))
d1.kind;
>d1.kind : Symbol(kind, Decl(objectLiteralNormalization.ts, 33, 11), Decl(objectLiteralNormalization.ts, 33, 47))
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
>kind : Symbol(kind, Decl(objectLiteralNormalization.ts, 33, 11), Decl(objectLiteralNormalization.ts, 33, 47))
d1.pos;
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
d1.pos.x;
>d1.pos.x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29))
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29))
d1.pos.y;
>d1.pos.y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35))
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35))
d1.pos.a;
>d1.pos.a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73))
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73))
d1.pos.b;
>d1.pos.b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86))
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86))
declare function f<T>(...items: T[]): T;
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
>T : Symbol(T, Decl(objectLiteralNormalization.ts, 41, 19))
>items : Symbol(items, Decl(objectLiteralNormalization.ts, 41, 22))
>T : Symbol(T, Decl(objectLiteralNormalization.ts, 41, 19))
>T : Symbol(T, Decl(objectLiteralNormalization.ts, 41, 19))
declare let data: { a: 1, b: "abc", c: true };
>data : Symbol(data, Decl(objectLiteralNormalization.ts, 42, 11))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 42, 19))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 42, 25))
>c : Symbol(c, Decl(objectLiteralNormalization.ts, 42, 35))
// Object literals are inferred as a single normalized union type
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
>e1 : Symbol(e1, Decl(objectLiteralNormalization.ts, 45, 3))
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 45, 12))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 45, 18))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 45, 28))
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
>e2 : Symbol(e2, Decl(objectLiteralNormalization.ts, 46, 3))
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 46, 16))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 46, 30))
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 46, 36))
let e3 = f(data, { a: 2 });
>e3 : Symbol(e3, Decl(objectLiteralNormalization.ts, 47, 3))
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
>data : Symbol(data, Decl(objectLiteralNormalization.ts, 42, 11))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 47, 18))
let e4 = f({ a: 2 }, data);
>e4 : Symbol(e4, Decl(objectLiteralNormalization.ts, 48, 3))
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 48, 12))
>data : Symbol(data, Decl(objectLiteralNormalization.ts, 42, 11))

View file

@ -0,0 +1,326 @@
=== tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts ===
// Object literals in unions are normalized upon widening
let a1 = [{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0];
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
>[{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }][0] : { a: number; } | { a: number; b: string; } | { a: number; b: string; c: boolean; }
>[{ a: 0 }, { a: 1, b: "x" }, { a: 2, b: "y", c: true }] : ({ a: number; } | { a: number; b: string; } | { a: number; b: string; c: boolean; })[]
>{ a: 0 } : { a: number; }
>a : number
>0 : 0
>{ a: 1, b: "x" } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>"x" : "x"
>{ a: 2, b: "y", c: true } : { a: number; b: string; c: boolean; }
>a : number
>2 : 2
>b : string
>"y" : "y"
>c : boolean
>true : true
>0 : 0
a1.a; // number
>a1.a : number
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
>a : number
a1.b; // string | undefined
>a1.b : string | undefined
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
>b : string | undefined
a1.c; // boolean | undefined
>a1.c : boolean | undefined
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
>c : boolean | undefined
a1 = { a: 1 };
>a1 = { a: 1 } : { a: number; }
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
>{ a: 1 } : { a: number; }
>a : number
>1 : 1
a1 = { a: 0, b: 0 }; // Error
>a1 = { a: 0, b: 0 } : { a: number; b: number; }
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
>{ a: 0, b: 0 } : { a: number; b: number; }
>a : number
>0 : 0
>b : number
>0 : 0
a1 = { b: "y" }; // Error
>a1 = { b: "y" } : { b: string; }
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
>{ b: "y" } : { b: string; }
>b : string
>"y" : "y"
a1 = { c: true }; // Error
>a1 = { c: true } : { c: true; }
>a1 : { a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }
>{ c: true } : { c: true; }
>c : boolean
>true : true
let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0];
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>[{ a: 1, b: 2 }, { a: "abc" }, {}][0] : { a: number; b: number; } | { a: string; } | {}
>[{ a: 1, b: 2 }, { a: "abc" }, {}] : ({ a: number; b: number; } | { a: string; } | {})[]
>{ a: 1, b: 2 } : { a: number; b: number; }
>a : number
>1 : 1
>b : number
>2 : 2
>{ a: "abc" } : { a: string; }
>a : string
>"abc" : "abc"
>{} : {}
>0 : 0
a2.a; // string | number | undefined
>a2.a : string | number | undefined
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>a : string | number | undefined
a2.b; // number | undefined
>a2.b : number | undefined
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>b : number | undefined
a2 = { a: 10, b: 20 };
>a2 = { a: 10, b: 20 } : { a: number; b: number; }
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>{ a: 10, b: 20 } : { a: number; b: number; }
>a : number
>10 : 10
>b : number
>20 : 20
a2 = { a: "def" };
>a2 = { a: "def" } : { a: string; }
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>{ a: "def" } : { a: string; }
>a : string
>"def" : "def"
a2 = {};
>a2 = {} : {}
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>{} : {}
a2 = { a: "def", b: 20 }; // Error
>a2 = { a: "def", b: 20 } : { a: string; b: number; }
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>{ a: "def", b: 20 } : { a: string; b: number; }
>a : string
>"def" : "def"
>b : number
>20 : 20
a2 = { a: 1 }; // Error
>a2 = { a: 1 } : { a: number; }
>a2 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>{ a: 1 } : { a: number; }
>a : number
>1 : 1
// Object literals containing spreads are not normalized
declare let b1: { a: string, b: string } | { b: string, c: string };
>b1 : { a: string; b: string; } | { b: string; c: string; }
>a : string
>b : string
>b : string
>c : string
let b2 = { ...b1, z: 55 };
>b2 : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
>{ ...b1, z: 55 } : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
>b1 : { a: string; b: string; } | { b: string; c: string; }
>z : number
>55 : 55
let b3 = { ...b2 };
>b3 : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
>{ ...b2 } : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
>b2 : { z: number; a: string; b: string; } | { z: number; b: string; c: string; }
// Before widening {} acts like { [x: string]: undefined }, which is a
// subtype of types with all optional properties
declare let opts: { foo?: string, bar?: string, baz?: boolean };
>opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
>foo : string | undefined
>bar : string | undefined
>baz : boolean | undefined
let c1 = !true ? {} : opts;
>c1 : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
>!true ? {} : opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
>!true : false
>true : true
>{} : {}
>opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
let c2 = !true ? opts : {};
>c2 : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
>!true ? opts : {} : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
>!true : false
>true : true
>opts : { foo?: string | undefined; bar?: string | undefined; baz?: boolean | undefined; }
>{} : {}
let c3 = !true ? { a: 0, b: 0 } : {};
>c3 : { a: number; b: number; } | { a?: undefined; b?: undefined; }
>!true ? { a: 0, b: 0 } : {} : { a: number; b: number; } | {}
>!true : false
>true : true
>{ a: 0, b: 0 } : { a: number; b: number; }
>a : number
>0 : 0
>b : number
>0 : 0
>{} : {}
let c4 = !true ? {} : { a: 0, b: 0 };
>c4 : { a?: undefined; b?: undefined; } | { a: number; b: number; }
>!true ? {} : { a: 0, b: 0 } : {} | { a: number; b: number; }
>!true : false
>true : true
>{} : {}
>{ a: 0, b: 0 } : { a: number; b: number; }
>a : number
>0 : 0
>b : number
>0 : 0
// Normalization applies to nested properties
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
>[{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0] : { kind: string; pos: { x: number; y: number; }; } | { kind: string; pos: { a: string; } | { b: number; }; }
>[{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }] : ({ kind: string; pos: { x: number; y: number; }; } | { kind: string; pos: { a: string; } | { b: number; }; })[]
>{ kind: 'a', pos: { x: 0, y: 0 } } : { kind: string; pos: { x: number; y: number; }; }
>kind : string
>'a' : "a"
>pos : { x: number; y: number; }
>{ x: 0, y: 0 } : { x: number; y: number; }
>x : number
>0 : 0
>y : number
>0 : 0
>{ kind: 'b', pos: !true ? { a: "x" } : { b: 0 } } : { kind: string; pos: { a: string; } | { b: number; }; }
>kind : string
>'b' : "b"
>pos : { a: string; } | { b: number; }
>!true ? { a: "x" } : { b: 0 } : { a: string; } | { b: number; }
>!true : false
>true : true
>{ a: "x" } : { a: string; }
>a : string
>"x" : "x"
>{ b: 0 } : { b: number; }
>b : number
>0 : 0
>0 : 0
d1.kind;
>d1.kind : string
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
>kind : string
d1.pos;
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
d1.pos.x;
>d1.pos.x : number | undefined
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>x : number | undefined
d1.pos.y;
>d1.pos.y : number | undefined
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>y : number | undefined
d1.pos.a;
>d1.pos.a : string | undefined
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>a : string | undefined
d1.pos.b;
>d1.pos.b : number | undefined
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }; }
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { a: string; x?: undefined; y?: undefined; b?: undefined; } | { b: number; x?: undefined; y?: undefined; a?: undefined; }
>b : number | undefined
declare function f<T>(...items: T[]): T;
>f : <T>(...items: T[]) => T
>T : T
>items : T[]
>T : T
>T : T
declare let data: { a: 1, b: "abc", c: true };
>data : { a: 1; b: "abc"; c: true; }
>a : 1
>b : "abc"
>c : true
>true : true
// Object literals are inferred as a single normalized union type
let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
>e1 : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>f({ a: 1, b: 2 }, { a: "abc" }, {}) : { a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }
>f : <T>(...items: T[]) => T
>{ a: 1, b: 2 } : { a: number; b: number; }
>a : number
>1 : 1
>b : number
>2 : 2
>{ a: "abc" } : { a: string; }
>a : string
>"abc" : "abc"
>{} : {}
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
>e2 : { a?: undefined; b?: undefined; } | { a: string; b?: undefined; } | { a: number; b: number; }
>f({}, { a: "abc" }, { a: 1, b: 2 }) : { a?: undefined; b?: undefined; } | { a: string; b?: undefined; } | { a: number; b: number; }
>f : <T>(...items: T[]) => T
>{} : {}
>{ a: "abc" } : { a: string; }
>a : string
>"abc" : "abc"
>{ a: 1, b: 2 } : { a: number; b: number; }
>a : number
>1 : 1
>b : number
>2 : 2
let e3 = f(data, { a: 2 });
>e3 : { a: number; }
>f(data, { a: 2 }) : { a: number; }
>f : <T>(...items: T[]) => T
>data : { a: 1; b: "abc"; c: true; }
>{ a: 2 } : { a: number; }
>a : number
>2 : 2
let e4 = f({ a: 2 }, data);
>e4 : { a: number; }
>f({ a: 2 }, data) : { a: number; }
>f : <T>(...items: T[]) => T
>{ a: 2 } : { a: number; }
>a : number
>2 : 2
>data : { a: 1; b: "abc"; c: true; }