Error: Property is overwritten by later spread

Move the checking from JSX to getSpreadType so that normal objects get
the error too.

Also reword the missing semicolon related error to be less silly.
This commit is contained in:
Nathan Shively-Sanders 2018-10-09 15:11:21 -07:00
parent 53906f222f
commit b5fc5c0ed8
26 changed files with 781 additions and 550 deletions

View file

@ -9861,6 +9861,9 @@ namespace ts {
result.nameType = leftProp.nameType;
members.set(leftProp.escapedName, result);
}
else if (symbol && shouldCheckAsExcessProperty(leftProp, symbol) && !shouldCheckAsExcessProperty(rightProp, symbol)) {
error(leftProp.valueDeclaration, Diagnostics._0_is_overwritten_by_a_later_spread, unescapeLeadingUnderscores(leftProp.escapedName));
}
}
else {
members.set(leftProp.escapedName, getNonReadonlySymbol(leftProp));
@ -11547,7 +11550,7 @@ namespace ts {
return hasExcessProperties(source, discriminant, /*discriminant*/ undefined, reportErrors);
}
for (const prop of getPropertiesOfObjectType(source)) {
if (!isPropertyFromSpread(prop, source.symbol) && !isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
if (shouldCheckAsExcessProperty(prop, source.symbol) && !isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
if (reportErrors) {
// We know *exactly* where things went wrong when comparing the types.
// Use this property as the error node as this will be more helpful in
@ -11591,10 +11594,6 @@ namespace ts {
return false;
}
function isPropertyFromSpread(prop: Symbol, container: Symbol) {
return prop.valueDeclaration && container.valueDeclaration && prop.valueDeclaration.parent !== container.valueDeclaration;
}
function eachTypeRelatedToSomeType(source: UnionOrIntersectionType, target: UnionOrIntersectionType): Ternary {
let result = Ternary.True;
const sourceTypes = source.types;
@ -12507,6 +12506,10 @@ namespace ts {
return match || defaultValue;
}
function shouldCheckAsExcessProperty(prop: Symbol, container: Symbol) {
return prop.valueDeclaration && container.valueDeclaration && prop.valueDeclaration.parent === container.valueDeclaration;
}
/**
* A type is 'weak' if it is an object type with at least one optional property
* and no required properties, call/construct signatures or index signatures
@ -17632,7 +17635,6 @@ namespace ts {
let spread: Type = emptyObjectType;
let hasSpreadAnyType = false;
let typeToIntersect: Type | undefined;
let explicitlySpecifyChildrenAttribute = false;
let propagatingFlags: TypeFlags = 0;
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement));
@ -17651,9 +17653,6 @@ namespace ts {
attributeSymbol.type = exprType;
attributeSymbol.target = member;
attributesTable.set(attributeSymbol.escapedName, attributeSymbol);
if (attributeDecl.name.escapedText === jsxChildrenPropertyName) {
explicitlySpecifyChildrenAttribute = true;
}
}
else {
Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute);
@ -17687,13 +17686,6 @@ namespace ts {
const childrenTypes: Type[] = checkJsxChildren(parent, checkMode);
if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") {
// Error if there is a attribute named "children" explicitly specified and children element.
// This is because children element will overwrite the value from attributes.
// Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread.
if (explicitlySpecifyChildrenAttribute) {
error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, unescapeLeadingUnderscores(jsxChildrenPropertyName));
}
const contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes);
const childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
// If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process
@ -20049,7 +20041,7 @@ namespace ts {
if (node.arguments.length === 1 && isTypeAssertion(first(node.arguments))) {
const text = getSourceFileOfNode(node).text;
if (isLineBreak(text.charCodeAt(skipTrivia(text, node.expression.end, /* stopAfterLineBreak */ true) - 1))) {
relatedInformation = createDiagnosticForNode(node.expression, Diagnostics.It_is_highly_likely_that_you_are_missing_a_semicolon);
relatedInformation = createDiagnosticForNode(node.expression, Diagnostics.Are_you_missing_a_semicolon_here);
}
}
invocationError(node, apparentType, SignatureKind.Call, relatedInformation);

View file

@ -2489,10 +2489,14 @@
"category": "Error",
"code": 2733
},
"It is highly likely that you are missing a semicolon.": {
"Are you missing a semicolon here?": {
"category": "Error",
"code": 2734
},
"'{0}' is overwritten by a later spread.": {
"category": "Error",
"code": 2735
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View file

@ -21,19 +21,19 @@ tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.t
(1 as number).toString();
~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
!!! related TS2734 tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts:7:1: It is highly likely that you are missing a semicolon.
!!! related TS2734 tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts:7:1: Are you missing a semicolon here?
foo()
~~~~~~~~
(1 as number).toString();
~~~~~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
!!! related TS2734 tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts:10:1: It is highly likely that you are missing a semicolon.
!!! related TS2734 tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts:10:1: Are you missing a semicolon here?
foo()
~~~~~~~~
(<number>1).toString();
~~~~~~~~~~~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
!!! related TS2734 tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts:13:1: It is highly likely that you are missing a semicolon.
!!! related TS2734 tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts:13:1: Are you missing a semicolon here?

View file

@ -1,4 +1,4 @@
tests/cases/conformance/jsx/file.tsx(12,30): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten.
tests/cases/conformance/jsx/file.tsx(12,46): error TS2735: 'children' is overwritten by a later spread.
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
@ -14,8 +14,8 @@ tests/cases/conformance/jsx/file.tsx(12,30): error TS2710: 'children' are specif
render() {
// Error children are specified twice
return (<InnerButton {...this.props} children="hi">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten.
~~~~~~~~~~~~~
!!! error TS2735: 'children' is overwritten by a later spread.
<div>Hello World</div>
</InnerButton>);
}

View file

@ -1,6 +1,6 @@
tests/cases/conformance/jsx/file.tsx(14,10): error TS2322: Type '{ a: number; b: string; }' is not assignable to type 'Prop'.
Property 'children' is missing in type '{ a: number; b: string; }'.
tests/cases/conformance/jsx/file.tsx(17,11): error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten.
tests/cases/conformance/jsx/file.tsx(17,25): error TS2735: 'children' is overwritten by a later spread.
tests/cases/conformance/jsx/file.tsx(31,6): error TS2322: Type '{ children: (Element | ((name: string) => Element))[]; a: number; b: string; }' is not assignable to type 'Prop'.
Types of property 'children' are incompatible.
Type '(Element | ((name: string) => Element))[]' is not assignable to type 'string | Element'.
@ -44,8 +44,8 @@ tests/cases/conformance/jsx/file.tsx(49,6): error TS2322: Type '{ children: Elem
let k0 =
<Comp a={10} b="hi" children="Random" >
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2710: 'children' are specified twice. The attribute named 'children' will be overwritten.
~~~~~~~~~~~~~~~~~
!!! error TS2735: 'children' is overwritten by a later spread.
hi hi hi!
</Comp>;

View file

@ -1,30 +0,0 @@
tests/cases/compiler/excessPropertyCheckWithSpread.ts(6,3): error TS2345: Argument of type '{ n: number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
Object literal may only specify known properties, and 'n' does not exist in type '{ a: any; }'.
tests/cases/compiler/excessPropertyCheckWithSpread.ts(16,3): error TS2345: Argument of type '{ opt: string | number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
Object literal may only specify known properties, and 'opt' does not exist in type '{ a: any; }'.
==== tests/cases/compiler/excessPropertyCheckWithSpread.ts (2 errors) ====
declare function f({ a: number }): void
interface I {
readonly n: number;
}
declare let i: I;
f({ a: 1, ...i });
~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ n: number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
!!! error TS2345: Object literal may only specify known properties, and 'n' does not exist in type '{ a: any; }'.
interface R {
opt?: number
}
interface L {
opt: string
}
declare let l: L;
declare let r: R;
f({ a: 1, ...l, ...r });
~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ opt: string | number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
!!! error TS2345: Object literal may only specify known properties, and 'opt' does not exist in type '{ a: any; }'.

View file

@ -7,23 +7,14 @@ let addAfter: { a: number, b: string, c: boolean } =
{ ...o, c: false }
let addBefore: { a: number, b: string, c: boolean } =
{ c: false, ...o }
// Note: ignore still changes the order that properties are printed
let ignore: { a: number, b: string } =
{ b: 'ignored', ...o }
let override: { a: number, b: string } =
{ ...o, b: 'override' }
let nested: { a: number, b: boolean, c: string } =
{ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' }
let combined: { a: number, b: string, c: boolean } =
{ ...o, ...o2 }
let combinedBefore: { a: number, b: string, c: boolean } =
{ b: 'ok', ...o, ...o2 }
let combinedMid: { a: number, b: string, c: boolean } =
{ ...o, b: 'ok', ...o2 }
let combinedAfter: { a: number, b: string, c: boolean } =
{ ...o, ...o2, b: 'ok' }
let combinedNested: { a: number, b: boolean, c: string, d: string } =
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
let combinedNestedChangeType: { a: number, b: boolean, c: number } =
{ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 }
let propertyNested: { a: { a: number, b: string } } =
@ -91,8 +82,6 @@ cplus.plus();
// new field's type conflicting with existing field is OK
let changeTypeAfter: { a: string, b: string } =
{ ...o, a: 'wrong type?' }
let changeTypeBefore: { a: number, b: string } =
{ a: 'wrong type?', ...o };
let changeTypeBoth: { a: string, b: number } =
{ ...o, ...swap };
@ -109,8 +98,6 @@ function container(
// 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 }
}
@ -138,15 +125,10 @@ var o2 = { b: 'yes', c: true };
var swap = { a: 'yes', b: -1 };
var addAfter = __assign({}, o, { c: false });
var addBefore = __assign({ c: false }, o);
// Note: ignore still changes the order that properties are printed
var ignore = __assign({ b: 'ignored' }, o);
var override = __assign({}, o, { b: 'override' });
var nested = __assign({}, __assign({ a: 3 }, { b: false, c: 'overriden' }), { c: 'whatever' });
var combined = __assign({}, o, o2);
var combinedBefore = __assign({ b: 'ok' }, o, o2);
var combinedMid = __assign({}, o, { b: 'ok' }, o2);
var combinedAfter = __assign({}, o, o2, { b: 'ok' });
var combinedNested = __assign({}, __assign({ a: 4 }, { b: false, c: 'overriden' }), { d: 'actually new' }, { a: 5, d: 'maybe new' });
var combinedNestedChangeType = __assign({}, __assign({ a: 1 }, { b: false, c: 'overriden' }), { c: -1 });
var propertyNested = { a: __assign({}, o) };
// accessors don't copy the descriptor
@ -196,18 +178,16 @@ var cplus = __assign({}, c, { plus: function () { return this.p + 1; } });
cplus.plus();
// new field's type conflicting with existing field is OK
var changeTypeAfter = __assign({}, o, { a: 'wrong type?' });
var changeTypeBefore = __assign({ a: 'wrong type?' }, o);
var changeTypeBoth = __assign({}, o, swap);
// optional
function container(definiteBoolean, definiteString, optionalString, optionalNumber) {
var _a, _b, _c;
var _a, _b;
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 computedAfter = __assign({}, o, (_b = { b: 'yeah' }, _b['at the end'] = 14, _b));
}
// shortcut syntax
var a = 12;

View file

@ -34,179 +34,161 @@ let addBefore: { a: number, b: string, c: boolean } =
>c : Symbol(c, Decl(objectSpread.ts, 7, 5))
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
// Note: ignore still changes the order that properties are printed
let ignore: { a: number, b: string } =
>ignore : Symbol(ignore, Decl(objectSpread.ts, 9, 3))
>a : Symbol(a, Decl(objectSpread.ts, 9, 13))
>b : Symbol(b, Decl(objectSpread.ts, 9, 24))
{ b: 'ignored', ...o }
>b : Symbol(b, Decl(objectSpread.ts, 10, 5))
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
let override: { a: number, b: string } =
>override : Symbol(override, Decl(objectSpread.ts, 11, 3))
>a : Symbol(a, Decl(objectSpread.ts, 11, 15))
>b : Symbol(b, Decl(objectSpread.ts, 11, 26))
>override : Symbol(override, Decl(objectSpread.ts, 8, 3))
>a : Symbol(a, Decl(objectSpread.ts, 8, 15))
>b : Symbol(b, Decl(objectSpread.ts, 8, 26))
{ ...o, b: 'override' }
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>b : Symbol(b, Decl(objectSpread.ts, 12, 11))
>b : Symbol(b, Decl(objectSpread.ts, 9, 11))
let nested: { a: number, b: boolean, c: string } =
>nested : Symbol(nested, Decl(objectSpread.ts, 13, 3))
>a : Symbol(a, Decl(objectSpread.ts, 13, 13))
>b : Symbol(b, Decl(objectSpread.ts, 13, 24))
>c : Symbol(c, Decl(objectSpread.ts, 13, 36))
>nested : Symbol(nested, Decl(objectSpread.ts, 10, 3))
>a : Symbol(a, Decl(objectSpread.ts, 10, 13))
>b : Symbol(b, Decl(objectSpread.ts, 10, 24))
>c : Symbol(c, Decl(objectSpread.ts, 10, 36))
{ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' }
>a : Symbol(a, Decl(objectSpread.ts, 14, 10))
>b : Symbol(b, Decl(objectSpread.ts, 14, 21))
>c : Symbol(c, Decl(objectSpread.ts, 14, 31))
>c : Symbol(c, Decl(objectSpread.ts, 14, 51))
>a : Symbol(a, Decl(objectSpread.ts, 11, 10))
>b : Symbol(b, Decl(objectSpread.ts, 11, 21))
>c : Symbol(c, Decl(objectSpread.ts, 11, 31))
>c : Symbol(c, Decl(objectSpread.ts, 11, 51))
let combined: { a: number, b: string, c: boolean } =
>combined : Symbol(combined, Decl(objectSpread.ts, 15, 3))
>a : Symbol(a, Decl(objectSpread.ts, 15, 15))
>b : Symbol(b, Decl(objectSpread.ts, 15, 26))
>c : Symbol(c, Decl(objectSpread.ts, 15, 37))
>combined : Symbol(combined, Decl(objectSpread.ts, 12, 3))
>a : Symbol(a, Decl(objectSpread.ts, 12, 15))
>b : Symbol(b, Decl(objectSpread.ts, 12, 26))
>c : Symbol(c, Decl(objectSpread.ts, 12, 37))
{ ...o, ...o2 }
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3))
let combinedBefore: { a: number, b: string, c: boolean } =
>combinedBefore : Symbol(combinedBefore, Decl(objectSpread.ts, 17, 3))
>a : Symbol(a, Decl(objectSpread.ts, 17, 21))
>b : Symbol(b, Decl(objectSpread.ts, 17, 32))
>c : Symbol(c, Decl(objectSpread.ts, 17, 43))
{ b: 'ok', ...o, ...o2 }
>b : Symbol(b, Decl(objectSpread.ts, 18, 5))
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3))
let combinedMid: { a: number, b: string, c: boolean } =
>combinedMid : Symbol(combinedMid, Decl(objectSpread.ts, 19, 3))
>a : Symbol(a, Decl(objectSpread.ts, 19, 18))
>b : Symbol(b, Decl(objectSpread.ts, 19, 29))
>c : Symbol(c, Decl(objectSpread.ts, 19, 40))
{ ...o, b: 'ok', ...o2 }
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>b : Symbol(b, Decl(objectSpread.ts, 20, 11))
>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3))
let combinedAfter: { a: number, b: string, c: boolean } =
>combinedAfter : Symbol(combinedAfter, Decl(objectSpread.ts, 21, 3))
>a : Symbol(a, Decl(objectSpread.ts, 21, 20))
>b : Symbol(b, Decl(objectSpread.ts, 21, 31))
>c : Symbol(c, Decl(objectSpread.ts, 21, 42))
>combinedAfter : Symbol(combinedAfter, Decl(objectSpread.ts, 14, 3))
>a : Symbol(a, Decl(objectSpread.ts, 14, 20))
>b : Symbol(b, Decl(objectSpread.ts, 14, 31))
>c : Symbol(c, Decl(objectSpread.ts, 14, 42))
{ ...o, ...o2, b: 'ok' }
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>o2 : Symbol(o2, Decl(objectSpread.ts, 1, 3))
>b : Symbol(b, Decl(objectSpread.ts, 22, 18))
let combinedNested: { a: number, b: boolean, c: string, d: string } =
>combinedNested : Symbol(combinedNested, Decl(objectSpread.ts, 23, 3))
>a : Symbol(a, Decl(objectSpread.ts, 23, 21))
>b : Symbol(b, Decl(objectSpread.ts, 23, 32))
>c : Symbol(c, Decl(objectSpread.ts, 23, 44))
>d : Symbol(d, Decl(objectSpread.ts, 23, 55))
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
>a : Symbol(a, Decl(objectSpread.ts, 24, 10))
>b : Symbol(b, Decl(objectSpread.ts, 24, 21))
>c : Symbol(c, Decl(objectSpread.ts, 24, 31))
>d : Symbol(d, Decl(objectSpread.ts, 24, 51))
>a : Symbol(a, Decl(objectSpread.ts, 24, 75))
>d : Symbol(d, Decl(objectSpread.ts, 24, 81))
>b : Symbol(b, Decl(objectSpread.ts, 15, 18))
let combinedNestedChangeType: { a: number, b: boolean, c: number } =
>combinedNestedChangeType : Symbol(combinedNestedChangeType, Decl(objectSpread.ts, 25, 3))
>a : Symbol(a, Decl(objectSpread.ts, 25, 31))
>b : Symbol(b, Decl(objectSpread.ts, 25, 42))
>c : Symbol(c, Decl(objectSpread.ts, 25, 54))
>combinedNestedChangeType : Symbol(combinedNestedChangeType, Decl(objectSpread.ts, 16, 3))
>a : Symbol(a, Decl(objectSpread.ts, 16, 31))
>b : Symbol(b, Decl(objectSpread.ts, 16, 42))
>c : Symbol(c, Decl(objectSpread.ts, 16, 54))
{ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 }
>a : Symbol(a, Decl(objectSpread.ts, 26, 10))
>b : Symbol(b, Decl(objectSpread.ts, 26, 21))
>c : Symbol(c, Decl(objectSpread.ts, 26, 31))
>c : Symbol(c, Decl(objectSpread.ts, 26, 51))
>a : Symbol(a, Decl(objectSpread.ts, 17, 10))
>b : Symbol(b, Decl(objectSpread.ts, 17, 21))
>c : Symbol(c, Decl(objectSpread.ts, 17, 31))
>c : Symbol(c, Decl(objectSpread.ts, 17, 51))
let propertyNested: { a: { a: number, b: string } } =
>propertyNested : Symbol(propertyNested, Decl(objectSpread.ts, 27, 3))
>a : Symbol(a, Decl(objectSpread.ts, 27, 21))
>a : Symbol(a, Decl(objectSpread.ts, 27, 26))
>b : Symbol(b, Decl(objectSpread.ts, 27, 37))
>propertyNested : Symbol(propertyNested, Decl(objectSpread.ts, 18, 3))
>a : Symbol(a, Decl(objectSpread.ts, 18, 21))
>a : Symbol(a, Decl(objectSpread.ts, 18, 26))
>b : Symbol(b, Decl(objectSpread.ts, 18, 37))
{ a: { ... o } }
>a : Symbol(a, Decl(objectSpread.ts, 28, 5))
>a : Symbol(a, Decl(objectSpread.ts, 19, 5))
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
// accessors don't copy the descriptor
// (which means that readonly getters become read/write properties)
let op = { get a () { return 6 } };
>op : Symbol(op, Decl(objectSpread.ts, 31, 3))
>a : Symbol(a, Decl(objectSpread.ts, 31, 10))
>op : Symbol(op, Decl(objectSpread.ts, 22, 3))
>a : Symbol(a, Decl(objectSpread.ts, 22, 10))
let getter: { a: number, c: number } =
>getter : Symbol(getter, Decl(objectSpread.ts, 32, 3))
>a : Symbol(a, Decl(objectSpread.ts, 32, 13))
>c : Symbol(c, Decl(objectSpread.ts, 32, 24))
>getter : Symbol(getter, Decl(objectSpread.ts, 23, 3))
>a : Symbol(a, Decl(objectSpread.ts, 23, 13))
>c : Symbol(c, Decl(objectSpread.ts, 23, 24))
{ ...op, c: 7 }
>op : Symbol(op, Decl(objectSpread.ts, 31, 3))
>c : Symbol(c, Decl(objectSpread.ts, 33, 12))
>op : Symbol(op, Decl(objectSpread.ts, 22, 3))
>c : Symbol(c, Decl(objectSpread.ts, 24, 12))
getter.a = 12;
>getter.a : Symbol(a, Decl(objectSpread.ts, 32, 13))
>getter : Symbol(getter, Decl(objectSpread.ts, 32, 3))
>a : Symbol(a, Decl(objectSpread.ts, 32, 13))
>getter.a : Symbol(a, Decl(objectSpread.ts, 23, 13))
>getter : Symbol(getter, Decl(objectSpread.ts, 23, 3))
>a : Symbol(a, Decl(objectSpread.ts, 23, 13))
// functions result in { }
let spreadFunc = { ...(function () { }) };
>spreadFunc : Symbol(spreadFunc, Decl(objectSpread.ts, 37, 3))
>spreadFunc : Symbol(spreadFunc, Decl(objectSpread.ts, 28, 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))
>Header : Symbol(Header, Decl(objectSpread.ts, 28, 42))
>head : Symbol(head, Decl(objectSpread.ts, 30, 15))
>body : Symbol(body, Decl(objectSpread.ts, 30, 29))
>authToken : Symbol(authToken, Decl(objectSpread.ts, 30, 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))
>from16326 : Symbol(from16326, Decl(objectSpread.ts, 30, 63))
>this : Symbol(this, Decl(objectSpread.ts, 31, 19))
>header : Symbol(header, Decl(objectSpread.ts, 31, 26))
>Header : Symbol(Header, Decl(objectSpread.ts, 28, 42))
>header : Symbol(header, Decl(objectSpread.ts, 31, 44))
>Header : Symbol(Header, Decl(objectSpread.ts, 28, 42))
>authToken : Symbol(authToken, Decl(objectSpread.ts, 31, 60))
>Header : Symbol(Header, Decl(objectSpread.ts, 28, 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))
>this.header : Symbol(header, Decl(objectSpread.ts, 31, 26))
>this : Symbol(this, Decl(objectSpread.ts, 31, 19))
>header : Symbol(header, Decl(objectSpread.ts, 31, 26))
...header,
>header : Symbol(header, Decl(objectSpread.ts, 40, 44))
>header : Symbol(header, Decl(objectSpread.ts, 31, 44))
...authToken && { authToken }
>authToken : Symbol(authToken, Decl(objectSpread.ts, 40, 60))
>authToken : Symbol(authToken, Decl(objectSpread.ts, 44, 25))
>authToken : Symbol(authToken, Decl(objectSpread.ts, 31, 60))
>authToken : Symbol(authToken, Decl(objectSpread.ts, 35, 25))
}
}
// boolean && T results in Partial<T>
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))
>conditionalSpreadBoolean : Symbol(conditionalSpreadBoolean, Decl(objectSpread.ts, 37, 1))
>b : Symbol(b, Decl(objectSpread.ts, 39, 34))
>x : Symbol(x, Decl(objectSpread.ts, 39, 49))
>y : Symbol(y, Decl(objectSpread.ts, 39, 60))
let o = { x: 12, y: 13 }
>o : Symbol(o, Decl(objectSpread.ts, 40, 7))
>x : Symbol(x, Decl(objectSpread.ts, 40, 13))
>y : Symbol(y, Decl(objectSpread.ts, 40, 20))
o = {
>o : Symbol(o, Decl(objectSpread.ts, 40, 7))
...o,
>o : Symbol(o, Decl(objectSpread.ts, 40, 7))
...b && { x: 14 }
>b : Symbol(b, Decl(objectSpread.ts, 39, 34))
>x : Symbol(x, Decl(objectSpread.ts, 43, 17))
}
let o2 = { ...b && { x: 21 }}
>o2 : Symbol(o2, Decl(objectSpread.ts, 45, 7))
>b : Symbol(b, Decl(objectSpread.ts, 39, 34))
>x : Symbol(x, Decl(objectSpread.ts, 45, 24))
return o;
>o : Symbol(o, Decl(objectSpread.ts, 40, 7))
}
function conditionalSpreadNumber(nt: number): { x: number, y: number } {
>conditionalSpreadNumber : Symbol(conditionalSpreadNumber, Decl(objectSpread.ts, 47, 1))
>nt : Symbol(nt, Decl(objectSpread.ts, 48, 33))
>x : Symbol(x, Decl(objectSpread.ts, 48, 47))
>y : Symbol(y, Decl(objectSpread.ts, 48, 58))
let o = { x: 15, y: 16 }
>o : Symbol(o, Decl(objectSpread.ts, 49, 7))
>x : Symbol(x, Decl(objectSpread.ts, 49, 13))
>y : Symbol(y, Decl(objectSpread.ts, 49, 20))
@ -217,28 +199,30 @@ function conditionalSpreadBoolean(b: boolean) : { x: number, y: number } {
...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))
...nt && { x: nt }
>nt : Symbol(nt, Decl(objectSpread.ts, 48, 33))
>x : Symbol(x, Decl(objectSpread.ts, 52, 18))
>nt : Symbol(nt, Decl(objectSpread.ts, 48, 33))
}
let o2 = { ...b && { x: 21 }}
let o2 = { ...nt && { x: nt }}
>o2 : Symbol(o2, Decl(objectSpread.ts, 54, 7))
>b : Symbol(b, Decl(objectSpread.ts, 48, 34))
>x : Symbol(x, Decl(objectSpread.ts, 54, 24))
>nt : Symbol(nt, Decl(objectSpread.ts, 48, 33))
>x : Symbol(x, Decl(objectSpread.ts, 54, 25))
>nt : Symbol(nt, Decl(objectSpread.ts, 48, 33))
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))
function conditionalSpreadString(st: string): { x: string, y: number } {
>conditionalSpreadString : Symbol(conditionalSpreadString, Decl(objectSpread.ts, 56, 1))
>st : Symbol(st, 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 }
let o = { x: 'hi', y: 17 }
>o : Symbol(o, Decl(objectSpread.ts, 58, 7))
>x : Symbol(x, Decl(objectSpread.ts, 58, 13))
>y : Symbol(y, Decl(objectSpread.ts, 58, 20))
>y : Symbol(y, Decl(objectSpread.ts, 58, 22))
o = {
>o : Symbol(o, Decl(objectSpread.ts, 58, 7))
@ -246,112 +230,72 @@ function conditionalSpreadNumber(nt: number): { x: number, y: number } {
...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))
>st : Symbol(st, Decl(objectSpread.ts, 57, 33))
>x : Symbol(x, Decl(objectSpread.ts, 61, 18))
>st : Symbol(st, Decl(objectSpread.ts, 57, 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))
>o2 : Symbol(o2, Decl(objectSpread.ts, 63, 7))
>st : Symbol(st, Decl(objectSpread.ts, 57, 33))
>x : Symbol(x, Decl(objectSpread.ts, 63, 25))
>st : Symbol(st, Decl(objectSpread.ts, 57, 33))
return o;
>o : Symbol(o, Decl(objectSpread.ts, 67, 7))
>o : Symbol(o, Decl(objectSpread.ts, 58, 7))
}
// any results in any
let anything: any;
>anything : Symbol(anything, Decl(objectSpread.ts, 77, 3))
>anything : Symbol(anything, Decl(objectSpread.ts, 68, 3))
let spreadAny = { ...anything };
>spreadAny : Symbol(spreadAny, Decl(objectSpread.ts, 78, 3))
>anything : Symbol(anything, Decl(objectSpread.ts, 77, 3))
>spreadAny : Symbol(spreadAny, Decl(objectSpread.ts, 69, 3))
>anything : Symbol(anything, Decl(objectSpread.ts, 68, 3))
// methods are not enumerable
class C { p = 1; m() { } }
>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))
>C : Symbol(C, Decl(objectSpread.ts, 69, 32))
>p : Symbol(C.p, Decl(objectSpread.ts, 72, 9))
>m : Symbol(C.m, Decl(objectSpread.ts, 72, 16))
let c: C = new C()
>c : Symbol(c, Decl(objectSpread.ts, 82, 3))
>C : Symbol(C, Decl(objectSpread.ts, 78, 32))
>C : Symbol(C, Decl(objectSpread.ts, 78, 32))
>c : Symbol(c, Decl(objectSpread.ts, 73, 3))
>C : Symbol(C, Decl(objectSpread.ts, 69, 32))
>C : Symbol(C, Decl(objectSpread.ts, 69, 32))
let spreadC: { p: number } = { ...c }
>spreadC : Symbol(spreadC, Decl(objectSpread.ts, 83, 3))
>p : Symbol(p, Decl(objectSpread.ts, 83, 14))
>c : Symbol(c, Decl(objectSpread.ts, 82, 3))
>spreadC : Symbol(spreadC, Decl(objectSpread.ts, 74, 3))
>p : Symbol(p, Decl(objectSpread.ts, 74, 14))
>c : Symbol(c, Decl(objectSpread.ts, 73, 3))
// own methods are enumerable
let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } };
>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 : Symbol(cplus, Decl(objectSpread.ts, 77, 3))
>p : Symbol(p, Decl(objectSpread.ts, 77, 12))
>plus : Symbol(plus, Decl(objectSpread.ts, 77, 23))
>c : Symbol(c, Decl(objectSpread.ts, 73, 3))
>plus : Symbol(plus, Decl(objectSpread.ts, 77, 48))
cplus.plus();
>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))
>cplus.plus : Symbol(plus, Decl(objectSpread.ts, 77, 23))
>cplus : Symbol(cplus, Decl(objectSpread.ts, 77, 3))
>plus : Symbol(plus, Decl(objectSpread.ts, 77, 23))
// new field's type conflicting with existing field is OK
let changeTypeAfter: { a: string, b: string } =
>changeTypeAfter : Symbol(changeTypeAfter, Decl(objectSpread.ts, 90, 3))
>a : Symbol(a, Decl(objectSpread.ts, 90, 22))
>b : Symbol(b, Decl(objectSpread.ts, 90, 33))
>changeTypeAfter : Symbol(changeTypeAfter, Decl(objectSpread.ts, 81, 3))
>a : Symbol(a, Decl(objectSpread.ts, 81, 22))
>b : Symbol(b, Decl(objectSpread.ts, 81, 33))
{ ...o, a: 'wrong type?' }
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>a : Symbol(a, Decl(objectSpread.ts, 91, 11))
let changeTypeBefore: { a: number, b: string } =
>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, 93, 5))
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>a : Symbol(a, Decl(objectSpread.ts, 82, 11))
let changeTypeBoth: { a: string, b: number } =
>changeTypeBoth : Symbol(changeTypeBoth, Decl(objectSpread.ts, 94, 3))
>a : Symbol(a, Decl(objectSpread.ts, 94, 21))
>b : Symbol(b, Decl(objectSpread.ts, 94, 32))
>changeTypeBoth : Symbol(changeTypeBoth, Decl(objectSpread.ts, 83, 3))
>a : Symbol(a, Decl(objectSpread.ts, 83, 21))
>b : Symbol(b, Decl(objectSpread.ts, 83, 32))
{ ...o, ...swap };
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
@ -359,96 +303,82 @@ let changeTypeBoth: { a: string, b: number } =
// optional
function container(
>container : Symbol(container, Decl(objectSpread.ts, 95, 22))
>container : Symbol(container, Decl(objectSpread.ts, 84, 22))
definiteBoolean: { sn: boolean },
>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 98, 19))
>sn : Symbol(sn, Decl(objectSpread.ts, 99, 22))
>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 87, 19))
>sn : Symbol(sn, Decl(objectSpread.ts, 88, 22))
definiteString: { sn: string },
>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 99, 37))
>sn : Symbol(sn, Decl(objectSpread.ts, 100, 21))
>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 88, 37))
>sn : Symbol(sn, Decl(objectSpread.ts, 89, 21))
optionalString: { sn?: string },
>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 100, 35))
>sn : Symbol(sn, Decl(objectSpread.ts, 101, 21))
>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 89, 35))
>sn : Symbol(sn, Decl(objectSpread.ts, 90, 21))
optionalNumber: { sn?: number }) {
>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 101, 36))
>sn : Symbol(sn, Decl(objectSpread.ts, 102, 21))
>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 90, 36))
>sn : Symbol(sn, Decl(objectSpread.ts, 91, 21))
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))
>optionalUnionStops : Symbol(optionalUnionStops, Decl(objectSpread.ts, 92, 7))
>sn : Symbol(sn, Decl(objectSpread.ts, 92, 29))
>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 87, 19))
>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 88, 37))
>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 90, 36))
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))
>optionalUnionDuplicates : Symbol(optionalUnionDuplicates, Decl(objectSpread.ts, 93, 7))
>sn : Symbol(sn, Decl(objectSpread.ts, 93, 34))
>definiteBoolean : Symbol(definiteBoolean, Decl(objectSpread.ts, 87, 19))
>definiteString : Symbol(definiteString, Decl(objectSpread.ts, 88, 37))
>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 89, 35))
>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 90, 36))
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))
>allOptional : Symbol(allOptional, Decl(objectSpread.ts, 94, 7))
>sn : Symbol(sn, Decl(objectSpread.ts, 94, 22))
>optionalString : Symbol(optionalString, Decl(objectSpread.ts, 89, 35))
>optionalNumber : Symbol(optionalNumber, Decl(objectSpread.ts, 90, 36))
// 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" : Symbol("before everything", Decl(objectSpread.ts, 108, 46))
>computedFirst : Symbol(computedFirst, Decl(objectSpread.ts, 97, 7))
>a : Symbol(a, Decl(objectSpread.ts, 97, 24))
>b : Symbol(b, Decl(objectSpread.ts, 97, 35))
>"before everything" : Symbol("before everything", Decl(objectSpread.ts, 97, 46))
{ ['before everything']: 12, ...o, b: 'yes' }
>['before everything'] : Symbol(['before everything'], Decl(objectSpread.ts, 109, 9))
>'before everything' : Symbol(['before everything'], Decl(objectSpread.ts, 109, 9))
>['before everything'] : Symbol(['before everything'], Decl(objectSpread.ts, 98, 9))
>'before everything' : Symbol(['before everything'], Decl(objectSpread.ts, 98, 9))
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>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, 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))
>"in the middle" : Symbol("in the middle", Decl(objectSpread.ts, 110, 59))
{ ...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, 111, 15))
>'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))
>b : Symbol(b, Decl(objectSpread.ts, 98, 42))
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))
>"at the end" : Symbol("at the end", Decl(objectSpread.ts, 112, 46))
>computedAfter : Symbol(computedAfter, Decl(objectSpread.ts, 99, 7))
>a : Symbol(a, Decl(objectSpread.ts, 99, 24))
>b : Symbol(b, Decl(objectSpread.ts, 99, 35))
>"at the end" : Symbol("at the end", Decl(objectSpread.ts, 99, 46))
{ ...o, b: 'yeah', ['at the end']: 14 }
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>b : Symbol(b, Decl(objectSpread.ts, 113, 15))
>['at the end'] : Symbol(['at the end'], Decl(objectSpread.ts, 113, 26))
>'at the end' : Symbol(['at the end'], Decl(objectSpread.ts, 113, 26))
>b : Symbol(b, Decl(objectSpread.ts, 100, 15))
>['at the end'] : Symbol(['at the end'], Decl(objectSpread.ts, 100, 26))
>'at the end' : Symbol(['at the end'], Decl(objectSpread.ts, 100, 26))
}
// shortcut syntax
let a = 12;
>a : Symbol(a, Decl(objectSpread.ts, 116, 3))
>a : Symbol(a, Decl(objectSpread.ts, 103, 3))
let shortCutted: { a: number, b: string } = { ...o, a }
>shortCutted : Symbol(shortCutted, Decl(objectSpread.ts, 117, 3))
>a : Symbol(a, Decl(objectSpread.ts, 117, 18))
>b : Symbol(b, Decl(objectSpread.ts, 117, 29))
>shortCutted : Symbol(shortCutted, Decl(objectSpread.ts, 104, 3))
>a : Symbol(a, Decl(objectSpread.ts, 104, 18))
>b : Symbol(b, Decl(objectSpread.ts, 104, 29))
>o : Symbol(o, Decl(objectSpread.ts, 0, 3))
>a : Symbol(a, Decl(objectSpread.ts, 117, 51))
>a : Symbol(a, Decl(objectSpread.ts, 104, 51))
// non primitive
let spreadNonPrimitive = { ...<object>{}};
>spreadNonPrimitive : Symbol(spreadNonPrimitive, Decl(objectSpread.ts, 119, 3))
>spreadNonPrimitive : Symbol(spreadNonPrimitive, Decl(objectSpread.ts, 106, 3))

