From f2e30f66936d4e4192aa0bb32049d7e64db10f59 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Tue, 29 Nov 2016 00:04:20 -0800 Subject: [PATCH] Allow union and intersection as targets for object spread and rest, and distribute spread&rest over unions --- src/compiler/checker.ts | 31 ++++- .../restIntersectionOrIntersection.js | 29 +++++ .../restIntersectionOrIntersection.symbols | 38 ++++++ .../restIntersectionOrIntersection.types | 38 ++++++ .../restInvalidArgumentType.errors.txt | 110 +++++++++++++++++ .../reference/restInvalidArgumentType.js | 115 ++++++++++++++++++ .../baselines/reference/spreadIntersection.js | 23 ++++ .../reference/spreadIntersection.symbols | 26 ++++ .../reference/spreadIntersection.types | 29 +++++ .../spreadInvalidArgumentType.errors.txt | 110 +++++++++++++++++ .../reference/spreadInvalidArgumentType.js | 114 +++++++++++++++++ tests/baselines/reference/spreadUnion.js | 28 +++++ tests/baselines/reference/spreadUnion.symbols | 38 ++++++ tests/baselines/reference/spreadUnion.types | 42 +++++++ .../restIntersectionOrIntersection.ts | 10 ++ .../cases/compiler/restInvalidArgumentType.ts | 59 +++++++++ tests/cases/compiler/spreadIntersection.ts | 7 ++ .../compiler/spreadInvalidArgumentType.ts | 59 +++++++++ tests/cases/compiler/spreadUnion.ts | 10 ++ 19 files changed, 911 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/restIntersectionOrIntersection.js create mode 100644 tests/baselines/reference/restIntersectionOrIntersection.symbols create mode 100644 tests/baselines/reference/restIntersectionOrIntersection.types create mode 100644 tests/baselines/reference/restInvalidArgumentType.errors.txt create mode 100644 tests/baselines/reference/restInvalidArgumentType.js create mode 100644 tests/baselines/reference/spreadIntersection.js create mode 100644 tests/baselines/reference/spreadIntersection.symbols create mode 100644 tests/baselines/reference/spreadIntersection.types create mode 100644 tests/baselines/reference/spreadInvalidArgumentType.errors.txt create mode 100644 tests/baselines/reference/spreadInvalidArgumentType.js create mode 100644 tests/baselines/reference/spreadUnion.js create mode 100644 tests/baselines/reference/spreadUnion.symbols create mode 100644 tests/baselines/reference/spreadUnion.types create mode 100644 tests/cases/compiler/restIntersectionOrIntersection.ts create mode 100644 tests/cases/compiler/restInvalidArgumentType.ts create mode 100644 tests/cases/compiler/spreadIntersection.ts create mode 100644 tests/cases/compiler/spreadInvalidArgumentType.ts create mode 100644 tests/cases/compiler/spreadUnion.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 527735a3b0f..e937f6d9b97 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3054,7 +3054,10 @@ namespace ts { } function getRestType(source: Type, properties: PropertyName[], symbol: Symbol): Type { - Debug.assert(!!(source.flags & TypeFlags.Object), "Rest types only support object types right now."); + if (source.flags & TypeFlags.Union) { + return getUnionType(map((source).types, t => getRestType(t, properties, symbol))); + } + const members = createMap(); const names = createMap(); for (const name of properties) { @@ -3095,7 +3098,7 @@ namespace ts { let type: Type; if (pattern.kind === SyntaxKind.ObjectBindingPattern) { if (declaration.dotDotDotToken) { - if (!(parentType.flags & TypeFlags.Object)) { + if (isInvalidValidSpreadType(parentType)) { error(declaration, Diagnostics.Rest_types_may_only_be_created_from_object_types); return unknownType; } @@ -6102,11 +6105,19 @@ namespace ts { * this function should be called in a left folding style, with left = previous result of getSpreadType * and right = the new element to be spread. */ - function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): ResolvedType | IntrinsicType { - Debug.assert(!!(left.flags & (TypeFlags.Object | TypeFlags.Any)) && !!(right.flags & (TypeFlags.Object | TypeFlags.Any)), "Only object types may be spread."); + function getSpreadType(left: Type, right: Type, isFromObjectLiteral: boolean): Type { if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) { return anyType; } + + if (left.flags & TypeFlags.Union) { + return getUnionType(map((left).types, t => getSpreadType(t, right, isFromObjectLiteral))); + } + + if (right.flags & TypeFlags.Union) { + return getUnionType(map((right).types, t => getSpreadType(left, t, isFromObjectLiteral))); + } + const members = createMap(); const skippedPrivateMembers = createMap(); let stringIndexInfo: IndexInfo; @@ -11438,7 +11449,7 @@ namespace ts { typeFlags = 0; } const type = checkExpression((memberDecl as SpreadAssignment).expression); - if (!(type.flags & (TypeFlags.Object | TypeFlags.Any))) { + if (!(type.flags & TypeFlags.Any) && isInvalidValidSpreadType(type)) { error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types); return unknownType; } @@ -11516,6 +11527,16 @@ namespace ts { } } + function isInvalidValidSpreadType(type: Type): boolean { + if (type.flags & TypeFlags.Object) { + return isGenericMappedType(type); + } + else if (type.flags & TypeFlags.UnionOrIntersection) { + return forEach((type).types, isInvalidValidSpreadType); + } + return true; + } + function checkJsxSelfClosingElement(node: JsxSelfClosingElement) { checkJsxOpeningLikeElement(node); return jsxElementType || anyType; diff --git a/tests/baselines/reference/restIntersectionOrIntersection.js b/tests/baselines/reference/restIntersectionOrIntersection.js new file mode 100644 index 00000000000..a60a5acbd93 --- /dev/null +++ b/tests/baselines/reference/restIntersectionOrIntersection.js @@ -0,0 +1,29 @@ +//// [restIntersectionOrIntersection.ts] +var intersection: { x: number, y: number } & { w: string, z: string }; +var union: { a: number, c: boolean } | { a: string, b: string }; + + +var rest1: { y: number, w: string, z: string }; +var {x, ...rest1 } = intersection; + +var rest2: { c: boolean } | { b: string }; +var {a, ...rest2 } = union; + + + +//// [restIntersectionOrIntersection.js] +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 (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 intersection; +var union; +var rest1; +var x = intersection.x, rest1 = __rest(intersection, ["x"]); +var rest2; +var a = union.a, rest2 = __rest(union, ["a"]); diff --git a/tests/baselines/reference/restIntersectionOrIntersection.symbols b/tests/baselines/reference/restIntersectionOrIntersection.symbols new file mode 100644 index 00000000000..f2eb4f16014 --- /dev/null +++ b/tests/baselines/reference/restIntersectionOrIntersection.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/restIntersectionOrIntersection.ts === +var intersection: { x: number, y: number } & { w: string, z: string }; +>intersection : Symbol(intersection, Decl(restIntersectionOrIntersection.ts, 0, 3)) +>x : Symbol(x, Decl(restIntersectionOrIntersection.ts, 0, 19)) +>y : Symbol(y, Decl(restIntersectionOrIntersection.ts, 0, 30)) +>w : Symbol(w, Decl(restIntersectionOrIntersection.ts, 0, 46)) +>z : Symbol(z, Decl(restIntersectionOrIntersection.ts, 0, 57)) + +var union: { a: number, c: boolean } | { a: string, b: string }; +>union : Symbol(union, Decl(restIntersectionOrIntersection.ts, 1, 3)) +>a : Symbol(a, Decl(restIntersectionOrIntersection.ts, 1, 12)) +>c : Symbol(c, Decl(restIntersectionOrIntersection.ts, 1, 23)) +>a : Symbol(a, Decl(restIntersectionOrIntersection.ts, 1, 40)) +>b : Symbol(b, Decl(restIntersectionOrIntersection.ts, 1, 51)) + + +var rest1: { y: number, w: string, z: string }; +>rest1 : Symbol(rest1, Decl(restIntersectionOrIntersection.ts, 4, 3), Decl(restIntersectionOrIntersection.ts, 5, 7)) +>y : Symbol(y, Decl(restIntersectionOrIntersection.ts, 4, 12)) +>w : Symbol(w, Decl(restIntersectionOrIntersection.ts, 4, 23)) +>z : Symbol(z, Decl(restIntersectionOrIntersection.ts, 4, 34)) + +var {x, ...rest1 } = intersection; +>x : Symbol(x, Decl(restIntersectionOrIntersection.ts, 5, 5)) +>rest1 : Symbol(rest1, Decl(restIntersectionOrIntersection.ts, 4, 3), Decl(restIntersectionOrIntersection.ts, 5, 7)) +>intersection : Symbol(intersection, Decl(restIntersectionOrIntersection.ts, 0, 3)) + +var rest2: { c: boolean } | { b: string }; +>rest2 : Symbol(rest2, Decl(restIntersectionOrIntersection.ts, 7, 3), Decl(restIntersectionOrIntersection.ts, 8, 7)) +>c : Symbol(c, Decl(restIntersectionOrIntersection.ts, 7, 12)) +>b : Symbol(b, Decl(restIntersectionOrIntersection.ts, 7, 29)) + +var {a, ...rest2 } = union; +>a : Symbol(a, Decl(restIntersectionOrIntersection.ts, 8, 5)) +>rest2 : Symbol(rest2, Decl(restIntersectionOrIntersection.ts, 7, 3), Decl(restIntersectionOrIntersection.ts, 8, 7)) +>union : Symbol(union, Decl(restIntersectionOrIntersection.ts, 1, 3)) + + diff --git a/tests/baselines/reference/restIntersectionOrIntersection.types b/tests/baselines/reference/restIntersectionOrIntersection.types new file mode 100644 index 00000000000..c87769ff3cc --- /dev/null +++ b/tests/baselines/reference/restIntersectionOrIntersection.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/restIntersectionOrIntersection.ts === +var intersection: { x: number, y: number } & { w: string, z: string }; +>intersection : { x: number; y: number; } & { w: string; z: string; } +>x : number +>y : number +>w : string +>z : string + +var union: { a: number, c: boolean } | { a: string, b: string }; +>union : { a: number; c: boolean; } | { a: string; b: string; } +>a : number +>c : boolean +>a : string +>b : string + + +var rest1: { y: number, w: string, z: string }; +>rest1 : { y: number; w: string; z: string; } +>y : number +>w : string +>z : string + +var {x, ...rest1 } = intersection; +>x : number +>rest1 : { y: number; w: string; z: string; } +>intersection : { x: number; y: number; } & { w: string; z: string; } + +var rest2: { c: boolean } | { b: string }; +>rest2 : { c: boolean; } | { b: string; } +>c : boolean +>b : string + +var {a, ...rest2 } = union; +>a : string | number +>rest2 : { c: boolean; } | { b: string; } +>union : { a: number; c: boolean; } | { a: string; b: string; } + + diff --git a/tests/baselines/reference/restInvalidArgumentType.errors.txt b/tests/baselines/reference/restInvalidArgumentType.errors.txt new file mode 100644 index 00000000000..e7cf1ba6f9f --- /dev/null +++ b/tests/baselines/reference/restInvalidArgumentType.errors.txt @@ -0,0 +1,110 @@ +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(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(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(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(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 (16 errors) ==== + enum E { v1, v2 }; + + function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + 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 num: number; + var str: number; + + 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. + var {...r2} = p2; // OK + 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. + var {...r5} = k; // Error, index + ~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r6} = mapped_generic; // Error, generic mapped object type + ~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r7} = mapped; // OK, non-generic mapped type + + var {...r8} = union_generic; // Error, union with generic type parameter + ~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r9} = union_primitive; // Error, union with generic type parameter + ~~ +!!! error TS2700: Rest types may only be created from object 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 + ~~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r12} = num; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r13} = str; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r14} = u; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r15} = n; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r16} = a; // OK + + var {...r17} = literal_string; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + var {...r18} = literal_number; // Error + ~~~ +!!! error TS2700: Rest types may only be created from object types. + + var {...r19} = e; // Error, enum + ~~~ +!!! error TS2700: Rest types may only be created from object types. + } \ No newline at end of file diff --git a/tests/baselines/reference/restInvalidArgumentType.js b/tests/baselines/reference/restInvalidArgumentType.js new file mode 100644 index 00000000000..23b46a2f775 --- /dev/null +++ b/tests/baselines/reference/restInvalidArgumentType.js @@ -0,0 +1,115 @@ +//// [restInvalidArgumentType.ts] +enum E { v1, v2 }; + +function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + 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 num: number; + var str: number; + + 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 + + var {...r6} = mapped_generic; // Error, generic mapped object type + var {...r7} = mapped; // OK, non-generic mapped type + + var {...r8} = union_generic; // Error, union with generic type parameter + 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 {...r12} = num; // Error + var {...r13} = str; // Error + + var {...r14} = u; // Error + var {...r15} = n; // Error + + var {...r16} = a; // OK + + var {...r17} = literal_string; // Error + var {...r18} = literal_number; // Error + + var {...r19} = e; // Error, enum +} + +//// [restInvalidArgumentType.js] +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 (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 E; +(function (E) { + E[E["v1"] = 0] = "v1"; + E[E["v2"] = 1] = "v2"; +})(E || (E = {})); +; +function f(p1, p2) { + var t; + var i; + var k; + var mapped_generic; + var mapped; + var union_generic; + var union_primitive; + var intersection_generic; + var intersection_premitive; + var num; + var str; + var u; + var n; + var a; + var literal_string; + var literal_number; + var e; + var r1 = __rest(p1, []); // Error, generic type paramterre + var r2 = __rest(p2, []); // OK + var r3 = __rest(t, []); // Error, generic type paramter + var r4 = __rest(i, []); // Error, index access + var r5 = __rest(k, []); // Error, index + var r6 = __rest(mapped_generic, []); // Error, generic mapped object type + var r7 = __rest(mapped, []); // OK, non-generic mapped type + 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 r12 = __rest(num, []); // Error + var r13 = __rest(str, []); // Error + var r14 = __rest(u, []); // Error + var r15 = __rest(n, []); // Error + var r16 = __rest(a, []); // OK + var r17 = __rest(literal_string, []); // Error + var r18 = __rest(literal_number, []); // Error + var r19 = __rest(e, []); // Error, enum +} diff --git a/tests/baselines/reference/spreadIntersection.js b/tests/baselines/reference/spreadIntersection.js new file mode 100644 index 00000000000..b3fa9f0c2fb --- /dev/null +++ b/tests/baselines/reference/spreadIntersection.js @@ -0,0 +1,23 @@ +//// [spreadIntersection.ts] +var intersection: { a: number } & { b: string }; + +var o1: { a: number, b: string }; +var o1 = { ...intersection }; + +var o2: { a: number, b: string, c: boolean }; +var o2 = { ...intersection, c: false }; + +//// [spreadIntersection.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var intersection; +var o1; +var o1 = __assign({}, intersection); +var o2; +var o2 = __assign({}, intersection, { c: false }); diff --git a/tests/baselines/reference/spreadIntersection.symbols b/tests/baselines/reference/spreadIntersection.symbols new file mode 100644 index 00000000000..1f6b3c12de1 --- /dev/null +++ b/tests/baselines/reference/spreadIntersection.symbols @@ -0,0 +1,26 @@ +=== tests/cases/compiler/spreadIntersection.ts === +var intersection: { a: number } & { b: string }; +>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3)) +>a : Symbol(a, Decl(spreadIntersection.ts, 0, 19)) +>b : Symbol(b, Decl(spreadIntersection.ts, 0, 35)) + +var o1: { a: number, b: string }; +>o1 : Symbol(o1, Decl(spreadIntersection.ts, 2, 3), Decl(spreadIntersection.ts, 3, 3)) +>a : Symbol(a, Decl(spreadIntersection.ts, 2, 9)) +>b : Symbol(b, Decl(spreadIntersection.ts, 2, 20)) + +var o1 = { ...intersection }; +>o1 : Symbol(o1, Decl(spreadIntersection.ts, 2, 3), Decl(spreadIntersection.ts, 3, 3)) +>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3)) + +var o2: { a: number, b: string, c: boolean }; +>o2 : Symbol(o2, Decl(spreadIntersection.ts, 5, 3), Decl(spreadIntersection.ts, 6, 3)) +>a : Symbol(a, Decl(spreadIntersection.ts, 5, 9)) +>b : Symbol(b, Decl(spreadIntersection.ts, 5, 20)) +>c : Symbol(c, Decl(spreadIntersection.ts, 5, 31)) + +var o2 = { ...intersection, c: false }; +>o2 : Symbol(o2, Decl(spreadIntersection.ts, 5, 3), Decl(spreadIntersection.ts, 6, 3)) +>intersection : Symbol(intersection, Decl(spreadIntersection.ts, 0, 3)) +>c : Symbol(c, Decl(spreadIntersection.ts, 6, 27)) + diff --git a/tests/baselines/reference/spreadIntersection.types b/tests/baselines/reference/spreadIntersection.types new file mode 100644 index 00000000000..c3c6b99adee --- /dev/null +++ b/tests/baselines/reference/spreadIntersection.types @@ -0,0 +1,29 @@ +=== tests/cases/compiler/spreadIntersection.ts === +var intersection: { a: number } & { b: string }; +>intersection : { a: number; } & { b: string; } +>a : number +>b : string + +var o1: { a: number, b: string }; +>o1 : { a: number; b: string; } +>a : number +>b : string + +var o1 = { ...intersection }; +>o1 : { a: number; b: string; } +>{ ...intersection } : { a: number; b: string; } +>intersection : { a: number; } & { b: string; } + +var o2: { a: number, b: string, c: boolean }; +>o2 : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + +var o2 = { ...intersection, c: false }; +>o2 : { a: number; b: string; c: boolean; } +>{ ...intersection, c: false } : { c: boolean; a: number; b: string; } +>intersection : { a: number; } & { b: string; } +>c : boolean +>false : false + diff --git a/tests/baselines/reference/spreadInvalidArgumentType.errors.txt b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt new file mode 100644 index 00000000000..34356e53813 --- /dev/null +++ b/tests/baselines/reference/spreadInvalidArgumentType.errors.txt @@ -0,0 +1,110 @@ +tests/cases/compiler/spreadInvalidArgumentType.ts(31,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(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(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(50,17): error TS2698: Spread types may only be created from object types. +tests/cases/compiler/spreadInvalidArgumentType.ts(51,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 (16 errors) ==== + enum E { v1, v2 }; + + function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + 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 num: number; + var str: number; + + 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 + ~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o2 = { ...p2 }; // OK + 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. + var o7 = { ...mapped }; // OK, non-generic mapped type + + var o8 = { ...union_generic }; // Error, union with generic type parameter + ~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o9 = { ...union_primitive }; // Error, union with generic type parameter + ~~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + + 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 + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o12 = { ...num }; // Error + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o13 = { ...str }; // Error + ~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o14 = { ...u }; // Error + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o15 = { ...n }; // Error + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o16 = { ...a }; // OK + + var o17 = { ...literal_string }; // Error + ~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + var o18 = { ...literal_number }; // Error + ~~~~~~~~~~~~~~~~~ +!!! error TS2698: Spread types may only be created from object types. + + var o19 = { ...e }; // Error, enum + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + } \ No newline at end of file diff --git a/tests/baselines/reference/spreadInvalidArgumentType.js b/tests/baselines/reference/spreadInvalidArgumentType.js new file mode 100644 index 00000000000..ecea599842e --- /dev/null +++ b/tests/baselines/reference/spreadInvalidArgumentType.js @@ -0,0 +1,114 @@ +//// [spreadInvalidArgumentType.ts] +enum E { v1, v2 }; + +function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + 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 num: number; + var str: number; + + 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 + + var o8 = { ...union_generic }; // Error, union with generic type parameter + 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 o12 = { ...num }; // Error + var o13 = { ...str }; // Error + + var o14 = { ...u }; // Error + var o15 = { ...n }; // Error + + var o16 = { ...a }; // OK + + var o17 = { ...literal_string }; // Error + var o18 = { ...literal_number }; // Error + + var o19 = { ...e }; // Error, enum +} + +//// [spreadInvalidArgumentType.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var E; +(function (E) { + E[E["v1"] = 0] = "v1"; + E[E["v2"] = 1] = "v2"; +})(E || (E = {})); +; +function f(p1, p2) { + var t; + var i; + var k; + var mapped_generic; + var mapped; + var union_generic; + var union_primitive; + var intersection_generic; + var intersection_premitive; + var num; + var str; + 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 + var o3 = __assign({}, t); // Error, generic type paramter + var o4 = __assign({}, i); // Error, index access + var o5 = __assign({}, k); // Error, index + var o6 = __assign({}, mapped_generic); // Error, generic mapped object type + var o7 = __assign({}, mapped); // OK, non-generic mapped type + 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 o12 = __assign({}, num); // Error + var o13 = __assign({}, str); // Error + var o14 = __assign({}, u); // Error + var o15 = __assign({}, n); // Error + var o16 = __assign({}, a); // OK + var o17 = __assign({}, literal_string); // Error + var o18 = __assign({}, literal_number); // Error + var o19 = __assign({}, e); // Error, enum +} diff --git a/tests/baselines/reference/spreadUnion.js b/tests/baselines/reference/spreadUnion.js new file mode 100644 index 00000000000..2691a3acdcc --- /dev/null +++ b/tests/baselines/reference/spreadUnion.js @@ -0,0 +1,28 @@ +//// [spreadUnion.ts] +var union: { a: number } | { b: string }; + +var o3: { a: number } | { b: string }; +var o3 = { ...union }; + +var o4: { a: boolean } | { b: string , a: boolean}; +var o4 = { ...union, a: false }; + +var o5: { a: number } | { b: string } | { a: number, b: string }; +var o5 = { ...union, ...union }; + +//// [spreadUnion.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var union; +var o3; +var o3 = __assign({}, union); +var o4; +var o4 = __assign({}, union, { a: false }); +var o5; +var o5 = __assign({}, union, union); diff --git a/tests/baselines/reference/spreadUnion.symbols b/tests/baselines/reference/spreadUnion.symbols new file mode 100644 index 00000000000..40a63d56d49 --- /dev/null +++ b/tests/baselines/reference/spreadUnion.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/spreadUnion.ts === +var union: { a: number } | { b: string }; +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 0, 12)) +>b : Symbol(b, Decl(spreadUnion.ts, 0, 28)) + +var o3: { a: number } | { b: string }; +>o3 : Symbol(o3, Decl(spreadUnion.ts, 2, 3), Decl(spreadUnion.ts, 3, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 2, 9)) +>b : Symbol(b, Decl(spreadUnion.ts, 2, 25)) + +var o3 = { ...union }; +>o3 : Symbol(o3, Decl(spreadUnion.ts, 2, 3), Decl(spreadUnion.ts, 3, 3)) +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) + +var o4: { a: boolean } | { b: string , a: boolean}; +>o4 : Symbol(o4, Decl(spreadUnion.ts, 5, 3), Decl(spreadUnion.ts, 6, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 5, 9)) +>b : Symbol(b, Decl(spreadUnion.ts, 5, 26)) +>a : Symbol(a, Decl(spreadUnion.ts, 5, 38)) + +var o4 = { ...union, a: false }; +>o4 : Symbol(o4, Decl(spreadUnion.ts, 5, 3), Decl(spreadUnion.ts, 6, 3)) +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 6, 21)) + +var o5: { a: number } | { b: string } | { a: number, b: string }; +>o5 : Symbol(o5, Decl(spreadUnion.ts, 8, 3), Decl(spreadUnion.ts, 9, 3)) +>a : Symbol(a, Decl(spreadUnion.ts, 8, 9)) +>b : Symbol(b, Decl(spreadUnion.ts, 8, 25)) +>a : Symbol(a, Decl(spreadUnion.ts, 8, 41)) +>b : Symbol(b, Decl(spreadUnion.ts, 8, 52)) + +var o5 = { ...union, ...union }; +>o5 : Symbol(o5, Decl(spreadUnion.ts, 8, 3), Decl(spreadUnion.ts, 9, 3)) +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) +>union : Symbol(union, Decl(spreadUnion.ts, 0, 3)) + diff --git a/tests/baselines/reference/spreadUnion.types b/tests/baselines/reference/spreadUnion.types new file mode 100644 index 00000000000..9e5ac1cffd5 --- /dev/null +++ b/tests/baselines/reference/spreadUnion.types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/spreadUnion.ts === +var union: { a: number } | { b: string }; +>union : { a: number; } | { b: string; } +>a : number +>b : string + +var o3: { a: number } | { b: string }; +>o3 : { a: number; } | { b: string; } +>a : number +>b : string + +var o3 = { ...union }; +>o3 : { a: number; } | { b: string; } +>{ ...union } : { a: number; } | { b: string; } +>union : { a: number; } | { b: string; } + +var o4: { a: boolean } | { b: string , a: boolean}; +>o4 : { a: boolean; } | { b: string; a: boolean; } +>a : boolean +>b : string +>a : boolean + +var o4 = { ...union, a: false }; +>o4 : { a: boolean; } | { b: string; a: boolean; } +>{ ...union, a: false } : { a: boolean; } | { a: boolean; b: string; } +>union : { a: number; } | { b: string; } +>a : boolean +>false : false + +var o5: { a: number } | { b: string } | { a: number, b: string }; +>o5 : { a: number; } | { b: string; } | { a: number; b: string; } +>a : number +>b : string +>a : number +>b : string + +var o5 = { ...union, ...union }; +>o5 : { a: number; } | { b: string; } | { a: number; b: string; } +>{ ...union, ...union } : { a: number; } | { b: string; a: number; } | { a: number; b: string; } | { b: string; } +>union : { a: number; } | { b: string; } +>union : { a: number; } | { b: string; } + diff --git a/tests/cases/compiler/restIntersectionOrIntersection.ts b/tests/cases/compiler/restIntersectionOrIntersection.ts new file mode 100644 index 00000000000..6d06ed5ebc2 --- /dev/null +++ b/tests/cases/compiler/restIntersectionOrIntersection.ts @@ -0,0 +1,10 @@ +var intersection: { x: number, y: number } & { w: string, z: string }; +var union: { a: number, c: boolean } | { a: string, b: string }; + + +var rest1: { y: number, w: string, z: string }; +var {x, ...rest1 } = intersection; + +var rest2: { c: boolean } | { b: string }; +var {a, ...rest2 } = union; + diff --git a/tests/cases/compiler/restInvalidArgumentType.ts b/tests/cases/compiler/restInvalidArgumentType.ts new file mode 100644 index 00000000000..7f7037bbb33 --- /dev/null +++ b/tests/cases/compiler/restInvalidArgumentType.ts @@ -0,0 +1,59 @@ +enum E { v1, v2 }; + +function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + 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 num: number; + var str: number; + + 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 + + var {...r6} = mapped_generic; // Error, generic mapped object type + var {...r7} = mapped; // OK, non-generic mapped type + + var {...r8} = union_generic; // Error, union with generic type parameter + 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 {...r12} = num; // Error + var {...r13} = str; // Error + + var {...r14} = u; // Error + var {...r15} = n; // Error + + var {...r16} = a; // OK + + var {...r17} = literal_string; // Error + var {...r18} = literal_number; // Error + + var {...r19} = e; // Error, enum +} \ No newline at end of file diff --git a/tests/cases/compiler/spreadIntersection.ts b/tests/cases/compiler/spreadIntersection.ts new file mode 100644 index 00000000000..3b397dc40cc --- /dev/null +++ b/tests/cases/compiler/spreadIntersection.ts @@ -0,0 +1,7 @@ +var intersection: { a: number } & { b: string }; + +var o1: { a: number, b: string }; +var o1 = { ...intersection }; + +var o2: { a: number, b: string, c: boolean }; +var o2 = { ...intersection, c: false }; \ No newline at end of file diff --git a/tests/cases/compiler/spreadInvalidArgumentType.ts b/tests/cases/compiler/spreadInvalidArgumentType.ts new file mode 100644 index 00000000000..bb8f4894711 --- /dev/null +++ b/tests/cases/compiler/spreadInvalidArgumentType.ts @@ -0,0 +1,59 @@ +enum E { v1, v2 }; + +function f(p1: T, p2: T[]) { + var t: T; + + var i: T["b"]; + var k: keyof T; + + var mapped_generic: {[P in keyof T]: T[P]}; + var mapped: {[P in "b"]: T[P]}; + + 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 num: number; + var str: number; + + 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 + + var o8 = { ...union_generic }; // Error, union with generic type parameter + 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 o12 = { ...num }; // Error + var o13 = { ...str }; // Error + + var o14 = { ...u }; // Error + var o15 = { ...n }; // Error + + var o16 = { ...a }; // OK + + var o17 = { ...literal_string }; // Error + var o18 = { ...literal_number }; // Error + + var o19 = { ...e }; // Error, enum +} \ No newline at end of file diff --git a/tests/cases/compiler/spreadUnion.ts b/tests/cases/compiler/spreadUnion.ts new file mode 100644 index 00000000000..ef8440122ed --- /dev/null +++ b/tests/cases/compiler/spreadUnion.ts @@ -0,0 +1,10 @@ +var union: { a: number } | { b: string }; + +var o3: { a: number } | { b: string }; +var o3 = { ...union }; + +var o4: { a: boolean } | { b: string , a: boolean}; +var o4 = { ...union, a: false }; + +var o5: { a: number } | { b: string } | { a: number, b: string }; +var o5 = { ...union, ...union }; \ No newline at end of file