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