swc/crates/swc_ecma_parser/tests/tsc/objectLiteralNormalization.ts

53 lines
1.5 KiB
TypeScript

// @strict: true
// @declaration: true
// 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);