View file

@ -48,18 +48,6 @@ let addBefore: { a: number, b: string, c: boolean } =
>false : false
>o : { a: number; b: string; }
// Note: ignore still changes the order that properties are printed
let ignore: { a: number, b: string } =
>ignore : { a: number; b: string; }
>a : number
>b : string
{ b: 'ignored', ...o }
>{ b: 'ignored', ...o } : { a: number; b: string; }
>b : string
>'ignored' : "ignored"
>o : { a: number; b: string; }
let override: { a: number, b: string } =
>override : { a: number; b: string; }
>a : number
@ -101,32 +89,6 @@ let combined: { a: number, b: string, c: boolean } =
>o : { a: number; b: string; }
>o2 : { b: string; c: boolean; }
let combinedBefore: { a: number, b: string, c: boolean } =
>combinedBefore : { a: number; b: string; c: boolean; }
>a : number
>b : string
>c : boolean
{ b: 'ok', ...o, ...o2 }
>{ b: 'ok', ...o, ...o2 } : { b: string; c: boolean; a: number; }
>b : string
>'ok' : "ok"
>o : { a: number; b: string; }
>o2 : { b: string; c: boolean; }
let combinedMid: { a: number, b: string, c: boolean } =
>combinedMid : { a: number; b: string; c: boolean; }
>a : number
>b : string
>c : boolean
{ ...o, b: 'ok', ...o2 }
>{ ...o, b: 'ok', ...o2 } : { b: string; c: boolean; a: number; }
>o : { a: number; b: string; }
>b : string
>'ok' : "ok"
>o2 : { b: string; c: boolean; }
let combinedAfter: { a: number, b: string, c: boolean } =
>combinedAfter : { a: number; b: string; c: boolean; }
>a : number
@ -140,31 +102,6 @@ let combinedAfter: { a: number, b: string, c: boolean } =
>b : string
>'ok' : "ok"
let combinedNested: { a: number, b: boolean, c: string, d: string } =
>combinedNested : { a: number; b: boolean; c: string; d: string; }
>a : number
>b : boolean
>c : string
>d : string
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
>{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } : { a: number; d: string; b: false; c: string; }
>{ a: 4, ...{ b: false, c: 'overriden' } } : { b: false; c: string; a: number; }
>a : number
>4 : 4
>{ b: false, c: 'overriden' } : { b: false; c: string; }
>b : false
>false : false
>c : string
>'overriden' : "overriden"
>d : string
>'actually new' : "actually new"
>{ a: 5, d: 'maybe new' } : { a: number; d: string; }
>a : number
>5 : 5
>d : string
>'maybe new' : "maybe new"
let combinedNestedChangeType: { a: number, b: boolean, c: number } =
>combinedNestedChangeType : { a: number; b: boolean; c: number; }
>a : number
@ -445,17 +382,6 @@ let changeTypeAfter: { a: string, b: string } =
>a : string
>'wrong type?' : "wrong type?"
let changeTypeBefore: { a: number, b: string } =
>changeTypeBefore : { a: number; b: string; }
>a : number
>b : string
{ a: 'wrong type?', ...o };
>{ a: 'wrong type?', ...o } : { a: number; b: string; }
>a : string
>'wrong type?' : "wrong type?"
>o : { a: number; b: string; }
let changeTypeBoth: { a: string, b: number } =
>changeTypeBoth : { a: string; b: number; }
>a : string
@ -526,23 +452,6 @@ function container(
>b : string
>'yes' : "yes"
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
>"in the middle" : number
{ ...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'] : number
>'in the middle' : "in the middle"
>13 : 13
>b : string
>'maybe?' : "maybe?"
>o2 : { b: string; c: boolean; }
let computedAfter: { a: number, b: string, "at the end": number } =
>computedAfter : { a: number; b: string; "at the end": number; }
>a : number

View file

@ -5,22 +5,29 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(23,1): error TS2322
Property 'b' is missing in type '{ s: string; }'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(25,1): error TS2322: Type '{ b: boolean; }' is not assignable to type '{ s: string; b: boolean; }'.
Property 's' is missing in type '{ b: boolean; }'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(28,36): error TS2300: Duplicate identifier 'b'.
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(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 '{}'.
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(27,20): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(27,36): error TS2300: Duplicate identifier 'b'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(27,53): error TS2300: Duplicate identifier 'b'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(31,7): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(36,7): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(38,14): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(40,53): error TS2735: 'd' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(42,7): error TS2735: 'a' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(44,37): error TS2735: 'b' is overwritten by a later spread.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(47,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(48,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(49,20): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(51,20): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(53,19): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(58,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(62,12): error TS2339: Property 'b' does not exist on type '{}'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(68,9): error TS2339: Property 'm' does not exist on type '{ p: number; }'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(73,11): error TS2339: Property 'a' does not exist on type '{}'.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(77,14): error TS2698: Spread types may only be created from object types.
tests/cases/conformance/types/spread/objectSpreadNegative.ts(80,14): error TS2698: Spread types may only be created from object types.
==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (17 errors) ====
==== tests/cases/conformance/types/spread/objectSpreadNegative.ts (24 errors) ====
let o = { a: 1, b: 'no' }
/// private propagates
@ -58,13 +65,42 @@ tests/cases/conformance/types/spread/objectSpreadNegative.ts(65,14): error TS269
!!! error TS2322: Type '{ b: boolean; }' is not assignable to type '{ s: string; b: boolean; }'.
!!! error TS2322: Property 's' is missing in type '{ b: boolean; }'.
// literal repeats are not allowed, but spread repeats are fine
let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
~~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
~
!!! error TS2300: Duplicate identifier 'b'.
~
!!! error TS2300: Duplicate identifier 'b'.
let duplicatedSpread = { ...o, ...o }
// Note: ignore changes the order that properties are printed
let ignore: { a: number, b: string } =
{ b: 'ignored', ...o }
~~~~~~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
let o3 = { a: 1, b: 'no' }
let o4 = { b: 'yes', c: true }
let combinedBefore: { a: number, b: string, c: boolean } =
{ b: 'ok', ...o3, ...o4 }
~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
let combinedMid: { a: number, b: string, c: boolean } =
{ ...o3, b: 'ok', ...o4 }
~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
let combinedNested: { a: number, b: boolean, c: string, d: string } =
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
~~~~~~~~~~~~~~~~~
!!! error TS2735: 'd' is overwritten by a later spread.
let changeTypeBefore: { a: number, b: string } =
{ a: 'wrong type?', ...o3 };
~~~~~~~~~~~~~~~~
!!! error TS2735: 'a' is overwritten by a later spread.
let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } =
{ ...o3, ['in the middle']: 13, b: 'maybe?', ...o4 }
~~~~~~~~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
// primitives are not allowed, except for falsy ones
let spreadNum = { ...12 };

View file

@ -25,9 +25,24 @@ spread = { s: "foo" }; // error, missing 'b'
let b = { b: false };
spread = b; // error, missing 's'
// literal repeats are not allowed, but spread repeats are fine
let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
let duplicatedSpread = { ...o, ...o }
// Note: ignore changes the order that properties are printed
let ignore: { a: number, b: string } =
{ b: 'ignored', ...o }
let o3 = { a: 1, b: 'no' }
let o4 = { b: 'yes', c: true }
let combinedBefore: { a: number, b: string, c: boolean } =
{ b: 'ok', ...o3, ...o4 }
let combinedMid: { a: number, b: string, c: boolean } =
{ ...o3, b: 'ok', ...o4 }
let combinedNested: { a: number, b: boolean, c: string, d: string } =
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
let changeTypeBefore: { a: number, b: string } =
{ a: 'wrong type?', ...o3 };
let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } =
{ ...o3, ['in the middle']: 13, b: 'maybe?', ...o4 }
// primitives are not allowed, except for falsy ones
let spreadNum = { ...12 };
@ -87,6 +102,7 @@ var __assign = (this && this.__assign) || function () {
};
return __assign.apply(this, arguments);
};
var _a;
var o = { a: 1, b: 'no' };
/// private propagates
var PrivateOptionalX = /** @class */ (function () {
@ -112,9 +128,17 @@ var spread = __assign({ b: true }, { s: "foo" });
spread = { s: "foo" }; // error, missing 'b'
var b = { b: false };
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);
// Note: ignore changes the order that properties are printed
var ignore = __assign({ b: 'ignored' }, o);
var o3 = { a: 1, b: 'no' };
var o4 = { b: 'yes', c: true };
var combinedBefore = __assign({ b: 'ok' }, o3, o4);
var combinedMid = __assign({}, o3, { b: 'ok' }, o4);
var combinedNested = __assign({}, __assign({ a: 4 }, { b: false, c: 'overriden' }), { d: 'actually new' }, { a: 5, d: 'maybe new' });
var changeTypeBefore = __assign({ a: 'wrong type?' }, o3);
var computedMiddle = __assign({}, o3, (_a = {}, _a['in the middle'] = 13, _a.b = 'maybe?', _a), o4);
// primitives are not allowed, except for falsy ones
var spreadNum = __assign({}, 12);
var spreadSum = __assign({}, 1 + 1);

View file

@ -76,170 +76,249 @@ spread = b; // error, missing 's'
>spread : Symbol(spread, Decl(objectSpreadNegative.ts, 21, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 23, 3))
// literal repeats are not allowed, but spread repeats are fine
let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
>duplicated : Symbol(duplicated, Decl(objectSpreadNegative.ts, 27, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 27, 18), Decl(objectSpreadNegative.ts, 27, 34), Decl(objectSpreadNegative.ts, 27, 51))
>duplicated : Symbol(duplicated, Decl(objectSpreadNegative.ts, 26, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 26, 18), Decl(objectSpreadNegative.ts, 26, 34), Decl(objectSpreadNegative.ts, 26, 51))
>o : Symbol(o, Decl(objectSpreadNegative.ts, 0, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 27, 18), Decl(objectSpreadNegative.ts, 27, 34), Decl(objectSpreadNegative.ts, 27, 51))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 26, 18), Decl(objectSpreadNegative.ts, 26, 34), Decl(objectSpreadNegative.ts, 26, 51))
>o2 : Symbol(o2, Decl(objectSpreadNegative.ts, 11, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 27, 18), Decl(objectSpreadNegative.ts, 27, 34), Decl(objectSpreadNegative.ts, 27, 51))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 26, 18), Decl(objectSpreadNegative.ts, 26, 34), Decl(objectSpreadNegative.ts, 26, 51))
let duplicatedSpread = { ...o, ...o }
>duplicatedSpread : Symbol(duplicatedSpread, Decl(objectSpreadNegative.ts, 28, 3))
>duplicatedSpread : Symbol(duplicatedSpread, Decl(objectSpreadNegative.ts, 27, 3))
>o : Symbol(o, Decl(objectSpreadNegative.ts, 0, 3))
>o : Symbol(o, Decl(objectSpreadNegative.ts, 0, 3))
// Note: ignore changes the order that properties are printed
let ignore: { a: number, b: string } =
>ignore : Symbol(ignore, Decl(objectSpreadNegative.ts, 29, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 29, 13))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 29, 24))
{ b: 'ignored', ...o }
>b : Symbol(b, Decl(objectSpreadNegative.ts, 30, 5))
>o : Symbol(o, Decl(objectSpreadNegative.ts, 0, 3))
let o3 = { a: 1, b: 'no' }
>o3 : Symbol(o3, Decl(objectSpreadNegative.ts, 32, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 32, 10))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 32, 16))
let o4 = { b: 'yes', c: true }
>o4 : Symbol(o4, Decl(objectSpreadNegative.ts, 33, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 33, 10))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 33, 20))
let combinedBefore: { a: number, b: string, c: boolean } =
>combinedBefore : Symbol(combinedBefore, Decl(objectSpreadNegative.ts, 34, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 34, 21))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 34, 32))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 34, 43))
{ b: 'ok', ...o3, ...o4 }
>b : Symbol(b, Decl(objectSpreadNegative.ts, 35, 5))
>o3 : Symbol(o3, Decl(objectSpreadNegative.ts, 32, 3))
>o4 : Symbol(o4, Decl(objectSpreadNegative.ts, 33, 3))
let combinedMid: { a: number, b: string, c: boolean } =
>combinedMid : Symbol(combinedMid, Decl(objectSpreadNegative.ts, 36, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 36, 18))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 36, 29))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 36, 40))
{ ...o3, b: 'ok', ...o4 }
>o3 : Symbol(o3, Decl(objectSpreadNegative.ts, 32, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 37, 12))
>o4 : Symbol(o4, Decl(objectSpreadNegative.ts, 33, 3))
let combinedNested: { a: number, b: boolean, c: string, d: string } =
>combinedNested : Symbol(combinedNested, Decl(objectSpreadNegative.ts, 38, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 38, 21))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 38, 32))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 38, 44))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 38, 55))
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
>a : Symbol(a, Decl(objectSpreadNegative.ts, 39, 10))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 39, 21))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 39, 31))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 39, 51))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 39, 75))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 39, 81))
let changeTypeBefore: { a: number, b: string } =
>changeTypeBefore : Symbol(changeTypeBefore, Decl(objectSpreadNegative.ts, 40, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 40, 23))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 40, 34))
{ a: 'wrong type?', ...o3 };
>a : Symbol(a, Decl(objectSpreadNegative.ts, 41, 5))
>o3 : Symbol(o3, Decl(objectSpreadNegative.ts, 32, 3))
let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } =
>computedMiddle : Symbol(computedMiddle, Decl(objectSpreadNegative.ts, 42, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 42, 21))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 42, 32))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 42, 43))
>"in the middle" : Symbol("in the middle", Decl(objectSpreadNegative.ts, 42, 55))
{ ...o3, ['in the middle']: 13, b: 'maybe?', ...o4 }
>o3 : Symbol(o3, Decl(objectSpreadNegative.ts, 32, 3))
>['in the middle'] : Symbol(['in the middle'], Decl(objectSpreadNegative.ts, 43, 12))
>'in the middle' : Symbol(['in the middle'], Decl(objectSpreadNegative.ts, 43, 12))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 43, 35))
>o4 : Symbol(o4, Decl(objectSpreadNegative.ts, 33, 3))
// primitives are not allowed, except for falsy ones
let spreadNum = { ...12 };
>spreadNum : Symbol(spreadNum, Decl(objectSpreadNegative.ts, 31, 3))
>spreadNum : Symbol(spreadNum, Decl(objectSpreadNegative.ts, 46, 3))
let spreadSum = { ...1 + 1 };
>spreadSum : Symbol(spreadSum, Decl(objectSpreadNegative.ts, 32, 3))
>spreadSum : Symbol(spreadSum, Decl(objectSpreadNegative.ts, 47, 3))
let spreadZero = { ...0 };
>spreadZero : Symbol(spreadZero, Decl(objectSpreadNegative.ts, 33, 3))
>spreadZero : Symbol(spreadZero, Decl(objectSpreadNegative.ts, 48, 3))
spreadZero.toFixed(); // error, no methods even from a falsy number
>spreadZero : Symbol(spreadZero, Decl(objectSpreadNegative.ts, 33, 3))
>spreadZero : Symbol(spreadZero, Decl(objectSpreadNegative.ts, 48, 3))
let spreadBool = { ...true };
>spreadBool : Symbol(spreadBool, Decl(objectSpreadNegative.ts, 35, 3))
>spreadBool : Symbol(spreadBool, Decl(objectSpreadNegative.ts, 50, 3))
spreadBool.valueOf();
>spreadBool : Symbol(spreadBool, Decl(objectSpreadNegative.ts, 35, 3))
>spreadBool : Symbol(spreadBool, Decl(objectSpreadNegative.ts, 50, 3))
let spreadStr = { ...'foo' };
>spreadStr : Symbol(spreadStr, Decl(objectSpreadNegative.ts, 37, 3))
>spreadStr : Symbol(spreadStr, Decl(objectSpreadNegative.ts, 52, 3))
spreadStr.length; // error, no 'length'
>spreadStr : Symbol(spreadStr, Decl(objectSpreadNegative.ts, 37, 3))
>spreadStr : Symbol(spreadStr, Decl(objectSpreadNegative.ts, 52, 3))
spreadStr.charAt(1); // error, no methods either
>spreadStr : Symbol(spreadStr, Decl(objectSpreadNegative.ts, 37, 3))
>spreadStr : Symbol(spreadStr, Decl(objectSpreadNegative.ts, 52, 3))
// functions are skipped
let spreadFunc = { ...function () { } }
>spreadFunc : Symbol(spreadFunc, Decl(objectSpreadNegative.ts, 41, 3))
>spreadFunc : Symbol(spreadFunc, Decl(objectSpreadNegative.ts, 56, 3))
spreadFunc(); // error, no call signature
>spreadFunc : Symbol(spreadFunc, Decl(objectSpreadNegative.ts, 41, 3))
>spreadFunc : Symbol(spreadFunc, Decl(objectSpreadNegative.ts, 56, 3))
// write-only properties get skipped
let setterOnly = { ...{ set b (bad: number) { } } };
>setterOnly : Symbol(setterOnly, Decl(objectSpreadNegative.ts, 45, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 45, 23))
>bad : Symbol(bad, Decl(objectSpreadNegative.ts, 45, 31))
>setterOnly : Symbol(setterOnly, Decl(objectSpreadNegative.ts, 60, 3))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 60, 23))
>bad : Symbol(bad, Decl(objectSpreadNegative.ts, 60, 31))
setterOnly.b = 12; // error, 'b' does not exist
>setterOnly : Symbol(setterOnly, Decl(objectSpreadNegative.ts, 45, 3))
>setterOnly : Symbol(setterOnly, Decl(objectSpreadNegative.ts, 60, 3))
// methods are skipped because they aren't enumerable
class C { p = 1; m() { } }
>C : Symbol(C, Decl(objectSpreadNegative.ts, 46, 18))
>p : Symbol(C.p, Decl(objectSpreadNegative.ts, 49, 9))
>m : Symbol(C.m, Decl(objectSpreadNegative.ts, 49, 16))
>C : Symbol(C, Decl(objectSpreadNegative.ts, 61, 18))
>p : Symbol(C.p, Decl(objectSpreadNegative.ts, 64, 9))
>m : Symbol(C.m, Decl(objectSpreadNegative.ts, 64, 16))
let c: C = new C()
>c : Symbol(c, Decl(objectSpreadNegative.ts, 50, 3))
>C : Symbol(C, Decl(objectSpreadNegative.ts, 46, 18))
>C : Symbol(C, Decl(objectSpreadNegative.ts, 46, 18))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 65, 3))
>C : Symbol(C, Decl(objectSpreadNegative.ts, 61, 18))
>C : Symbol(C, Decl(objectSpreadNegative.ts, 61, 18))
let spreadC = { ...c }
>spreadC : Symbol(spreadC, Decl(objectSpreadNegative.ts, 51, 3))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 50, 3))
>spreadC : Symbol(spreadC, Decl(objectSpreadNegative.ts, 66, 3))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 65, 3))
spreadC.m(); // error 'm' is not in '{ ... c }'
>spreadC : Symbol(spreadC, Decl(objectSpreadNegative.ts, 51, 3))
>spreadC : Symbol(spreadC, Decl(objectSpreadNegative.ts, 66, 3))
// non primitive
let obj: object = { a: 123 };
>obj : Symbol(obj, Decl(objectSpreadNegative.ts, 55, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 55, 19))
>obj : Symbol(obj, Decl(objectSpreadNegative.ts, 70, 3))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 70, 19))
let spreadObj = { ...obj };
>spreadObj : Symbol(spreadObj, Decl(objectSpreadNegative.ts, 56, 3))
>obj : Symbol(obj, Decl(objectSpreadNegative.ts, 55, 3))
>spreadObj : Symbol(spreadObj, Decl(objectSpreadNegative.ts, 71, 3))
>obj : Symbol(obj, Decl(objectSpreadNegative.ts, 70, 3))
spreadObj.a; // error 'a' is not in {}
>spreadObj : Symbol(spreadObj, Decl(objectSpreadNegative.ts, 56, 3))
>spreadObj : Symbol(spreadObj, Decl(objectSpreadNegative.ts, 71, 3))
// generics
function f<T, U>(t: T, u: U) {
>f : Symbol(f, Decl(objectSpreadNegative.ts, 57, 12))
>T : Symbol(T, Decl(objectSpreadNegative.ts, 60, 11))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 60, 13))
>t : Symbol(t, Decl(objectSpreadNegative.ts, 60, 17))
>T : Symbol(T, Decl(objectSpreadNegative.ts, 60, 11))
>u : Symbol(u, Decl(objectSpreadNegative.ts, 60, 22))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 60, 13))
>f : Symbol(f, Decl(objectSpreadNegative.ts, 72, 12))
>T : Symbol(T, Decl(objectSpreadNegative.ts, 75, 11))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 75, 13))
>t : Symbol(t, Decl(objectSpreadNegative.ts, 75, 17))
>T : Symbol(T, Decl(objectSpreadNegative.ts, 75, 11))
>u : Symbol(u, Decl(objectSpreadNegative.ts, 75, 22))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 75, 13))
return { ...t, ...u, id: 'id' };
>t : Symbol(t, Decl(objectSpreadNegative.ts, 60, 17))
>u : Symbol(u, Decl(objectSpreadNegative.ts, 60, 22))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 61, 24))
>t : Symbol(t, Decl(objectSpreadNegative.ts, 75, 17))
>u : Symbol(u, Decl(objectSpreadNegative.ts, 75, 22))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 76, 24))
}
function override<U>(initial: U, override: U): U {
>override : Symbol(override, Decl(objectSpreadNegative.ts, 62, 1))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 63, 18))
>initial : Symbol(initial, Decl(objectSpreadNegative.ts, 63, 21))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 63, 18))
>override : Symbol(override, Decl(objectSpreadNegative.ts, 63, 32))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 63, 18))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 63, 18))
>override : Symbol(override, Decl(objectSpreadNegative.ts, 77, 1))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 78, 18))
>initial : Symbol(initial, Decl(objectSpreadNegative.ts, 78, 21))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 78, 18))
>override : Symbol(override, Decl(objectSpreadNegative.ts, 78, 32))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 78, 18))
>U : Symbol(U, Decl(objectSpreadNegative.ts, 78, 18))
return { ...initial, ...override };
>initial : Symbol(initial, Decl(objectSpreadNegative.ts, 63, 21))
>override : Symbol(override, Decl(objectSpreadNegative.ts, 63, 32))
>initial : Symbol(initial, Decl(objectSpreadNegative.ts, 78, 21))
>override : Symbol(override, Decl(objectSpreadNegative.ts, 78, 32))
}
let exclusive: { id: string, a: number, b: string, c: string, d: boolean } =
>exclusive : Symbol(exclusive, Decl(objectSpreadNegative.ts, 66, 3))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 66, 16))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 66, 28))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 66, 39))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 66, 50))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 66, 61))
>exclusive : Symbol(exclusive, Decl(objectSpreadNegative.ts, 81, 3))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 81, 16))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 81, 28))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 81, 39))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 81, 50))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 81, 61))
f({ a: 1, b: 'yes' }, { c: 'no', d: false })
>f : Symbol(f, Decl(objectSpreadNegative.ts, 57, 12))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 67, 7))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 67, 13))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 67, 27))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 67, 36))
>f : Symbol(f, Decl(objectSpreadNegative.ts, 72, 12))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 82, 7))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 82, 13))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 82, 27))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 82, 36))
let overlap: { id: string, a: number, b: string } =
>overlap : Symbol(overlap, Decl(objectSpreadNegative.ts, 68, 3))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 68, 14))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 68, 26))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 68, 37))
>overlap : Symbol(overlap, Decl(objectSpreadNegative.ts, 83, 3))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 83, 14))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 83, 26))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 83, 37))
f({ a: 1 }, { a: 2, b: 'extra' })
>f : Symbol(f, Decl(objectSpreadNegative.ts, 57, 12))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 69, 7))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 69, 17))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 69, 23))
>f : Symbol(f, Decl(objectSpreadNegative.ts, 72, 12))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 84, 7))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 84, 17))
>b : Symbol(b, Decl(objectSpreadNegative.ts, 84, 23))
let overlapConflict: { id:string, a: string } =
>overlapConflict : Symbol(overlapConflict, Decl(objectSpreadNegative.ts, 70, 3))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 70, 22))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 70, 33))
>overlapConflict : Symbol(overlapConflict, Decl(objectSpreadNegative.ts, 85, 3))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 85, 22))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 85, 33))
f({ a: 1 }, { a: 'mismatch' })
>f : Symbol(f, Decl(objectSpreadNegative.ts, 57, 12))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 71, 7))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 71, 17))
>f : Symbol(f, Decl(objectSpreadNegative.ts, 72, 12))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 86, 7))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 86, 17))
let overwriteId: { id: string, a: number, c: number, d: string } =
>overwriteId : Symbol(overwriteId, Decl(objectSpreadNegative.ts, 72, 3))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 72, 18))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 72, 30))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 72, 41))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 72, 52))
>overwriteId : Symbol(overwriteId, Decl(objectSpreadNegative.ts, 87, 3))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 87, 18))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 87, 30))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 87, 41))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 87, 52))
f({ a: 1, id: true }, { c: 1, d: 'no' })
>f : Symbol(f, Decl(objectSpreadNegative.ts, 57, 12))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 73, 7))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 73, 13))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 73, 27))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 73, 33))
>f : Symbol(f, Decl(objectSpreadNegative.ts, 72, 12))
>a : Symbol(a, Decl(objectSpreadNegative.ts, 88, 7))
>id : Symbol(id, Decl(objectSpreadNegative.ts, 88, 13))
>c : Symbol(c, Decl(objectSpreadNegative.ts, 88, 27))
>d : Symbol(d, Decl(objectSpreadNegative.ts, 88, 33))

