• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// @target: es5
2// @strictNullChecks: true
3let o = { a: 1, b: 'no' }
4
5/// private propagates
6class PrivateOptionalX {
7    private x?: number;
8}
9class PublicX {
10    public x: number;
11}
12declare let publicX: PublicX;
13declare let privateOptionalX: PrivateOptionalX;
14let o2 = { ...publicX, ...privateOptionalX };
15let sn: number = o2.x; // error, x is private
16declare let optionalString: { sn?: string };
17declare let optionalNumber: { sn?: number };
18let allOptional: { sn: string | number } = { ...optionalString, ...optionalNumber };
19// error, 'sn' is optional in source, required in target
20
21// assignability as target
22interface Bool { b: boolean };
23interface Str { s: string };
24let spread = { ...{ b: true }, ...{s: "foo" } };
25spread = { s: "foo" };  // error, missing 'b'
26let b = { b: false };
27spread = b; // error, missing 's'
28
29// literal repeats are not allowed, but spread repeats are fine
30let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
31let duplicatedSpread = { ...o, ...o }
32// Note: ignore changes the order that properties are printed
33let ignore: { a: number, b: string } =
34    { b: 'ignored', ...o }
35
36let o3 = { a: 1, b: 'no' }
37let o4 = { b: 'yes', c: true }
38let combinedBefore: { a: number, b: string, c: boolean } =
39    { b: 'ok', ...o3, ...o4 }
40let combinedMid: { a: number, b: string, c: boolean } =
41    { ...o3, b: 'ok', ...o4 }
42let combinedNested: { a: number, b: boolean, c: string, d: string } =
43    { ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
44let changeTypeBefore: { a: number, b: string } =
45    { a: 'wrong type?', ...o3 };
46let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } =
47    { ...o3, ['in the middle']: 13, b: 'maybe?', ...o4 }
48
49// primitives are not allowed, except for falsy ones
50let spreadNum = { ...12 };
51let spreadSum = { ...1 + 1 };
52let spreadZero = { ...0 };
53spreadZero.toFixed(); // error, no methods even from a falsy number
54let spreadBool = { ...true };
55spreadBool.valueOf();
56let spreadStr = { ...'foo' };
57spreadStr.length; // error, no 'length'
58spreadStr.charAt(1); // error, no methods either
59// functions are skipped
60let spreadFunc = { ...function () { } }
61spreadFunc(); // error, no call signature
62
63// write-only properties get skipped
64let setterOnly = { ...{ set b (bad: number) { } } };
65setterOnly.b = 12; // error, 'b' does not exist
66
67// methods are skipped because they aren't enumerable
68class C { p = 1; m() { } }
69let c: C = new C()
70let spreadC = { ...c }
71spreadC.m(); // error 'm' is not in '{ ... c }'
72
73// non primitive
74let obj: object = { a: 123 };
75let spreadObj = { ...obj };
76spreadObj.a; // error 'a' is not in {}
77