2016-09-26 18:33:08 +02:00
|
|
|
// @target: es5
|
|
|
|
let o = { a: 1, b: 'no' }
|
|
|
|
|
|
|
|
/// private propagates
|
|
|
|
class PrivateOptionalX {
|
|
|
|
private x?: number;
|
|
|
|
}
|
|
|
|
class PublicX {
|
|
|
|
public x: number;
|
|
|
|
}
|
2016-11-03 17:39:58 +01:00
|
|
|
let publicX: PublicX;
|
|
|
|
let privateOptionalX: PrivateOptionalX;
|
|
|
|
let o2 = { ...publicX, ...privateOptionalX };
|
2016-10-10 19:07:41 +02:00
|
|
|
let sn: number = o2.x; // error, x is private
|
2016-09-26 18:33:08 +02:00
|
|
|
let optionalString: { sn?: string };
|
|
|
|
let optionalNumber: { sn?: number };
|
|
|
|
let allOptional: { sn: string | number } = { ...optionalString, ...optionalNumber };
|
|
|
|
// error, 'sn' is optional in source, required in target
|
|
|
|
|
|
|
|
// assignability as target
|
|
|
|
interface Bool { b: boolean };
|
|
|
|
interface Str { s: string };
|
2016-11-03 17:39:58 +01:00
|
|
|
let spread = { ...{ b: true }, ...{s: "foo" } };
|
|
|
|
spread = { s: "foo" }; // error, missing 'b'
|
|
|
|
let b = { b: false };
|
2016-09-26 18:33:08 +02:00
|
|
|
spread = b; // error, missing 's'
|
|
|
|
|
|
|
|
// literal repeats are not allowed, but spread repeats are fine
|
|
|
|
let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
|
|
|
|
let duplicatedSpread = { ...o, ...o }
|
|
|
|
|
2016-11-03 17:39:58 +01:00
|
|
|
// null, undefined and primitives are not allowed
|
|
|
|
let spreadNull = { ...null };
|
|
|
|
let spreadUndefind = { ...undefined };
|
2016-10-10 19:07:41 +02:00
|
|
|
let spreadNum = { ...12 };
|
|
|
|
let spreadSum = { ...1 + 1 };
|
|
|
|
spreadSum.toFixed(); // error, no methods from number
|
2016-11-03 17:39:58 +01:00
|
|
|
let spreadBool = { ...false };
|
|
|
|
spreadBool.valueOf(); // error, what were you thinking?
|
2016-10-10 19:07:41 +02:00
|
|
|
let spreadStr = { ...'foo' };
|
|
|
|
spreadStr.length; // error, no 'length'
|
|
|
|
spreadStr.charAt(1); // error, no methods either
|
2016-11-03 17:39:58 +01:00
|
|
|
// functions are skipped
|
2016-10-10 19:07:41 +02:00
|
|
|
let spreadFunc = { ...function () { } }
|
|
|
|
spreadFunc(); // error, no call signature
|
|
|
|
|
2016-09-26 18:33:08 +02:00
|
|
|
// write-only properties get skipped
|
|
|
|
let setterOnly = { ...{ set b (bad: number) { } } };
|
|
|
|
setterOnly.b = 12; // error, 'b' does not exist
|
|
|
|
|
|
|
|
// methods are skipped because they aren't enumerable
|
|
|
|
class C { p = 1; m() { } }
|
|
|
|
let c: C = new C()
|
|
|
|
let spreadC = { ...c }
|
|
|
|
spreadC.m(); // error 'm' is not in '{ ... c }'
|
|
|
|
|
2016-11-03 17:39:58 +01:00
|
|
|
// generics
|
|
|
|
function f<T, U>(t: T, u: U) {
|
|
|
|
return { ...t, ...u, id: 'id' };
|
|
|
|
}
|
|
|
|
function override<U>(initial: U, override: U): U {
|
2016-10-04 00:49:23 +02:00
|
|
|
return { ...initial, ...override };
|
|
|
|
}
|
2016-11-03 17:39:58 +01:00
|
|
|
let exclusive: { id: string, a: number, b: string, c: string, d: boolean } =
|
|
|
|
f({ a: 1, b: 'yes' }, { c: 'no', d: false })
|
|
|
|
let overlap: { id: string, a: number, b: string } =
|
|
|
|
f({ a: 1 }, { a: 2, b: 'extra' })
|
|
|
|
let overlapConflict: { id:string, a: string } =
|
|
|
|
f({ a: 1 }, { a: 'mismatch' })
|
|
|
|
let overwriteId: { id: string, a: number, c: number, d: string } =
|
|
|
|
f({ a: 1, id: true }, { c: 1, d: 'no' })
|