View file

@ -90,7 +90,6 @@ spread = b; // error, missing 's'
>spread : { s: string; b: boolean; }
>b : { b: boolean; }
// literal repeats are not allowed, but spread repeats are fine
let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
>duplicated : { b: string; a: number; }
>{ b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' } : { b: string; a: number; }
@ -109,6 +108,113 @@ let duplicatedSpread = { ...o, ...o }
>o : { a: number; b: string; }
>o : { a: number; b: string; }
// Note: ignore changes the order that properties are printed
let ignore: { a: number, b: string } =
>ignore : { a: number; b: string; }
>a : number
>b : string
{ b: 'ignored', ...o }
>{ b: 'ignored', ...o } : { a: number; b: string; }
>b : string
>'ignored' : "ignored"
>o : { a: number; b: string; }
let o3 = { a: 1, b: 'no' }
>o3 : { a: number; b: string; }
>{ a: 1, b: 'no' } : { a: number; b: string; }
>a : number
>1 : 1
>b : string
>'no' : "no"
let o4 = { b: 'yes', c: true }
>o4 : { b: string; c: boolean; }
>{ b: 'yes', c: true } : { b: string; c: boolean; }
>b : string
>'yes' : "yes"
>c : boolean
>true : true
let combinedBefore: { a: number, b: string, c: boolean } =
>combinedBefore : { a: number; b: string; c: boolean; }
>a : number
>b : string
>c : boolean
{ b: 'ok', ...o3, ...o4 }
>{ b: 'ok', ...o3, ...o4 } : { b: string; c: boolean; a: number; }
>b : string
>'ok' : "ok"
>o3 : { a: number; b: string; }
>o4 : { b: string; c: boolean; }
let combinedMid: { a: number, b: string, c: boolean } =
>combinedMid : { a: number; b: string; c: boolean; }
>a : number
>b : string
>c : boolean
{ ...o3, b: 'ok', ...o4 }
>{ ...o3, b: 'ok', ...o4 } : { b: string; c: boolean; a: number; }
>o3 : { a: number; b: string; }
>b : string
>'ok' : "ok"
>o4 : { b: string; c: boolean; }
let combinedNested: { a: number, b: boolean, c: string, d: string } =
>combinedNested : { a: number; b: boolean; c: string; d: string; }
>a : number
>b : boolean
>c : string
>d : string
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
>{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } } : { a: number; d: string; b: false; c: string; }
>{ a: 4, ...{ b: false, c: 'overriden' } } : { b: false; c: string; a: number; }
>a : number
>4 : 4
>{ b: false, c: 'overriden' } : { b: false; c: string; }
>b : false
>false : false
>c : string
>'overriden' : "overriden"
>d : string
>'actually new' : "actually new"
>{ a: 5, d: 'maybe new' } : { a: number; d: string; }
>a : number
>5 : 5
>d : string
>'maybe new' : "maybe new"
let changeTypeBefore: { a: number, b: string } =
>changeTypeBefore : { a: number; b: string; }
>a : number
>b : string
{ a: 'wrong type?', ...o3 };
>{ a: 'wrong type?', ...o3 } : { a: number; b: string; }
>a : string
>'wrong type?' : "wrong type?"
>o3 : { a: number; b: string; }
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
>"in the middle" : number
{ ...o3, ['in the middle']: 13, b: 'maybe?', ...o4 }
>{ ...o3, ['in the middle']: 13, b: 'maybe?', ...o4 } : { b: string; c: boolean; ['in the middle']: number; a: number; }
>o3 : { a: number; b: string; }
>['in the middle'] : number
>'in the middle' : "in the middle"
>13 : 13
>b : string
>'maybe?' : "maybe?"
>o4 : { b: string; c: boolean; }
// primitives are not allowed, except for falsy ones
let spreadNum = { ...12 };
>spreadNum : any

