diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 28c9fb25af9..62d44d160a7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7862,7 +7862,10 @@ namespace ts { return mapType(right, t => getSpreadType(left, t)); } if (right.flags & TypeFlags.NonPrimitive) { - return emptyObjectType; + return nonPrimitiveType; + } + if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.EnumLike)) { + return left; } const members = createSymbolTable(); @@ -7889,6 +7892,7 @@ namespace ts { members.set(rightProp.escapedName, getNonReadonlySymbol(rightProp)); } } + for (const leftProp of getPropertiesOfType(left)) { if (leftProp.flags & SymbolFlags.SetAccessor && !(leftProp.flags & SymbolFlags.GetAccessor) || skippedPrivateMembers.has(leftProp.escapedName) @@ -13784,7 +13788,8 @@ namespace ts { } function isValidSpreadType(type: Type): boolean { - return !!(type.flags & (TypeFlags.Any | TypeFlags.Null | TypeFlags.Undefined | TypeFlags.NonPrimitive) || + return !!(type.flags & (TypeFlags.Any | TypeFlags.NonPrimitive) || + getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) || type.flags & TypeFlags.Object && !isGenericMappedType(type) || type.flags & TypeFlags.UnionOrIntersection && !forEach((type).types, t => !isValidSpreadType(t))); } diff --git a/tests/baselines/reference/objectSpread.js b/tests/baselines/reference/objectSpread.js index e05837c32d5..eea39c8e773 100644 --- a/tests/baselines/reference/objectSpread.js +++ b/tests/baselines/reference/objectSpread.js @@ -38,6 +38,43 @@ getter.a = 12; // functions result in { } let spreadFunc = { ...(function () { }) }; +type Header = { head: string, body: string, authToken: string } +function from16326(this: { header: Header }, header: Header, authToken: string): Header { + return { + ...this.header, + ...header, + ...authToken && { authToken } + } +} +// boolean && T results in Partial +function conditionalSpreadBoolean(b: boolean) : { x: number, y: number } { + let o = { x: 12, y: 13 } + o = { + ...o, + ...b && { x: 14 } + } + let o2 = { ...b && { x: 21 }} + return o; +} +function conditionalSpreadNumber(nt: number): { x: number, y: number } { + let o = { x: 15, y: 16 } + o = { + ...o, + ...nt && { x: nt } + } + let o2 = { ...nt && { x: nt }} + return o; +} +function conditionalSpreadString(st: string): { x: string, y: number } { + let o = { x: 'hi', y: 17 } + o = { + ...o, + ...st && { x: st } + } + let o2 = { ...st && { x: st }} + return o; +} + // any results in any let anything: any; let spreadAny = { ...anything }; @@ -60,21 +97,23 @@ let changeTypeBoth: { a: string, b: number } = { ...o, ...swap }; // optional -let definiteBoolean: { sn: boolean }; -let definiteString: { sn: string }; -let optionalString: { sn?: string }; -let optionalNumber: { sn?: number }; -let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; -let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; -let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; +function container( + definiteBoolean: { sn: boolean }, + definiteString: { sn: string }, + optionalString: { sn?: string }, + optionalNumber: { sn?: number }) { + let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; + let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; + let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; -// computed property -let computedFirst: { a: number, b: string, "before everything": number } = - { ['before everything']: 12, ...o, b: 'yes' } -let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = - { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } -let computedAfter: { a: number, b: string, "at the end": number } = - { ...o, b: 'yeah', ['at the end']: 14 } + // computed property + let computedFirst: { a: number, b: string, "before everything": number } = + { ['before everything']: 12, ...o, b: 'yes' } + let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = + { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } + let computedAfter: { a: number, b: string, "at the end": number } = + { ...o, b: 'yeah', ['at the end']: 14 } +} // shortcut syntax let a = 12; let shortCutted: { a: number, b: string } = { ...o, a } @@ -114,6 +153,28 @@ var getter = __assign({}, op, { c: 7 }); getter.a = 12; // functions result in { } var spreadFunc = __assign({}, (function () { })); +function from16326(header, authToken) { + return __assign({}, this.header, header, authToken && { authToken: authToken }); +} +// boolean && T results in Partial +function conditionalSpreadBoolean(b) { + var o = { x: 12, y: 13 }; + o = __assign({}, o, b && { x: 14 }); + var o2 = __assign({}, b && { x: 21 }); + return o; +} +function conditionalSpreadNumber(nt) { + var o = { x: 15, y: 16 }; + o = __assign({}, o, nt && { x: nt }); + var o2 = __assign({}, nt && { x: nt }); + return o; +} +function conditionalSpreadString(st) { + var o = { x: 'hi', y: 17 }; + o = __assign({}, o, st && { x: st }); + var o2 = __assign({}, st && { x: st }); + return o; +} // any results in any var anything; var spreadAny = __assign({}, anything); @@ -135,20 +196,18 @@ var changeTypeAfter = __assign({}, o, { a: 'wrong type?' }); var changeTypeBefore = __assign({ a: 'wrong type?' }, o); var changeTypeBoth = __assign({}, o, swap); // optional -var definiteBoolean; -var definiteString; -var optionalString; -var optionalNumber; -var optionalUnionStops = __assign({}, definiteBoolean, definiteString, optionalNumber); -var optionalUnionDuplicates = __assign({}, definiteBoolean, definiteString, optionalString, optionalNumber); -var allOptional = __assign({}, optionalString, optionalNumber); -// computed property -var computedFirst = __assign((_a = {}, _a['before everything'] = 12, _a), o, { b: 'yes' }); -var computedMiddle = __assign({}, o, (_b = {}, _b['in the middle'] = 13, _b.b = 'maybe?', _b), o2); -var computedAfter = __assign({}, o, (_c = { b: 'yeah' }, _c['at the end'] = 14, _c)); +function container(definiteBoolean, definiteString, optionalString, optionalNumber) { + var optionalUnionStops = __assign({}, definiteBoolean, definiteString, optionalNumber); + var optionalUnionDuplicates = __assign({}, definiteBoolean, definiteString, optionalString, optionalNumber); + var allOptional = __assign({}, optionalString, optionalNumber); + // computed property + var computedFirst = __assign((_a = {}, _a['before everything'] = 12, _a), o, { b: 'yes' }); + var computedMiddle = __assign({}, o, (_b = {}, _b['in the middle'] = 13, _b.b = 'maybe?', _b), o2); + var computedAfter = __assign({}, o, (_c = { b: 'yeah' }, _c['at the end'] = 14, _c)); + var _a, _b, _c; +} // shortcut syntax var a = 12; var shortCutted = __assign({}, o, { a: a }); // non primitive var spreadNonPrimitive = __assign({}, {}); -var _a, _b, _c; diff --git a/tests/baselines/reference/objectSpread.symbols b/tests/baselines/reference/objectSpread.symbols index 1ec2520e166..0cb15d4ea7a 100644 --- a/tests/baselines/reference/objectSpread.symbols +++ b/tests/baselines/reference/objectSpread.symbols @@ -169,154 +169,280 @@ getter.a = 12; let spreadFunc = { ...(function () { }) }; >spreadFunc : Symbol(spreadFunc, Decl(objectSpread.ts, 37, 3)) +type Header = { head: string, body: string, authToken: string } +>Header : Symbol(Header, Decl(objectSpread.ts, 37, 42)) +>head : Symbol(head, Decl(objectSpread.ts, 39, 15)) +>body : Symbol(body, Decl(objectSpread.ts, 39, 29)) +>authToken : Symbol(authToken, Decl(objectSpread.ts, 39, 43)) + +function from16326(this: { header: Header }, header: Header, authToken: string): Header { +>from16326 : Symbol(from16326, Decl(objectSpread.ts, 39, 63)) +>this : Symbol(this, Decl(objectSpread.ts, 40, 19)) +>header : Symbol(header, Decl(objectSpread.ts, 40, 26)) +>Header : Symbol(Header, Decl(objectSpread.ts, 37, 42)) +>header : Symbol(header, Decl(objectSpread.ts, 40, 44)) +>Header : Symbol(Header, Decl(objectSpread.ts, 37, 42)) +>authToken : Symbol(authToken, Decl(objectSpread.ts, 40, 60)) +>Header : Symbol(Header, Decl(objectSpread.ts, 37, 42)) + + return { + ...this.header, +>this.header : Symbol(header, Decl(objectSpread.ts, 40, 26)) +>this : Symbol(this, Decl(objectSpread.ts, 40, 19)) +>header : Symbol(header, Decl(objectSpread.ts, 40, 26)) + + ...header, +>header : Symbol(header, Decl(objectSpread.ts, 40, 44)) + + ...authToken && { authToken } +>authToken : Symbol(authToken, Decl(objectSpread.ts, 40, 60)) +>authToken : Symbol(authToken, Decl(objectSpread.ts, 44, 25)) + } +} +// boolean && T results in Partial +function conditionalSpreadBoolean(b: boolean) : { x: number, y: number } { +>conditionalSpreadBoolean : Symbol(conditionalSpreadBoolean, Decl(objectSpread.ts, 46, 1)) +>b : Symbol(b, Decl(objectSpread.ts, 48, 34)) +>x : Symbol(x, Decl(objectSpread.ts, 48, 49)) +>y : Symbol(y, Decl(objectSpread.ts, 48, 60)) + + let o = { x: 12, y: 13 } +>o : Symbol(o, Decl(objectSpread.ts, 49, 7)) +>x : Symbol(x, Decl(objectSpread.ts, 49, 13)) +>y : Symbol(y, Decl(objectSpread.ts, 49, 20)) + + o = { +>o : Symbol(o, Decl(objectSpread.ts, 49, 7)) + + ...o, +>o : Symbol(o, Decl(objectSpread.ts, 49, 7)) + + ...b && { x: 14 } +>b : Symbol(b, Decl(objectSpread.ts, 48, 34)) +>x : Symbol(x, Decl(objectSpread.ts, 52, 17)) + } + let o2 = { ...b && { x: 21 }} +>o2 : Symbol(o2, Decl(objectSpread.ts, 54, 7)) +>b : Symbol(b, Decl(objectSpread.ts, 48, 34)) +>x : Symbol(x, Decl(objectSpread.ts, 54, 24)) + + return o; +>o : Symbol(o, Decl(objectSpread.ts, 49, 7)) +} +function conditionalSpreadNumber(nt: number): { x: number, y: number } { +>conditionalSpreadNumber : Symbol(conditionalSpreadNumber, Decl(objectSpread.ts, 56, 1)) +>nt : Symbol(nt, Decl(objectSpread.ts, 57, 33)) +>x : Symbol(x, Decl(objectSpread.ts, 57, 47)) +>y : Symbol(y, Decl(objectSpread.ts, 57, 58)) + + let o = { x: 15, y: 16 } +>o : Symbol(o, Decl(objectSpread.ts, 58, 7)) +>x : Symbol(x, Decl(objectSpread.ts, 58, 13)) +>y : Symbol(y, Decl(objectSpread.ts, 58, 20)) + + o = { +>o : Symbol(o, Decl(objectSpread.ts, 58, 7)) + + ...o, +>o : Symbol(o, Decl(objectSpread.ts, 58, 7)) + + ...nt && { x: nt } +>nt : Symbol(nt, Decl(objectSpread.ts, 57, 33)) +>x : Symbol(x, Decl(objectSpread.ts, 61, 18)) +>nt : Symbol(nt, Decl(objectSpread.ts, 57, 33)) + } + let o2 = { ...nt && { x: nt }} +>o2 : Symbol(o2, Decl(objectSpread.ts, 63, 7)) +>nt : Symbol(nt, Decl(objectSpread.ts, 57, 33)) +>x : Symbol(x, Decl(objectSpread.ts, 63, 25)) +>nt : Symbol(nt, Decl(objectSpread.ts, 57, 33)) + + return o; +>o : Symbol(o, Decl(objectSpread.ts, 58, 7)) +} +function conditionalSpreadString(st: string): { x: string, y: number } { +>conditionalSpreadString : Symbol(conditionalSpreadString, Decl(objectSpread.ts, 65, 1)) +>st : Symbol(st, Decl(objectSpread.ts, 66, 33)) +>x : Symbol(x, Decl(objectSpread.ts, 66, 47)) +>y : Symbol(y, Decl(objectSpread.ts, 66, 58)) + + let o = { x: 'hi', y: 17 } +>o : Symbol(o, Decl(objectSpread.ts, 67, 7)) +>x : Symbol(x, Decl(objectSpread.ts, 67, 13)) +>y : Symbol(y, Decl(objectSpread.ts, 67, 22)) + + o = { +>o : Symbol(o, Decl(objectSpread.ts, 67, 7)) + + ...o, +>o : Symbol(o, Decl(objectSpread.ts, 67, 7)) + + ...st && { x: st } +>st : Symbol(st, Decl(objectSpread.ts, 66, 33)) +>x : Symbol(x, Decl(objectSpread.ts, 70, 18)) +>st : Symbol(st, Decl(objectSpread.ts, 66, 33)) + } + let o2 = { ...st && { x: st }} +>o2 : Symbol(o2, Decl(objectSpread.ts, 72, 7)) +>st : Symbol(st, Decl(objectSpread.ts, 66, 33)) +>x : Symbol(x, Decl(objectSpread.ts, 72, 25)) +>st : Symbol(st, Decl(objectSpread.ts, 66, 33)) + + return o; +>o : Symbol(o, Decl(objectSpread.ts, 67, 7)) +} + // any results in any let anything: any; ->anything : Symbol(anything, Decl(objectSpread.ts, 40, 3)) +>anything : Symbol(anything, Decl(objectSpread.ts, 77, 3)) let spreadAny = { ...anything }; ->spreadAny : Symbol(spreadAny, Decl(objectSpread.ts, 41, 3)) ->anything : Symbol(anything, Decl(objectSpread.ts, 40, 3)) +>spreadAny : Symbol(spreadAny, Decl(objectSpread.ts, 78, 3)) +>anything : Symbol(anything, Decl(objectSpread.ts, 77, 3)) // methods are not enumerable class C { p = 1; m() { } } ->C : Symbol(C, Decl(objectSpread.ts, 41, 32)) ->p : Symbol(C.p, Decl(objectSpread.ts, 44, 9)) ->m : Symbol(C.m, Decl(objectSpread.ts, 44, 16)) +>C : Symbol(C, Decl(objectSpread.ts, 78, 32)) +>p : Symbol(C.p, Decl(objectSpread.ts, 81, 9)) +>m : Symbol(C.m, Decl(objectSpread.ts, 81, 16)) let c: C = new C() ->c : Symbol(c, Decl(objectSpread.ts, 45, 3)) ->C : Symbol(C, Decl(objectSpread.ts, 41, 32)) ->C : Symbol(C, Decl(objectSpread.ts, 41, 32)) +>c : Symbol(c, Decl(objectSpread.ts, 82, 3)) +>C : Symbol(C, Decl(objectSpread.ts, 78, 32)) +>C : Symbol(C, Decl(objectSpread.ts, 78, 32)) let spreadC: { p: number } = { ...c } ->spreadC : Symbol(spreadC, Decl(objectSpread.ts, 46, 3)) ->p : Symbol(p, Decl(objectSpread.ts, 46, 14)) ->c : Symbol(c, Decl(objectSpread.ts, 45, 3)) +>spreadC : Symbol(spreadC, Decl(objectSpread.ts, 83, 3)) +>p : Symbol(p, Decl(objectSpread.ts, 83, 14)) +>c : Symbol(c, Decl(objectSpread.ts, 82, 3)) // own methods are enumerable let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } }; ->cplus : Symbol(cplus, Decl(objectSpread.ts, 49, 3)) ->p : Symbol(p, Decl(objectSpread.ts, 49, 12)) ->plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) ->c : Symbol(c, Decl(objectSpread.ts, 45, 3)) ->plus : Symbol(plus, Decl(objectSpread.ts, 49, 48)) +>cplus : Symbol(cplus, Decl(objectSpread.ts, 86, 3)) +>p : Symbol(p, Decl(objectSpread.ts, 86, 12)) +>plus : Symbol(plus, Decl(objectSpread.ts, 86, 23)) +>c : Symbol(c, Decl(objectSpread.ts, 82, 3)) +>plus : Symbol(plus, Decl(objectSpread.ts, 86, 48)) cplus.plus(); ->cplus.plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) ->cplus : Symbol(cplus, Decl(objectSpread.ts, 49, 3)) ->plus : Symbol(plus, Decl(objectSpread.ts, 49, 23)) +>cplus.plus : Symbol(plus, Decl(objectSpread.ts, 86, 23)) +>cplus : Symbol(cplus, Decl(objectSpread.ts, 86, 3)) +>plus : Symbol(plus, Decl(objectSpread.ts, 86, 23)) // new field's type conflicting with existing field is OK let changeTypeAfter: { a: string, b: string } = ->changeTypeAfter : Symbol(changeTypeAfter, Decl(objectSpread.ts, 53, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 53, 22)) ->b : Symbol(b, Decl(objectSpread.ts, 53, 33)) +>changeTypeAfter : Symbol(changeTypeAfter, Decl(objectSpread.ts, 90, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 90, 22)) +>b : Symbol(b, Decl(objectSpread.ts, 90, 33)) { ...o, a: 'wrong type?' } >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 54, 11)) +>a : Symbol(a, Decl(objectSpread.ts, 91, 11)) let changeTypeBefore: { a: number, b: string } = ->changeTypeBefore : Symbol(changeTypeBefore, Decl(objectSpread.ts, 55, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 55, 23)) ->b : Symbol(b, Decl(objectSpread.ts, 55, 34)) +>changeTypeBefore : Symbol(changeTypeBefore, Decl(objectSpread.ts, 92, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 92, 23)) +>b : Symbol(b, Decl(objectSpread.ts, 92, 34)) { a: 'wrong type?', ...o }; ->a : Symbol(a, Decl(objectSpread.ts, 56, 5)) +>a : Symbol(a, Decl(objectSpread.ts, 93, 5)) >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) let changeTypeBoth: { a: string, b: number } = ->changeTypeBoth : Symbol(changeTypeBoth, Decl(objectSpread.ts, 57, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 57, 21)) ->b : Symbol(b, Decl(objectSpread.ts, 57, 32)) +>changeTypeBoth : Symbol(changeTypeBoth, Decl(objectSpread.ts, 94, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 94, 21)) +>b : Symbol(b, Decl(objectSpread.ts, 94, 32)) { ...o, ...swap }; >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) >swap : Symbol(swap, Decl(objectSpread.ts, 2, 3)) // optional -let definiteBoolean: { sn: boolean }; ->definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 61, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 61, 22)) +function container( +>container : Symbol(container, Decl(objectSpread.ts, 95, 22)) -let definiteString: { sn: string }; ->definiteString : Symbol(definiteString, Decl(objectSpread.ts, 62, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 62, 21)) + definiteBoolean: { sn: boolean }, +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 98, 19)) +>sn : Symbol(sn, Decl(objectSpread.ts, 99, 22)) -let optionalString: { sn?: string }; ->optionalString : Symbol(optionalString, Decl(objectSpread.ts, 63, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 63, 21)) + definiteString: { sn: string }, +>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 99, 37)) +>sn : Symbol(sn, Decl(objectSpread.ts, 100, 21)) -let optionalNumber: { sn?: number }; ->optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 64, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 64, 21)) + optionalString: { sn?: string }, +>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 100, 35)) +>sn : Symbol(sn, Decl(objectSpread.ts, 101, 21)) -let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; ->optionalUnionStops : Symbol(optionalUnionStops, Decl(objectSpread.ts, 65, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 65, 25)) ->definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 61, 3)) ->definiteString : Symbol(definiteString, Decl(objectSpread.ts, 62, 3)) ->optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 64, 3)) + optionalNumber: { sn?: number }) { +>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 101, 36)) +>sn : Symbol(sn, Decl(objectSpread.ts, 102, 21)) -let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; ->optionalUnionDuplicates : Symbol(optionalUnionDuplicates, Decl(objectSpread.ts, 66, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 66, 30)) ->definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 61, 3)) ->definiteString : Symbol(definiteString, Decl(objectSpread.ts, 62, 3)) ->optionalString : Symbol(optionalString, Decl(objectSpread.ts, 63, 3)) ->optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 64, 3)) + let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; +>optionalUnionStops : Symbol(optionalUnionStops, Decl(objectSpread.ts, 103, 7)) +>sn : Symbol(sn, Decl(objectSpread.ts, 103, 29)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 98, 19)) +>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 99, 37)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 101, 36)) -let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; ->allOptional : Symbol(allOptional, Decl(objectSpread.ts, 67, 3)) ->sn : Symbol(sn, Decl(objectSpread.ts, 67, 18)) ->optionalString : Symbol(optionalString, Decl(objectSpread.ts, 63, 3)) ->optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 64, 3)) + let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; +>optionalUnionDuplicates : Symbol(optionalUnionDuplicates, Decl(objectSpread.ts, 104, 7)) +>sn : Symbol(sn, Decl(objectSpread.ts, 104, 34)) +>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 98, 19)) +>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 99, 37)) +>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 100, 35)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 101, 36)) -// computed property -let computedFirst: { a: number, b: string, "before everything": number } = ->computedFirst : Symbol(computedFirst, Decl(objectSpread.ts, 70, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 70, 20)) ->b : Symbol(b, Decl(objectSpread.ts, 70, 31)) + let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; +>allOptional : Symbol(allOptional, Decl(objectSpread.ts, 105, 7)) +>sn : Symbol(sn, Decl(objectSpread.ts, 105, 22)) +>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 100, 35)) +>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 101, 36)) - { ['before everything']: 12, ...o, b: 'yes' } ->'before everything' : Symbol(['before everything'], Decl(objectSpread.ts, 71, 5)) + // computed property + let computedFirst: { a: number, b: string, "before everything": number } = +>computedFirst : Symbol(computedFirst, Decl(objectSpread.ts, 108, 7)) +>a : Symbol(a, Decl(objectSpread.ts, 108, 24)) +>b : Symbol(b, Decl(objectSpread.ts, 108, 35)) + + { ['before everything']: 12, ...o, b: 'yes' } +>'before everything' : Symbol(['before everything'], Decl(objectSpread.ts, 109, 9)) >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) ->b : Symbol(b, Decl(objectSpread.ts, 71, 38)) +>b : Symbol(b, Decl(objectSpread.ts, 109, 42)) -let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = ->computedMiddle : Symbol(computedMiddle, Decl(objectSpread.ts, 72, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 72, 21)) ->b : Symbol(b, Decl(objectSpread.ts, 72, 32)) ->c : Symbol(c, Decl(objectSpread.ts, 72, 43)) + let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = +>computedMiddle : Symbol(computedMiddle, Decl(objectSpread.ts, 110, 7)) +>a : Symbol(a, Decl(objectSpread.ts, 110, 25)) +>b : Symbol(b, Decl(objectSpread.ts, 110, 36)) +>c : Symbol(c, Decl(objectSpread.ts, 110, 47)) - { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } + { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) ->'in the middle' : Symbol(['in the middle'], Decl(objectSpread.ts, 73, 11)) ->b : Symbol(b, Decl(objectSpread.ts, 73, 34)) +>'in the middle' : Symbol(['in the middle'], Decl(objectSpread.ts, 111, 15)) +>b : Symbol(b, Decl(objectSpread.ts, 111, 38)) >o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3)) -let computedAfter: { a: number, b: string, "at the end": number } = ->computedAfter : Symbol(computedAfter, Decl(objectSpread.ts, 74, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 74, 20)) ->b : Symbol(b, Decl(objectSpread.ts, 74, 31)) + let computedAfter: { a: number, b: string, "at the end": number } = +>computedAfter : Symbol(computedAfter, Decl(objectSpread.ts, 112, 7)) +>a : Symbol(a, Decl(objectSpread.ts, 112, 24)) +>b : Symbol(b, Decl(objectSpread.ts, 112, 35)) - { ...o, b: 'yeah', ['at the end']: 14 } + { ...o, b: 'yeah', ['at the end']: 14 } >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) ->b : Symbol(b, Decl(objectSpread.ts, 75, 11)) ->'at the end' : Symbol(['at the end'], Decl(objectSpread.ts, 75, 22)) - +>b : Symbol(b, Decl(objectSpread.ts, 113, 15)) +>'at the end' : Symbol(['at the end'], Decl(objectSpread.ts, 113, 26)) +} // shortcut syntax let a = 12; ->a : Symbol(a, Decl(objectSpread.ts, 77, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 116, 3)) let shortCutted: { a: number, b: string } = { ...o, a } ->shortCutted : Symbol(shortCutted, Decl(objectSpread.ts, 78, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 78, 18)) ->b : Symbol(b, Decl(objectSpread.ts, 78, 29)) +>shortCutted : Symbol(shortCutted, Decl(objectSpread.ts, 117, 3)) +>a : Symbol(a, Decl(objectSpread.ts, 117, 18)) +>b : Symbol(b, Decl(objectSpread.ts, 117, 29)) >o : Symbol(o, Decl(objectSpread.ts, 0, 3)) ->a : Symbol(a, Decl(objectSpread.ts, 78, 51)) +>a : Symbol(a, Decl(objectSpread.ts, 117, 51)) // non primitive let spreadNonPrimitive = { ...{}}; ->spreadNonPrimitive : Symbol(spreadNonPrimitive, Decl(objectSpread.ts, 80, 3)) +>spreadNonPrimitive : Symbol(spreadNonPrimitive, Decl(objectSpread.ts, 119, 3)) diff --git a/tests/baselines/reference/objectSpread.types b/tests/baselines/reference/objectSpread.types index 7bac35119ed..0caef49f439 100644 --- a/tests/baselines/reference/objectSpread.types +++ b/tests/baselines/reference/objectSpread.types @@ -230,6 +230,165 @@ let spreadFunc = { ...(function () { }) }; >(function () { }) : () => void >function () { } : () => void +type Header = { head: string, body: string, authToken: string } +>Header : Header +>head : string +>body : string +>authToken : string + +function from16326(this: { header: Header }, header: Header, authToken: string): Header { +>from16326 : (this: { header: Header; }, header: Header, authToken: string) => Header +>this : { header: Header; } +>header : Header +>Header : Header +>header : Header +>Header : Header +>authToken : string +>Header : Header + + return { +>{ ...this.header, ...header, ...authToken && { authToken } } : { head: string; body: string; authToken: string; } | { authToken: string; head: string; body: string; } + + ...this.header, +>this.header : Header +>this : { header: Header; } +>header : Header + + ...header, +>header : Header + + ...authToken && { authToken } +>authToken && { authToken } : "" | { authToken: string; } +>authToken : string +>{ authToken } : { authToken: string; } +>authToken : string + } +} +// boolean && T results in Partial +function conditionalSpreadBoolean(b: boolean) : { x: number, y: number } { +>conditionalSpreadBoolean : (b: boolean) => { x: number; y: number; } +>b : boolean +>x : number +>y : number + + let o = { x: 12, y: 13 } +>o : { x: number; y: number; } +>{ x: 12, y: 13 } : { x: number; y: number; } +>x : number +>12 : 12 +>y : number +>13 : 13 + + o = { +>o = { ...o, ...b && { x: 14 } } : { x: number; y: number; } | { x: number; y: number; } +>o : { x: number; y: number; } +>{ ...o, ...b && { x: 14 } } : { x: number; y: number; } | { x: number; y: number; } + + ...o, +>o : { x: number; y: number; } + + ...b && { x: 14 } +>b && { x: 14 } : false | { x: number; } +>b : boolean +>{ x: 14 } : { x: number; } +>x : number +>14 : 14 + } + let o2 = { ...b && { x: 21 }} +>o2 : {} | { x: number; } +>{ ...b && { x: 21 }} : {} | { x: number; } +>b && { x: 21 } : false | { x: number; } +>b : boolean +>{ x: 21 } : { x: number; } +>x : number +>21 : 21 + + return o; +>o : { x: number; y: number; } +} +function conditionalSpreadNumber(nt: number): { x: number, y: number } { +>conditionalSpreadNumber : (nt: number) => { x: number; y: number; } +>nt : number +>x : number +>y : number + + let o = { x: 15, y: 16 } +>o : { x: number; y: number; } +>{ x: 15, y: 16 } : { x: number; y: number; } +>x : number +>15 : 15 +>y : number +>16 : 16 + + o = { +>o = { ...o, ...nt && { x: nt } } : { x: number; y: number; } | { x: number; y: number; } +>o : { x: number; y: number; } +>{ ...o, ...nt && { x: nt } } : { x: number; y: number; } | { x: number; y: number; } + + ...o, +>o : { x: number; y: number; } + + ...nt && { x: nt } +>nt && { x: nt } : 0 | { x: number; } +>nt : number +>{ x: nt } : { x: number; } +>x : number +>nt : number + } + let o2 = { ...nt && { x: nt }} +>o2 : {} | { x: number; } +>{ ...nt && { x: nt }} : {} | { x: number; } +>nt && { x: nt } : 0 | { x: number; } +>nt : number +>{ x: nt } : { x: number; } +>x : number +>nt : number + + return o; +>o : { x: number; y: number; } +} +function conditionalSpreadString(st: string): { x: string, y: number } { +>conditionalSpreadString : (st: string) => { x: string; y: number; } +>st : string +>x : string +>y : number + + let o = { x: 'hi', y: 17 } +>o : { x: string; y: number; } +>{ x: 'hi', y: 17 } : { x: string; y: number; } +>x : string +>'hi' : "hi" +>y : number +>17 : 17 + + o = { +>o = { ...o, ...st && { x: st } } : { x: string; y: number; } | { x: string; y: number; } +>o : { x: string; y: number; } +>{ ...o, ...st && { x: st } } : { x: string; y: number; } | { x: string; y: number; } + + ...o, +>o : { x: string; y: number; } + + ...st && { x: st } +>st && { x: st } : "" | { x: string; } +>st : string +>{ x: st } : { x: string; } +>x : string +>st : string + } + let o2 = { ...st && { x: st }} +>o2 : {} | { x: string; } +>{ ...st && { x: st }} : {} | { x: string; } +>st && { x: st } : "" | { x: string; } +>st : string +>{ x: st } : { x: string; } +>x : string +>st : string + + return o; +>o : { x: string; y: number; } +} + // any results in any let anything: any; >anything : any @@ -312,53 +471,56 @@ let changeTypeBoth: { a: string, b: number } = >swap : { a: string; b: number; } // optional -let definiteBoolean: { sn: boolean }; +function container( +>container : (definiteBoolean: { sn: boolean; }, definiteString: { sn: string; }, optionalString: { sn?: string | undefined; }, optionalNumber: { sn?: number | undefined; }) => void + + definiteBoolean: { sn: boolean }, >definiteBoolean : { sn: boolean; } >sn : boolean -let definiteString: { sn: string }; + definiteString: { sn: string }, >definiteString : { sn: string; } >sn : string -let optionalString: { sn?: string }; ->optionalString : { sn?: string; } ->sn : string + optionalString: { sn?: string }, +>optionalString : { sn?: string | undefined; } +>sn : string | undefined -let optionalNumber: { sn?: number }; ->optionalNumber : { sn?: number; } ->sn : number + optionalNumber: { sn?: number }) { +>optionalNumber : { sn?: number | undefined; } +>sn : number | undefined -let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; + let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; >optionalUnionStops : { sn: string | number | boolean; } >sn : string | number | boolean >{ ...definiteBoolean, ...definiteString, ...optionalNumber } : { sn: string | number; } >definiteBoolean : { sn: boolean; } >definiteString : { sn: string; } ->optionalNumber : { sn?: number; } +>optionalNumber : { sn?: number | undefined; } -let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; + let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; >optionalUnionDuplicates : { sn: string | number; } >sn : string | number >{ ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber } : { sn: string | number; } >definiteBoolean : { sn: boolean; } >definiteString : { sn: string; } ->optionalString : { sn?: string; } ->optionalNumber : { sn?: number; } +>optionalString : { sn?: string | undefined; } +>optionalNumber : { sn?: number | undefined; } -let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; ->allOptional : { sn?: string | number; } ->sn : string | number ->{ ...optionalString, ...optionalNumber } : { sn?: string | number; } ->optionalString : { sn?: string; } ->optionalNumber : { sn?: number; } + let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; +>allOptional : { sn?: string | number | undefined; } +>sn : string | number | undefined +>{ ...optionalString, ...optionalNumber } : { sn?: string | number | undefined; } +>optionalString : { sn?: string | undefined; } +>optionalNumber : { sn?: number | undefined; } -// computed property -let computedFirst: { a: number, b: string, "before everything": number } = + // computed property + let computedFirst: { a: number, b: string, "before everything": number } = >computedFirst : { a: number; b: string; "before everything": number; } >a : number >b : string - { ['before everything']: 12, ...o, b: 'yes' } + { ['before everything']: 12, ...o, b: 'yes' } >{ ['before everything']: 12, ...o, b: 'yes' } : { b: string; a: number; ['before everything']: number; } >'before everything' : "before everything" >12 : 12 @@ -366,13 +528,13 @@ let computedFirst: { a: number, b: string, "before everything": number } = >b : string >'yes' : "yes" -let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = + let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = >computedMiddle : { a: number; b: string; c: boolean; "in the middle": number; } >a : number >b : string >c : boolean - { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } + { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } >{ ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } : { b: string; c: boolean; ['in the middle']: number; a: number; } >o : { a: number; b: string; } >'in the middle' : "in the middle" @@ -381,19 +543,19 @@ let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number >'maybe?' : "maybe?" >o2 : { b: string; c: boolean; } -let computedAfter: { a: number, b: string, "at the end": number } = + let computedAfter: { a: number, b: string, "at the end": number } = >computedAfter : { a: number; b: string; "at the end": number; } >a : number >b : string - { ...o, b: 'yeah', ['at the end']: 14 } + { ...o, b: 'yeah', ['at the end']: 14 } >{ ...o, b: 'yeah', ['at the end']: 14 } : { b: string; ['at the end']: number; a: number; } >o : { a: number; b: string; } >b : string >'yeah' : "yeah" >'at the end' : "at the end" >14 : 14 - +} // shortcut syntax let a = 12; >a : number @@ -409,8 +571,8 @@ let shortCutted: { a: number, b: string } = { ...o, a } // non primitive let spreadNonPrimitive = { ...{}}; ->spreadNonPrimitive : {} ->{ ...{}} : {} +>spreadNonPrimitive : object +>{ ...{}} : object >{} : object >{} : {} diff --git a/tests/baselines/reference/objectSpreadNegative.errors.txt b/tests/baselines/reference/objectSpreadNegative.errors.txt index a9381a0dcb1..5b78f10f281 100644 --- a/tests/baselines/reference/objectSpreadNegative.errors.txt +++ b/tests/baselines/reference/objectSpreadNegative.errors.txt @@ -9,23 +9,24 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,36): error TS230 tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,53): error TS2300: Duplicate identifier 'b'. tests/cases/conformance/types/spread/objectSpreadNegative.ts(32,19): error TS2698: Spread types may only be created from object types. tests/cases/conformance/types/spread/objectSpreadNegative.ts(33,19): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(35,20): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(37,19): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(46,12): error TS2339: Property 'b' does not exist on type '{}'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(52,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(57,11): error TS2339: Property 'a' does not exist on type '{}'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(61,14): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(64,14): error TS2698: Spread types may only be created from object types. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(78,37): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(34,20): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(36,20): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(38,19): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(43,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(47,12): error TS2339: Property 'b' does not exist on type '{}'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(53,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(58,11): error TS2339: Property 'a' does not exist on type 'object'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(62,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(65,14): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(79,37): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. Object literal may only specify known properties, and 'extra' does not exist in type 'A'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(81,7): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(82,7): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. Object literal may only specify known properties, and 'extra' does not exist in type 'A'. -tests/cases/conformance/types/spread/objectSpreadNegative.ts(83,7): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. +tests/cases/conformance/types/spread/objectSpreadNegative.ts(84,7): error TS2322: Type '{ a: string; b: string; extra: string; }' is not assignable to type 'A'. Object literal may only specify known properties, and 'extra' does not exist in type 'A'. -==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (19 errors) ==== +==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (20 errors) ==== let o = { a: 1, b: 'no' } /// private propagates @@ -71,18 +72,21 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(83,7): error TS2322 !!! error TS2300: Duplicate identifier 'b'. let duplicatedSpread = { ...o, ...o } - // primitives are not allowed + // primitives are not allowed, except for falsy ones let spreadNum = { ...12 }; ~~~~~ !!! error TS2698: Spread types may only be created from object types. let spreadSum = { ...1 + 1 }; ~~~~~~~~ !!! error TS2698: Spread types may only be created from object types. - spreadSum.toFixed(); // error, no methods from number - let spreadBool = { ...false }; - ~~~~~~~~ + let spreadZero = { ...0 }; + ~~~~ !!! error TS2698: Spread types may only be created from object types. - spreadBool.valueOf(); // error, what were you thinking? + spreadZero.toFixed(); // error, no methods even from a falsy number + let spreadBool = { ...true }; + ~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + spreadBool.valueOf(); let spreadStr = { ...'foo' }; ~~~~~~~~ !!! error TS2698: Spread types may only be created from object types. @@ -113,7 +117,7 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(83,7): error TS2322 let spreadObj = { ...obj }; spreadObj.a; // error 'a' is not in {} ~ -!!! error TS2339: Property 'a' does not exist on type '{}'. +!!! error TS2339: Property 'a' does not exist on type 'object'. // generics function f(t: T, u: U) { diff --git a/tests/baselines/reference/objectSpreadNegative.js b/tests/baselines/reference/objectSpreadNegative.js index aab8ffc4e91..7e6720b9b16 100644 --- a/tests/baselines/reference/objectSpreadNegative.js +++ b/tests/baselines/reference/objectSpreadNegative.js @@ -29,12 +29,13 @@ spread = b; // error, missing 's' let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' } let duplicatedSpread = { ...o, ...o } -// primitives are not allowed +// primitives are not allowed, except for falsy ones let spreadNum = { ...12 }; let spreadSum = { ...1 + 1 }; -spreadSum.toFixed(); // error, no methods from number -let spreadBool = { ...false }; -spreadBool.valueOf(); // error, what were you thinking? +let spreadZero = { ...0 }; +spreadZero.toFixed(); // error, no methods even from a falsy number +let spreadBool = { ...true }; +spreadBool.valueOf(); let spreadStr = { ...'foo' }; spreadStr.length; // error, no 'length' spreadStr.charAt(1); // error, no methods either @@ -121,12 +122,13 @@ spread = b; // error, missing 's' // literal repeats are not allowed, but spread repeats are fine var duplicated = __assign({ b: 'bad' }, o, { b: 'bad' }, o2, { b: 'bad' }); var duplicatedSpread = __assign({}, o, o); -// primitives are not allowed +// primitives are not allowed, except for falsy ones var spreadNum = __assign({}, 12); var spreadSum = __assign({}, 1 + 1); -spreadSum.toFixed(); // error, no methods from number -var spreadBool = __assign({}, false); -spreadBool.valueOf(); // error, what were you thinking? +var spreadZero = __assign({}, 0); +spreadZero.toFixed(); // error, no methods even from a falsy number +var spreadBool = __assign({}, true); +spreadBool.valueOf(); var spreadStr = __assign({}, 'foo'); spreadStr.length; // error, no 'length' spreadStr.charAt(1); // error, no methods either diff --git a/tests/baselines/reference/restInvalidArgumentType.errors.txt b/tests/baselines/reference/restInvalidArgumentType.errors.txt index fff2c7b3563..0cc4faea557 100644 --- a/tests/baselines/reference/restInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/restInvalidArgumentType.errors.txt @@ -1,20 +1,22 @@ +tests/cases/compiler/restInvalidArgumentType.ts(27,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(29,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(30,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(31,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(33,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(35,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(36,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(38,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(41,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(37,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(39,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(40,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(42,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(44,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(43,13): error TS2700: Rest types may only be created from object types. tests/cases/compiler/restInvalidArgumentType.ts(45,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(47,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(48,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(55,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(56,13): error TS2700: Rest types may only be created from object types. -tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(46,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(50,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(51,13): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restInvalidArgumentType.ts(53,13): error TS2700: Rest types may only be created from object types. -==== tests/cases/compiler/restInvalidArgumentType.ts (14 errors) ==== +==== tests/cases/compiler/restInvalidArgumentType.ts (16 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -28,23 +30,19 @@ tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types var union_generic: T | { a: number }; var union_primitive: { a: number } | number; - var intersection_generic: T & { a: number }; - var intersection_premitive: { a: number } | string; - + var intersection_primitive: { a: number } & string; var num: number; - var str: number; + var str: string; + var literal_string: "string"; + var literal_number: 42; + var e: E; var u: undefined; var n: null; var a: any; - var literal_string: "string"; - var literal_number: 42; - - var e: E; - var {...r1} = p1; // Error, generic type paramterre ~~ !!! error TS2700: Rest types may only be created from object types. @@ -52,7 +50,6 @@ tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types var {...r3} = t; // Error, generic type paramter ~~ !!! error TS2700: Rest types may only be created from object types. - var {...r4} = i; // Error, index access ~~ !!! error TS2700: Rest types may only be created from object types. @@ -75,7 +72,7 @@ tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types var {...r10} = intersection_generic; // Error, intersection with generic type parameter ~~~ !!! error TS2700: Rest types may only be created from object types. - var {...r11} = intersection_premitive; // Error, intersection with generic type parameter + var {...r11} = intersection_primitive; // Error, intersection with generic type parameter ~~~ !!! error TS2700: Rest types may only be created from object types. @@ -86,8 +83,12 @@ tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types ~~~ !!! error TS2700: Rest types may only be created from object types. - var {...r14} = u; // OK - var {...r15} = n; // OK + var {...r14} = u; // error, undefined-only not allowed + ~~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r15} = n; // error, null-only not allowed + ~~~ +!!! error TS2700: Rest types may only be created from object types. var {...r16} = a; // OK @@ -101,4 +102,5 @@ tests/cases/compiler/restInvalidArgumentType.ts(58,13): error TS2700: Rest types var {...r19} = e; // Error, enum ~~~ !!! error TS2700: Rest types may only be created from object types. - } \ No newline at end of file + } + \ No newline at end of file diff --git a/tests/baselines/reference/restInvalidArgumentType.js b/tests/baselines/reference/restInvalidArgumentType.js index 48e4e11e805..75b52a8c6e8 100644 --- a/tests/baselines/reference/restInvalidArgumentType.js +++ b/tests/baselines/reference/restInvalidArgumentType.js @@ -12,27 +12,22 @@ function f(p1: T, p2: T[]) { var union_generic: T | { a: number }; var union_primitive: { a: number } | number; - var intersection_generic: T & { a: number }; - var intersection_premitive: { a: number } | string; - + var intersection_primitive: { a: number } & string; var num: number; - var str: number; + var str: string; + var literal_string: "string"; + var literal_number: 42; + var e: E; var u: undefined; var n: null; var a: any; - var literal_string: "string"; - var literal_number: 42; - - var e: E; - var {...r1} = p1; // Error, generic type paramterre var {...r2} = p2; // OK var {...r3} = t; // Error, generic type paramter - var {...r4} = i; // Error, index access var {...r5} = k; // Error, index @@ -43,13 +38,13 @@ function f(p1: T, p2: T[]) { var {...r9} = union_primitive; // Error, union with generic type parameter var {...r10} = intersection_generic; // Error, intersection with generic type parameter - var {...r11} = intersection_premitive; // Error, intersection with generic type parameter + var {...r11} = intersection_primitive; // Error, intersection with generic type parameter var {...r12} = num; // Error var {...r13} = str; // Error - var {...r14} = u; // OK - var {...r15} = n; // OK + var {...r14} = u; // error, undefined-only not allowed + var {...r15} = n; // error, null-only not allowed var {...r16} = a; // OK @@ -57,7 +52,8 @@ function f(p1: T, p2: T[]) { var {...r18} = literal_number; // Error var {...r19} = e; // Error, enum -} +} + //// [restInvalidArgumentType.js] var __rest = (this && this.__rest) || function (s, e) { @@ -84,15 +80,15 @@ function f(p1, p2) { var union_generic; var union_primitive; var intersection_generic; - var intersection_premitive; + var intersection_primitive; var num; var str; - var u; - var n; - var a; var literal_string; var literal_number; var e; + var u; + var n; + var a; var r1 = __rest(p1, []); // Error, generic type paramterre var r2 = __rest(p2, []); // OK var r3 = __rest(t, []); // Error, generic type paramter @@ -103,11 +99,11 @@ function f(p1, p2) { var r8 = __rest(union_generic, []); // Error, union with generic type parameter var r9 = __rest(union_primitive, []); // Error, union with generic type parameter var r10 = __rest(intersection_generic, []); // Error, intersection with generic type parameter - var r11 = __rest(intersection_premitive, []); // Error, intersection with generic type parameter + var r11 = __rest(intersection_primitive, []); // Error, intersection with generic type parameter var r12 = __rest(num, []); // Error var r13 = __rest(str, []); // Error - var r14 = __rest(u, []); // OK - var r15 = __rest(n, []); // OK + var r14 = __rest(u, []); // error, undefined-only not allowed + var r15 = __rest(n, []); // error, null-only not allowed var r16 = __rest(a, []); // OK var r17 = __rest(literal_string, []); // Error var r18 = __rest(literal_number, []); // Error diff --git a/tests/baselines/reference/restUnion2.js b/tests/baselines/reference/restUnion2.js index 382b7bb2bc9..437ea780193 100644 --- a/tests/baselines/reference/restUnion2.js +++ b/tests/baselines/reference/restUnion2.js @@ -7,15 +7,7 @@ var {...rest2 } = undefinedUnion; declare const nullUnion: { n: number } | null; var rest3: { n: number }; var {...rest3 } = nullUnion; - - -declare const nullAndUndefinedUnion: null | undefined; -var rest4: { }; -var {...rest4 } = nullAndUndefinedUnion; - -declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; -var rest5: { n: number, s: string }; -var {...rest5 } = unionWithIntersection; + //// [restUnion2.js] var __rest = (this && this.__rest) || function (s, e) { @@ -31,7 +23,3 @@ var rest2; var rest2 = __rest(undefinedUnion, []); var rest3; var rest3 = __rest(nullUnion, []); -var rest4; -var rest4 = __rest(nullAndUndefinedUnion, []); -var rest5; -var rest5 = __rest(unionWithIntersection, []); diff --git a/tests/baselines/reference/restUnion2.symbols b/tests/baselines/reference/restUnion2.symbols index 2728285f5ef..c6c34511b17 100644 --- a/tests/baselines/reference/restUnion2.symbols +++ b/tests/baselines/reference/restUnion2.symbols @@ -24,28 +24,3 @@ var {...rest3 } = nullUnion; >rest3 : Symbol(rest3, Decl(restUnion2.ts, 6, 3), Decl(restUnion2.ts, 7, 5)) >nullUnion : Symbol(nullUnion, Decl(restUnion2.ts, 5, 13)) - -declare const nullAndUndefinedUnion: null | undefined; ->nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(restUnion2.ts, 10, 13)) - -var rest4: { }; ->rest4 : Symbol(rest4, Decl(restUnion2.ts, 11, 3), Decl(restUnion2.ts, 12, 5)) - -var {...rest4 } = nullAndUndefinedUnion; ->rest4 : Symbol(rest4, Decl(restUnion2.ts, 11, 3), Decl(restUnion2.ts, 12, 5)) ->nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(restUnion2.ts, 10, 13)) - -declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; ->unionWithIntersection : Symbol(unionWithIntersection, Decl(restUnion2.ts, 14, 13)) ->n : Symbol(n, Decl(restUnion2.ts, 14, 39)) ->s : Symbol(s, Decl(restUnion2.ts, 14, 55)) - -var rest5: { n: number, s: string }; ->rest5 : Symbol(rest5, Decl(restUnion2.ts, 15, 3), Decl(restUnion2.ts, 16, 5)) ->n : Symbol(n, Decl(restUnion2.ts, 15, 12)) ->s : Symbol(s, Decl(restUnion2.ts, 15, 23)) - -var {...rest5 } = unionWithIntersection; ->rest5 : Symbol(rest5, Decl(restUnion2.ts, 15, 3), Decl(restUnion2.ts, 16, 5)) ->unionWithIntersection : Symbol(unionWithIntersection, Decl(restUnion2.ts, 14, 13)) - diff --git a/tests/baselines/reference/restUnion2.types b/tests/baselines/reference/restUnion2.types index 029192a9ac4..0e464930b07 100644 --- a/tests/baselines/reference/restUnion2.types +++ b/tests/baselines/reference/restUnion2.types @@ -25,29 +25,3 @@ var {...rest3 } = nullUnion; >rest3 : { n: number; } >nullUnion : { n: number; } | null - -declare const nullAndUndefinedUnion: null | undefined; ->nullAndUndefinedUnion : null | undefined ->null : null - -var rest4: { }; ->rest4 : {} - -var {...rest4 } = nullAndUndefinedUnion; ->rest4 : {} ->nullAndUndefinedUnion : null | undefined - -declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; ->unionWithIntersection : { n: number; } & { s: string; } & undefined ->n : number ->s : string - -var rest5: { n: number, s: string }; ->rest5 : { n: number; s: string; } ->n : number ->s : string - -var {...rest5 } = unionWithIntersection; ->rest5 : { n: number; s: string; } ->unionWithIntersection : { n: number; } & { s: string; } & undefined - diff --git a/tests/baselines/reference/restUnion3.errors.txt b/tests/baselines/reference/restUnion3.errors.txt new file mode 100644 index 00000000000..f0fa6f68812 --- /dev/null +++ b/tests/baselines/reference/restUnion3.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/restUnion3.ts(3,9): error TS2700: Rest types may only be created from object types. +tests/cases/compiler/restUnion3.ts(7,9): error TS2700: Rest types may only be created from object types. + + +==== tests/cases/compiler/restUnion3.ts (2 errors) ==== + declare const nullAndUndefinedUnion: null | undefined; + var rest4: { }; + var {...rest4 } = nullAndUndefinedUnion; + ~~~~~ +!!! error TS2700: Rest types may only be created from object types. + + declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; + var rest5: { n: number, s: string }; + var {...rest5 } = unionWithIntersection; + ~~~~~ +!!! error TS2700: Rest types may only be created from object types. + \ No newline at end of file diff --git a/tests/baselines/reference/restUnion3.js b/tests/baselines/reference/restUnion3.js new file mode 100644 index 00000000000..0dbfc425754 --- /dev/null +++ b/tests/baselines/reference/restUnion3.js @@ -0,0 +1,25 @@ +//// [restUnion3.ts] +declare const nullAndUndefinedUnion: null | undefined; +var rest4: { }; +var {...rest4 } = nullAndUndefinedUnion; + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; +var rest5: { n: number, s: string }; +var {...rest5 } = unionWithIntersection; + + +//// [restUnion3.js] +"use strict"; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var rest4; +var rest4 = __rest(nullAndUndefinedUnion, []); +var rest5; +var rest5 = __rest(unionWithIntersection, []); diff --git a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt index 5088390f9ee..4c1aa286aad 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt +++ b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt @@ -1,20 +1,22 @@ -tests/cases/compiler/spreadInvalidArgumentType.ts(31,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(30,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(32,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(33,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(34,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(35,16): error TS2698: Spread types may only be created from object types. -tests/cases/compiler/spreadInvalidArgumentType.ts(36,16): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(38,16): error TS2698: Spread types may only be created from object types. -tests/cases/compiler/spreadInvalidArgumentType.ts(41,16): error TS2698: Spread types may only be created from object types. -tests/cases/compiler/spreadInvalidArgumentType.ts(42,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(39,16): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(41,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(42,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(44,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(45,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(47,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(48,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(52,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(53,17): error TS2698: Spread types may only be created from object types. tests/cases/compiler/spreadInvalidArgumentType.ts(55,17): error TS2698: Spread types may only be created from object types. -tests/cases/compiler/spreadInvalidArgumentType.ts(56,17): error TS2698: Spread types may only be created from object types. -tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread types may only be created from object types. -==== tests/cases/compiler/spreadInvalidArgumentType.ts (14 errors) ==== +==== tests/cases/compiler/spreadInvalidArgumentType.ts (16 errors) ==== enum E { v1, v2 }; function f(p1: T, p2: T[]) { @@ -30,18 +32,17 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread t var union_primitive: { a: number } | number; var intersection_generic: T & { a: number }; - var intersection_premitive: { a: number } | string; + var intersection_primitive: { a: number } | string; var num: number; var str: number; + var literal_string: "string"; + var literal_number: 42; var u: undefined; var n: null; - var a: any; - var literal_string: "string"; - var literal_number: 42; var e: E; @@ -52,14 +53,12 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread t var o3 = { ...t }; // Error, generic type paramter ~~~~ !!! error TS2698: Spread types may only be created from object types. - var o4 = { ...i }; // Error, index access ~~~~ !!! error TS2698: Spread types may only be created from object types. var o5 = { ...k }; // Error, index ~~~~ !!! error TS2698: Spread types may only be created from object types. - var o6 = { ...mapped_generic }; // Error, generic mapped object type ~~~~~~~~~~~~~~~~~ !!! error TS2698: Spread types may only be created from object types. @@ -75,7 +74,7 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread t var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter ~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2698: Spread types may only be created from object types. - var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter + var o11 = { ...intersection_primitive }; // Error, intersection with generic type parameter ~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2698: Spread types may only be created from object types. @@ -86,8 +85,12 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread t ~~~~~~ !!! error TS2698: Spread types may only be created from object types. - var o14 = { ...u }; // OK - var o15 = { ...n }; // OK + var o14 = { ...u }; // error, undefined-only not allowed + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o15 = { ...n }; // error, null-only not allowed + ~~~~ +!!! error TS2698: Spread types may only be created from object types. var o16 = { ...a }; // OK @@ -101,4 +104,5 @@ tests/cases/compiler/spreadInvalidArgumentType.ts(58,17): error TS2698: Spread t var o19 = { ...e }; // Error, enum ~~~~ !!! error TS2698: Spread types may only be created from object types. - } \ No newline at end of file + } + \ No newline at end of file diff --git a/tests/baselines/reference/spreadInvalidArgumentType.js b/tests/baselines/reference/spreadInvalidArgumentType.js index 26f958f224d..7aa04616fd1 100644 --- a/tests/baselines/reference/spreadInvalidArgumentType.js +++ b/tests/baselines/reference/spreadInvalidArgumentType.js @@ -14,28 +14,25 @@ function f(p1: T, p2: T[]) { var union_primitive: { a: number } | number; var intersection_generic: T & { a: number }; - var intersection_premitive: { a: number } | string; + var intersection_primitive: { a: number } | string; var num: number; var str: number; + var literal_string: "string"; + var literal_number: 42; var u: undefined; var n: null; - var a: any; - var literal_string: "string"; - var literal_number: 42; var e: E; var o1 = { ...p1 }; // Error, generic type paramterre var o2 = { ...p2 }; // OK var o3 = { ...t }; // Error, generic type paramter - var o4 = { ...i }; // Error, index access var o5 = { ...k }; // Error, index - var o6 = { ...mapped_generic }; // Error, generic mapped object type var o7 = { ...mapped }; // OK, non-generic mapped type @@ -43,13 +40,13 @@ function f(p1: T, p2: T[]) { var o9 = { ...union_primitive }; // Error, union with generic type parameter var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter - var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter + var o11 = { ...intersection_primitive }; // Error, intersection with generic type parameter var o12 = { ...num }; // Error var o13 = { ...str }; // Error - var o14 = { ...u }; // OK - var o15 = { ...n }; // OK + var o14 = { ...u }; // error, undefined-only not allowed + var o15 = { ...n }; // error, null-only not allowed var o16 = { ...a }; // OK @@ -57,7 +54,8 @@ function f(p1: T, p2: T[]) { var o18 = { ...literal_number }; // Error var o19 = { ...e }; // Error, enum -} +} + //// [spreadInvalidArgumentType.js] var __assign = (this && this.__assign) || Object.assign || function(t) { @@ -83,14 +81,14 @@ function f(p1, p2) { var union_generic; var union_primitive; var intersection_generic; - var intersection_premitive; + var intersection_primitive; var num; var str; + var literal_string; + var literal_number; var u; var n; var a; - var literal_string; - var literal_number; var e; var o1 = __assign({}, p1); // Error, generic type paramterre var o2 = __assign({}, p2); // OK @@ -102,11 +100,11 @@ function f(p1, p2) { var o8 = __assign({}, union_generic); // Error, union with generic type parameter var o9 = __assign({}, union_primitive); // Error, union with generic type parameter var o10 = __assign({}, intersection_generic); // Error, intersection with generic type parameter - var o11 = __assign({}, intersection_premitive); // Error, intersection with generic type parameter + var o11 = __assign({}, intersection_primitive); // Error, intersection with generic type parameter var o12 = __assign({}, num); // Error var o13 = __assign({}, str); // Error - var o14 = __assign({}, u); // OK - var o15 = __assign({}, n); // OK + var o14 = __assign({}, u); // error, undefined-only not allowed + var o15 = __assign({}, n); // error, null-only not allowed var o16 = __assign({}, a); // OK var o17 = __assign({}, literal_string); // Error var o18 = __assign({}, literal_number); // Error diff --git a/tests/baselines/reference/spreadUnion2.js b/tests/baselines/reference/spreadUnion2.js index 6e49770617a..0ae63266da3 100644 --- a/tests/baselines/reference/spreadUnion2.js +++ b/tests/baselines/reference/spreadUnion2.js @@ -1,7 +1,6 @@ //// [spreadUnion2.ts] declare const undefinedUnion: { a: number } | undefined; declare const nullUnion: { b: number } | null; -declare const nullAndUndefinedUnion: null | undefined; var o1: {} | { a: number }; var o1 = { ...undefinedUnion }; @@ -9,7 +8,7 @@ var o1 = { ...undefinedUnion }; var o2: {} | { b: number }; var o2 = { ...nullUnion }; -var o3: {} | { b: number } | { a: number } | { a: number, b: number }; +var o3: {} | { a: number } | { b: number } | { a: number, b: number }; var o3 = { ...undefinedUnion, ...nullUnion }; var o3 = { ...nullUnion, ...undefinedUnion }; @@ -19,8 +18,6 @@ var o4 = { ...undefinedUnion, ...undefinedUnion }; var o5: {} | { b: number }; var o5 = { ...nullUnion, ...nullUnion }; -var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; -var o7 = { ...nullAndUndefinedUnion }; //// [spreadUnion2.js] @@ -43,5 +40,3 @@ var o4; var o4 = __assign({}, undefinedUnion, undefinedUnion); var o5; var o5 = __assign({}, nullUnion, nullUnion); -var o6 = __assign({}, nullAndUndefinedUnion, nullAndUndefinedUnion); -var o7 = __assign({}, nullAndUndefinedUnion); diff --git a/tests/baselines/reference/spreadUnion2.symbols b/tests/baselines/reference/spreadUnion2.symbols index c4d1f19b6d9..72e373d862d 100644 --- a/tests/baselines/reference/spreadUnion2.symbols +++ b/tests/baselines/reference/spreadUnion2.symbols @@ -7,66 +7,55 @@ declare const nullUnion: { b: number } | null; >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) >b : Symbol(b, Decl(spreadUnion2.ts, 1, 26)) -declare const nullAndUndefinedUnion: null | undefined; ->nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) - var o1: {} | { a: number }; ->o1 : Symbol(o1, Decl(spreadUnion2.ts, 4, 3), Decl(spreadUnion2.ts, 5, 3)) ->a : Symbol(a, Decl(spreadUnion2.ts, 4, 14)) +>o1 : Symbol(o1, Decl(spreadUnion2.ts, 3, 3), Decl(spreadUnion2.ts, 4, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 3, 14)) var o1 = { ...undefinedUnion }; ->o1 : Symbol(o1, Decl(spreadUnion2.ts, 4, 3), Decl(spreadUnion2.ts, 5, 3)) +>o1 : Symbol(o1, Decl(spreadUnion2.ts, 3, 3), Decl(spreadUnion2.ts, 4, 3)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) var o2: {} | { b: number }; ->o2 : Symbol(o2, Decl(spreadUnion2.ts, 7, 3), Decl(spreadUnion2.ts, 8, 3)) ->b : Symbol(b, Decl(spreadUnion2.ts, 7, 14)) +>o2 : Symbol(o2, Decl(spreadUnion2.ts, 6, 3), Decl(spreadUnion2.ts, 7, 3)) +>b : Symbol(b, Decl(spreadUnion2.ts, 6, 14)) var o2 = { ...nullUnion }; ->o2 : Symbol(o2, Decl(spreadUnion2.ts, 7, 3), Decl(spreadUnion2.ts, 8, 3)) +>o2 : Symbol(o2, Decl(spreadUnion2.ts, 6, 3), Decl(spreadUnion2.ts, 7, 3)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) -var o3: {} | { b: number } | { a: number } | { a: number, b: number }; ->o3 : Symbol(o3, Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3)) ->b : Symbol(b, Decl(spreadUnion2.ts, 10, 14)) ->a : Symbol(a, Decl(spreadUnion2.ts, 10, 30)) ->a : Symbol(a, Decl(spreadUnion2.ts, 10, 46)) ->b : Symbol(b, Decl(spreadUnion2.ts, 10, 57)) +var o3: {} | { a: number } | { b: number } | { a: number, b: number }; +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 9, 3), Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 9, 14)) +>b : Symbol(b, Decl(spreadUnion2.ts, 9, 30)) +>a : Symbol(a, Decl(spreadUnion2.ts, 9, 46)) +>b : Symbol(b, Decl(spreadUnion2.ts, 9, 57)) var o3 = { ...undefinedUnion, ...nullUnion }; ->o3 : Symbol(o3, Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3)) +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 9, 3), Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) var o3 = { ...nullUnion, ...undefinedUnion }; ->o3 : Symbol(o3, Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3), Decl(spreadUnion2.ts, 12, 3)) +>o3 : Symbol(o3, Decl(spreadUnion2.ts, 9, 3), Decl(spreadUnion2.ts, 10, 3), Decl(spreadUnion2.ts, 11, 3)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) var o4: {} | { a: number }; ->o4 : Symbol(o4, Decl(spreadUnion2.ts, 14, 3), Decl(spreadUnion2.ts, 15, 3)) ->a : Symbol(a, Decl(spreadUnion2.ts, 14, 14)) +>o4 : Symbol(o4, Decl(spreadUnion2.ts, 13, 3), Decl(spreadUnion2.ts, 14, 3)) +>a : Symbol(a, Decl(spreadUnion2.ts, 13, 14)) var o4 = { ...undefinedUnion, ...undefinedUnion }; ->o4 : Symbol(o4, Decl(spreadUnion2.ts, 14, 3), Decl(spreadUnion2.ts, 15, 3)) +>o4 : Symbol(o4, Decl(spreadUnion2.ts, 13, 3), Decl(spreadUnion2.ts, 14, 3)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) >undefinedUnion : Symbol(undefinedUnion, Decl(spreadUnion2.ts, 0, 13)) var o5: {} | { b: number }; ->o5 : Symbol(o5, Decl(spreadUnion2.ts, 17, 3), Decl(spreadUnion2.ts, 18, 3)) ->b : Symbol(b, Decl(spreadUnion2.ts, 17, 14)) +>o5 : Symbol(o5, Decl(spreadUnion2.ts, 16, 3), Decl(spreadUnion2.ts, 17, 3)) +>b : Symbol(b, Decl(spreadUnion2.ts, 16, 14)) var o5 = { ...nullUnion, ...nullUnion }; ->o5 : Symbol(o5, Decl(spreadUnion2.ts, 17, 3), Decl(spreadUnion2.ts, 18, 3)) +>o5 : Symbol(o5, Decl(spreadUnion2.ts, 16, 3), Decl(spreadUnion2.ts, 17, 3)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) >nullUnion : Symbol(nullUnion, Decl(spreadUnion2.ts, 1, 13)) -var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; ->o6 : Symbol(o6, Decl(spreadUnion2.ts, 20, 3)) ->nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) ->nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) - -var o7 = { ...nullAndUndefinedUnion }; ->o7 : Symbol(o7, Decl(spreadUnion2.ts, 21, 3)) ->nullAndUndefinedUnion : Symbol(nullAndUndefinedUnion, Decl(spreadUnion2.ts, 2, 13)) diff --git a/tests/baselines/reference/spreadUnion2.types b/tests/baselines/reference/spreadUnion2.types index ea3364f296b..5077949bc97 100644 --- a/tests/baselines/reference/spreadUnion2.types +++ b/tests/baselines/reference/spreadUnion2.types @@ -8,10 +8,6 @@ declare const nullUnion: { b: number } | null; >b : number >null : null -declare const nullAndUndefinedUnion: null | undefined; ->nullAndUndefinedUnion : null | undefined ->null : null - var o1: {} | { a: number }; >o1 : {} | { a: number; } >a : number @@ -30,21 +26,21 @@ var o2 = { ...nullUnion }; >{ ...nullUnion } : {} | { b: number; } >nullUnion : { b: number; } | null -var o3: {} | { b: number } | { a: number } | { a: number, b: number }; ->o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } ->b : number +var o3: {} | { a: number } | { b: number } | { a: number, b: number }; +>o3 : {} | { a: number; } | { b: number; } | { a: number; b: number; } >a : number +>b : number >a : number >b : number var o3 = { ...undefinedUnion, ...nullUnion }; ->o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } +>o3 : {} | { a: number; } | { b: number; } | { a: number; b: number; } >{ ...undefinedUnion, ...nullUnion } : {} | { b: number; } | { a: number; } | { b: number; a: number; } >undefinedUnion : { a: number; } | undefined >nullUnion : { b: number; } | null var o3 = { ...nullUnion, ...undefinedUnion }; ->o3 : {} | { b: number; } | { a: number; } | { a: number; b: number; } +>o3 : {} | { a: number; } | { b: number; } | { a: number; b: number; } >{ ...nullUnion, ...undefinedUnion } : {} | { a: number; } | { b: number; } | { a: number; b: number; } >nullUnion : { b: number; } | null >undefinedUnion : { a: number; } | undefined @@ -69,14 +65,4 @@ var o5 = { ...nullUnion, ...nullUnion }; >nullUnion : { b: number; } | null >nullUnion : { b: number; } | null -var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; ->o6 : {} | {} | {} | {} ->{ ...nullAndUndefinedUnion, ...nullAndUndefinedUnion } : {} | {} | {} | {} ->nullAndUndefinedUnion : null | undefined ->nullAndUndefinedUnion : null | undefined - -var o7 = { ...nullAndUndefinedUnion }; ->o7 : {} | {} ->{ ...nullAndUndefinedUnion } : {} | {} ->nullAndUndefinedUnion : null | undefined diff --git a/tests/baselines/reference/spreadUnion3.errors.txt b/tests/baselines/reference/spreadUnion3.errors.txt index 5f5b620685c..b7c59697946 100644 --- a/tests/baselines/reference/spreadUnion3.errors.txt +++ b/tests/baselines/reference/spreadUnion3.errors.txt @@ -4,9 +4,11 @@ tests/cases/conformance/types/spread/spreadUnion3.ts(2,5): error TS2322: Type '{ Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/spread/spreadUnion3.ts(9,23): error TS2339: Property 'a' does not exist on type '{} | {} | { a: number; }'. Property 'a' does not exist on type '{}'. +tests/cases/conformance/types/spread/spreadUnion3.ts(17,11): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/spread/spreadUnion3.ts(18,11): error TS2698: Spread types may only be created from object types. -==== tests/cases/conformance/types/spread/spreadUnion3.ts (2 errors) ==== +==== tests/cases/conformance/types/spread/spreadUnion3.ts (4 errors) ==== function f(x: { y: string } | undefined): { y: string } { return { y: 123, ...x } // y: string | number ~~~~~~~~~~~~~~~~~~~~~~~ @@ -28,4 +30,13 @@ tests/cases/conformance/types/spread/spreadUnion3.ts(9,23): error TS2339: Proper g() g(undefined) g(null) + + // spreading nothing but null and undefined is not allowed + declare const nullAndUndefinedUnion: null | undefined; + var x = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var y = { ...nullAndUndefinedUnion }; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. \ No newline at end of file diff --git a/tests/baselines/reference/spreadUnion3.js b/tests/baselines/reference/spreadUnion3.js index 2aaf9efeb78..253c2998b9d 100644 --- a/tests/baselines/reference/spreadUnion3.js +++ b/tests/baselines/reference/spreadUnion3.js @@ -12,6 +12,11 @@ function g(t?: { a: number } | null): void { g() g(undefined) g(null) + +// spreading nothing but null and undefined is not allowed +declare const nullAndUndefinedUnion: null | undefined; +var x = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +var y = { ...nullAndUndefinedUnion }; //// [spreadUnion3.js] @@ -34,3 +39,5 @@ function g(t) { g(); g(undefined); g(null); +var x = __assign({}, nullAndUndefinedUnion, nullAndUndefinedUnion); +var y = __assign({}, nullAndUndefinedUnion); diff --git a/tests/cases/compiler/restInvalidArgumentType.ts b/tests/cases/compiler/restInvalidArgumentType.ts index 488f546e231..db372fbd4af 100644 --- a/tests/cases/compiler/restInvalidArgumentType.ts +++ b/tests/cases/compiler/restInvalidArgumentType.ts @@ -11,27 +11,22 @@ function f(p1: T, p2: T[]) { var union_generic: T | { a: number }; var union_primitive: { a: number } | number; - var intersection_generic: T & { a: number }; - var intersection_premitive: { a: number } | string; - + var intersection_primitive: { a: number } & string; var num: number; - var str: number; + var str: string; + var literal_string: "string"; + var literal_number: 42; + var e: E; var u: undefined; var n: null; var a: any; - var literal_string: "string"; - var literal_number: 42; - - var e: E; - var {...r1} = p1; // Error, generic type paramterre var {...r2} = p2; // OK var {...r3} = t; // Error, generic type paramter - var {...r4} = i; // Error, index access var {...r5} = k; // Error, index @@ -42,13 +37,13 @@ function f(p1: T, p2: T[]) { var {...r9} = union_primitive; // Error, union with generic type parameter var {...r10} = intersection_generic; // Error, intersection with generic type parameter - var {...r11} = intersection_premitive; // Error, intersection with generic type parameter + var {...r11} = intersection_primitive; // Error, intersection with generic type parameter var {...r12} = num; // Error var {...r13} = str; // Error - var {...r14} = u; // OK - var {...r15} = n; // OK + var {...r14} = u; // error, undefined-only not allowed + var {...r15} = n; // error, null-only not allowed var {...r16} = a; // OK @@ -56,4 +51,4 @@ function f(p1: T, p2: T[]) { var {...r18} = literal_number; // Error var {...r19} = e; // Error, enum -} \ No newline at end of file +} diff --git a/tests/cases/compiler/restUnion2.ts b/tests/cases/compiler/restUnion2.ts index 21f912cb2fb..9ae6503fb13 100644 --- a/tests/cases/compiler/restUnion2.ts +++ b/tests/cases/compiler/restUnion2.ts @@ -8,12 +8,3 @@ var {...rest2 } = undefinedUnion; declare const nullUnion: { n: number } | null; var rest3: { n: number }; var {...rest3 } = nullUnion; - - -declare const nullAndUndefinedUnion: null | undefined; -var rest4: { }; -var {...rest4 } = nullAndUndefinedUnion; - -declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; -var rest5: { n: number, s: string }; -var {...rest5 } = unionWithIntersection; \ No newline at end of file diff --git a/tests/cases/compiler/restUnion3.ts b/tests/cases/compiler/restUnion3.ts new file mode 100644 index 00000000000..9847a628f38 --- /dev/null +++ b/tests/cases/compiler/restUnion3.ts @@ -0,0 +1,8 @@ +// @strict: true +declare const nullAndUndefinedUnion: null | undefined; +var rest4: { }; +var {...rest4 } = nullAndUndefinedUnion; + +declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined; +var rest5: { n: number, s: string }; +var {...rest5 } = unionWithIntersection; diff --git a/tests/cases/compiler/spreadInvalidArgumentType.ts b/tests/cases/compiler/spreadInvalidArgumentType.ts index 2ac6aa921f4..f18e73b31ef 100644 --- a/tests/cases/compiler/spreadInvalidArgumentType.ts +++ b/tests/cases/compiler/spreadInvalidArgumentType.ts @@ -13,28 +13,25 @@ function f(p1: T, p2: T[]) { var union_primitive: { a: number } | number; var intersection_generic: T & { a: number }; - var intersection_premitive: { a: number } | string; + var intersection_primitive: { a: number } | string; var num: number; var str: number; + var literal_string: "string"; + var literal_number: 42; var u: undefined; var n: null; - var a: any; - var literal_string: "string"; - var literal_number: 42; var e: E; var o1 = { ...p1 }; // Error, generic type paramterre var o2 = { ...p2 }; // OK var o3 = { ...t }; // Error, generic type paramter - var o4 = { ...i }; // Error, index access var o5 = { ...k }; // Error, index - var o6 = { ...mapped_generic }; // Error, generic mapped object type var o7 = { ...mapped }; // OK, non-generic mapped type @@ -42,13 +39,13 @@ function f(p1: T, p2: T[]) { var o9 = { ...union_primitive }; // Error, union with generic type parameter var o10 = { ...intersection_generic }; // Error, intersection with generic type parameter - var o11 = { ...intersection_premitive }; // Error, intersection with generic type parameter + var o11 = { ...intersection_primitive }; // Error, intersection with generic type parameter var o12 = { ...num }; // Error var o13 = { ...str }; // Error - var o14 = { ...u }; // OK - var o15 = { ...n }; // OK + var o14 = { ...u }; // error, undefined-only not allowed + var o15 = { ...n }; // error, null-only not allowed var o16 = { ...a }; // OK @@ -56,4 +53,4 @@ function f(p1: T, p2: T[]) { var o18 = { ...literal_number }; // Error var o19 = { ...e }; // Error, enum -} \ No newline at end of file +} diff --git a/tests/cases/conformance/types/spread/objectSpread.ts b/tests/cases/conformance/types/spread/objectSpread.ts index 59b93bdd9e4..c7cf5e49eed 100644 --- a/tests/cases/conformance/types/spread/objectSpread.ts +++ b/tests/cases/conformance/types/spread/objectSpread.ts @@ -1,3 +1,4 @@ +// @strictNullChecks: true // @target: es5 let o = { a: 1, b: 'no' } let o2 = { b: 'yes', c: true } @@ -38,6 +39,43 @@ getter.a = 12; // functions result in { } let spreadFunc = { ...(function () { }) }; +type Header = { head: string, body: string, authToken: string } +function from16326(this: { header: Header }, header: Header, authToken: string): Header { + return { + ...this.header, + ...header, + ...authToken && { authToken } + } +} +// boolean && T results in Partial +function conditionalSpreadBoolean(b: boolean) : { x: number, y: number } { + let o = { x: 12, y: 13 } + o = { + ...o, + ...b && { x: 14 } + } + let o2 = { ...b && { x: 21 }} + return o; +} +function conditionalSpreadNumber(nt: number): { x: number, y: number } { + let o = { x: 15, y: 16 } + o = { + ...o, + ...nt && { x: nt } + } + let o2 = { ...nt && { x: nt }} + return o; +} +function conditionalSpreadString(st: string): { x: string, y: number } { + let o = { x: 'hi', y: 17 } + o = { + ...o, + ...st && { x: st } + } + let o2 = { ...st && { x: st }} + return o; +} + // any results in any let anything: any; let spreadAny = { ...anything }; @@ -60,21 +98,23 @@ let changeTypeBoth: { a: string, b: number } = { ...o, ...swap }; // optional -let definiteBoolean: { sn: boolean }; -let definiteString: { sn: string }; -let optionalString: { sn?: string }; -let optionalNumber: { sn?: number }; -let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; -let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; -let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; +function container( + definiteBoolean: { sn: boolean }, + definiteString: { sn: string }, + optionalString: { sn?: string }, + optionalNumber: { sn?: number }) { + let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; + let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; + let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; -// computed property -let computedFirst: { a: number, b: string, "before everything": number } = - { ['before everything']: 12, ...o, b: 'yes' } -let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = - { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } -let computedAfter: { a: number, b: string, "at the end": number } = - { ...o, b: 'yeah', ['at the end']: 14 } + // computed property + let computedFirst: { a: number, b: string, "before everything": number } = + { ['before everything']: 12, ...o, b: 'yes' } + let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } = + { ...o, ['in the middle']: 13, b: 'maybe?', ...o2 } + let computedAfter: { a: number, b: string, "at the end": number } = + { ...o, b: 'yeah', ['at the end']: 14 } +} // shortcut syntax let a = 12; let shortCutted: { a: number, b: string } = { ...o, a } diff --git a/tests/cases/conformance/types/spread/objectSpreadNegative.ts b/tests/cases/conformance/types/spread/objectSpreadNegative.ts index fced7706c96..b6e7c5b88c9 100644 --- a/tests/cases/conformance/types/spread/objectSpreadNegative.ts +++ b/tests/cases/conformance/types/spread/objectSpreadNegative.ts @@ -29,12 +29,13 @@ spread = b; // error, missing 's' let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' } let duplicatedSpread = { ...o, ...o } -// primitives are not allowed +// primitives are not allowed, except for falsy ones let spreadNum = { ...12 }; let spreadSum = { ...1 + 1 }; -spreadSum.toFixed(); // error, no methods from number -let spreadBool = { ...false }; -spreadBool.valueOf(); // error, what were you thinking? +let spreadZero = { ...0 }; +spreadZero.toFixed(); // error, no methods even from a falsy number +let spreadBool = { ...true }; +spreadBool.valueOf(); let spreadStr = { ...'foo' }; spreadStr.length; // error, no 'length' spreadStr.charAt(1); // error, no methods either diff --git a/tests/cases/conformance/types/spread/spreadUnion2.ts b/tests/cases/conformance/types/spread/spreadUnion2.ts index e2f72879915..5fbca1d4bf2 100644 --- a/tests/cases/conformance/types/spread/spreadUnion2.ts +++ b/tests/cases/conformance/types/spread/spreadUnion2.ts @@ -2,7 +2,6 @@ declare const undefinedUnion: { a: number } | undefined; declare const nullUnion: { b: number } | null; -declare const nullAndUndefinedUnion: null | undefined; var o1: {} | { a: number }; var o1 = { ...undefinedUnion }; @@ -10,7 +9,7 @@ var o1 = { ...undefinedUnion }; var o2: {} | { b: number }; var o2 = { ...nullUnion }; -var o3: {} | { b: number } | { a: number } | { a: number, b: number }; +var o3: {} | { a: number } | { b: number } | { a: number, b: number }; var o3 = { ...undefinedUnion, ...nullUnion }; var o3 = { ...nullUnion, ...undefinedUnion }; @@ -20,5 +19,3 @@ var o4 = { ...undefinedUnion, ...undefinedUnion }; var o5: {} | { b: number }; var o5 = { ...nullUnion, ...nullUnion }; -var o6 = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; -var o7 = { ...nullAndUndefinedUnion }; diff --git a/tests/cases/conformance/types/spread/spreadUnion3.ts b/tests/cases/conformance/types/spread/spreadUnion3.ts index c16acbdf7d3..42ad1a1c652 100644 --- a/tests/cases/conformance/types/spread/spreadUnion3.ts +++ b/tests/cases/conformance/types/spread/spreadUnion3.ts @@ -12,3 +12,8 @@ function g(t?: { a: number } | null): void { g() g(undefined) g(null) + +// spreading nothing but null and undefined is not allowed +declare const nullAndUndefinedUnion: null | undefined; +var x = { ...nullAndUndefinedUnion, ...nullAndUndefinedUnion }; +var y = { ...nullAndUndefinedUnion };