View file

@ -0,0 +1,12 @@
tests/cases/conformance/types/spread/spreadOverwritesProperty.ts(3,17): error TS2735: 'b' is overwritten by a later spread.
==== tests/cases/conformance/types/spread/spreadOverwritesProperty.ts (1 errors) ====
declare var ab: { a: number, b: number };
declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }

View file

@ -0,0 +1,23 @@
//// [spreadOverwritesProperty.ts]
declare var ab: { a: number, b: number };
declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }
//// [spreadOverwritesProperty.js]
var __assign = (this && this.__assign) || function () {
__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;
};
return __assign.apply(this, arguments);
};
var unused1 = __assign({ b: 1 }, ab);
var unused2 = __assign({}, ab, ab);
var unused3 = __assign({ b: 1 }, abq);

View file

@ -0,0 +1,26 @@
=== tests/cases/conformance/types/spread/spreadOverwritesProperty.ts ===
declare var ab: { a: number, b: number };
>ab : Symbol(ab, Decl(spreadOverwritesProperty.ts, 0, 11))
>a : Symbol(a, Decl(spreadOverwritesProperty.ts, 0, 17))
>b : Symbol(b, Decl(spreadOverwritesProperty.ts, 0, 28))
declare var abq: { a: number, b?: number };
>abq : Symbol(abq, Decl(spreadOverwritesProperty.ts, 1, 11))
>a : Symbol(a, Decl(spreadOverwritesProperty.ts, 1, 18))
>b : Symbol(b, Decl(spreadOverwritesProperty.ts, 1, 29))
var unused1 = { b: 1, ...ab }
>unused1 : Symbol(unused1, Decl(spreadOverwritesProperty.ts, 2, 3))
>b : Symbol(b, Decl(spreadOverwritesProperty.ts, 2, 15))
>ab : Symbol(ab, Decl(spreadOverwritesProperty.ts, 0, 11))
var unused2 = { ...ab, ...ab }
>unused2 : Symbol(unused2, Decl(spreadOverwritesProperty.ts, 3, 3))
>ab : Symbol(ab, Decl(spreadOverwritesProperty.ts, 0, 11))
>ab : Symbol(ab, Decl(spreadOverwritesProperty.ts, 0, 11))
var unused3 = { b: 1, ...abq }
>unused3 : Symbol(unused3, Decl(spreadOverwritesProperty.ts, 4, 3))
>b : Symbol(b, Decl(spreadOverwritesProperty.ts, 4, 15))
>abq : Symbol(abq, Decl(spreadOverwritesProperty.ts, 1, 11))

View file

@ -0,0 +1,31 @@
=== tests/cases/conformance/types/spread/spreadOverwritesProperty.ts ===
declare var ab: { a: number, b: number };
>ab : { a: number; b: number; }
>a : number
>b : number
declare var abq: { a: number, b?: number };
>abq : { a: number; b?: number; }
>a : number
>b : number
var unused1 = { b: 1, ...ab }
>unused1 : { a: number; b: number; }
>{ b: 1, ...ab } : { a: number; b: number; }
>b : number
>1 : 1
>ab : { a: number; b: number; }
var unused2 = { ...ab, ...ab }
>unused2 : { a: number; b: number; }
>{ ...ab, ...ab } : { a: number; b: number; }
>ab : { a: number; b: number; }
>ab : { a: number; b: number; }
var unused3 = { b: 1, ...abq }
>unused3 : { a: number; b: number; }
>{ b: 1, ...abq } : { a: number; b: number; }
>b : number
>1 : 1
>abq : { a: number; b?: number; }

View file

@ -0,0 +1,12 @@
tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts(3,17): error TS2735: 'b' is overwritten by a later spread.
==== tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts (1 errors) ====
declare var ab: { a: number, b: number };
declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
~~~~
!!! error TS2735: 'b' is overwritten by a later spread.
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }

View file

@ -0,0 +1,24 @@
//// [spreadOverwritesPropertyStrict.ts]
declare var ab: { a: number, b: number };
declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }
//// [spreadOverwritesPropertyStrict.js]
"use strict";
var __assign = (this && this.__assign) || function () {
__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;
};
return __assign.apply(this, arguments);
};
var unused1 = __assign({ b: 1 }, ab);
var unused2 = __assign({}, ab, ab);
var unused3 = __assign({ b: 1 }, abq);

View file

@ -0,0 +1,26 @@
=== tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts ===
declare var ab: { a: number, b: number };
>ab : Symbol(ab, Decl(spreadOverwritesPropertyStrict.ts, 0, 11))
>a : Symbol(a, Decl(spreadOverwritesPropertyStrict.ts, 0, 17))
>b : Symbol(b, Decl(spreadOverwritesPropertyStrict.ts, 0, 28))
declare var abq: { a: number, b?: number };
>abq : Symbol(abq, Decl(spreadOverwritesPropertyStrict.ts, 1, 11))
>a : Symbol(a, Decl(spreadOverwritesPropertyStrict.ts, 1, 18))
>b : Symbol(b, Decl(spreadOverwritesPropertyStrict.ts, 1, 29))
var unused1 = { b: 1, ...ab }
>unused1 : Symbol(unused1, Decl(spreadOverwritesPropertyStrict.ts, 2, 3))
>b : Symbol(b, Decl(spreadOverwritesPropertyStrict.ts, 2, 15))
>ab : Symbol(ab, Decl(spreadOverwritesPropertyStrict.ts, 0, 11))
var unused2 = { ...ab, ...ab }
>unused2 : Symbol(unused2, Decl(spreadOverwritesPropertyStrict.ts, 3, 3))
>ab : Symbol(ab, Decl(spreadOverwritesPropertyStrict.ts, 0, 11))
>ab : Symbol(ab, Decl(spreadOverwritesPropertyStrict.ts, 0, 11))
var unused3 = { b: 1, ...abq }
>unused3 : Symbol(unused3, Decl(spreadOverwritesPropertyStrict.ts, 4, 3))
>b : Symbol(b, Decl(spreadOverwritesPropertyStrict.ts, 4, 15))
>abq : Symbol(abq, Decl(spreadOverwritesPropertyStrict.ts, 1, 11))

View file

@ -0,0 +1,31 @@
=== tests/cases/conformance/types/spread/spreadOverwritesPropertyStrict.ts ===
declare var ab: { a: number, b: number };
>ab : { a: number; b: number; }
>a : number
>b : number
declare var abq: { a: number, b?: number };
>abq : { a: number; b?: number | undefined; }
>a : number
>b : number | undefined
var unused1 = { b: 1, ...ab }
>unused1 : { a: number; b: number; }
>{ b: 1, ...ab } : { a: number; b: number; }
>b : number
>1 : 1
>ab : { a: number; b: number; }
var unused2 = { ...ab, ...ab }
>unused2 : { a: number; b: number; }
>{ ...ab, ...ab } : { a: number; b: number; }
>ab : { a: number; b: number; }
>ab : { a: number; b: number; }
var unused3 = { b: 1, ...abq }
>unused3 : { a: number; b: number; }
>{ b: 1, ...abq } : { a: number; b: number; }
>b : number
>1 : 1
>abq : { a: number; b?: number | undefined; }

View file

@ -1,15 +1,18 @@
tests/cases/conformance/types/spread/spreadUnion3.ts(2,14): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/spread/spreadUnion3.ts(2,14): error TS2735: 'y' is overwritten by a later spread.
tests/cases/conformance/types/spread/spreadUnion3.ts(9,23): error TS2339: 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 (4 errors) ====
==== tests/cases/conformance/types/spread/spreadUnion3.ts (5 errors) ====
function f(x: { y: string } | undefined): { y: string } {
return { y: 123, ...x } // y: string | number
~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! related TS6500 tests/cases/conformance/types/spread/spreadUnion3.ts:1:45: The expected type comes from property 'y' which is declared here on type '{ y: string; }'
~~~~~~
!!! error TS2735: 'y' is overwritten by a later spread.
}
f(undefined)

View file

@ -8,23 +8,14 @@ let addAfter: { a: number, b: string, c: boolean } =
{ ...o, c: false }
let addBefore: { a: number, b: string, c: boolean } =
{ c: false, ...o }
// Note: ignore still changes the order that properties are printed
let ignore: { a: number, b: string } =
{ b: 'ignored', ...o }
let override: { a: number, b: string } =
{ ...o, b: 'override' }
let nested: { a: number, b: boolean, c: string } =
{ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' }
let combined: { a: number, b: string, c: boolean } =
{ ...o, ...o2 }
let combinedBefore: { a: number, b: string, c: boolean } =
{ b: 'ok', ...o, ...o2 }
let combinedMid: { a: number, b: string, c: boolean } =
{ ...o, b: 'ok', ...o2 }
let combinedAfter: { a: number, b: string, c: boolean } =
{ ...o, ...o2, b: 'ok' }
let combinedNested: { a: number, b: boolean, c: string, d: string } =
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
let combinedNestedChangeType: { a: number, b: boolean, c: number } =
{ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 }
let propertyNested: { a: { a: number, b: string } } =
@ -92,8 +83,6 @@ cplus.plus();
// new field's type conflicting with existing field is OK
let changeTypeAfter: { a: string, b: string } =
{ ...o, a: 'wrong type?' }
let changeTypeBefore: { a: number, b: string } =
{ a: 'wrong type?', ...o };
let changeTypeBoth: { a: string, b: number } =
{ ...o, ...swap };
@ -110,8 +99,6 @@ function container(
// 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 }
}

View file

@ -25,9 +25,24 @@ spread = { s: "foo" }; // error, missing 'b'
let b = { b: false };
spread = b; // error, missing 's'
// literal repeats are not allowed, but spread repeats are fine
let duplicated = { b: 'bad', ...o, b: 'bad', ...o2, b: 'bad' }
let duplicatedSpread = { ...o, ...o }
// Note: ignore changes the order that properties are printed
let ignore: { a: number, b: string } =
{ b: 'ignored', ...o }
let o3 = { a: 1, b: 'no' }
let o4 = { b: 'yes', c: true }
let combinedBefore: { a: number, b: string, c: boolean } =
{ b: 'ok', ...o3, ...o4 }
let combinedMid: { a: number, b: string, c: boolean } =
{ ...o3, b: 'ok', ...o4 }
let combinedNested: { a: number, b: boolean, c: string, d: string } =
{ ...{ a: 4, ...{ b: false, c: 'overriden' } }, d: 'actually new', ...{ a: 5, d: 'maybe new' } }
let changeTypeBefore: { a: number, b: string } =
{ a: 'wrong type?', ...o3 };
let computedMiddle: { a: number, b: string, c: boolean, "in the middle": number } =
{ ...o3, ['in the middle']: 13, b: 'maybe?', ...o4 }
// primitives are not allowed, except for falsy ones
let spreadNum = { ...12 };

View file

@ -0,0 +1,5 @@
declare var ab: { a: number, b: number };
declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }

View file

@ -0,0 +1,6 @@
// @strict: true
declare var ab: { a: number, b: number };
declare var abq: { a: number, b?: number };
var unused1 = { b: 1, ...ab }
var unused2 = { ...ab, ...ab }
var unused3 = { b: 1, ...abq }