1/* 2* Copyright (c) Microsoft Corporation. All rights reserved. 3* Copyright (c) 2023 Huawei Device Co., Ltd. 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15* 16* This file has been modified by Huawei to verify type inference by adding verification statements. 17*/ 18 19// === tests/cases/conformance/types/spread/objectSpread.ts === 20declare function AssertType(value:any, type:string):void; 21let o = { a: 1, b: 'no' 22AssertType(o, "{ a: number; b: string; }"); 23 24AssertType({ a: 1, b: 'no' }, "{ a: number; b: string; }"); 25 26AssertType(a, "number"); 27 28AssertType(1, "int"); 29 30AssertType(b, "string"); 31 32AssertType('no', "string"); 33} 34 35let o2 = { b: 'yes', c: true 36AssertType(o2, "{ b: string; c: boolean; }"); 37 38AssertType({ b: 'yes', c: true }, "{ b: string; c: boolean; }"); 39 40AssertType(b, "string"); 41 42AssertType('yes', "string"); 43 44AssertType(c, "boolean"); 45 46AssertType(true, "boolean"); 47} 48 49let swap = { a: 'yes', b: -1 }; 50AssertType(swap, "{ a: string; b: number; }"); 51AssertType({ a: 'yes', b: -1 }, "{ a: string; b: number; }"); 52AssertType(a, "string"); 53AssertType('yes', "string"); 54AssertType(b, "number"); 55AssertType(-1, "int"); 56AssertType(1, "int"); 57 58let addAfter: { a: number, b: string, c: boolean } = 59AssertType(addAfter, "{ a: number; b: string; c: boolean; }"); 60AssertType(a, "number"); 61AssertType(b, "string"); 62AssertType(c, "boolean"); 63 64 { ...o, c: false 65AssertType({ ...o, c: false }, "{ c: false; a: number; b: string; }"); 66 67AssertType(o, "{ a: number; b: string; }"); 68 69AssertType(c, "boolean"); 70 71AssertType(false, "boolean"); 72} 73 74let addBefore: { a: number, b: string, c: boolean } = 75AssertType(addBefore, "{ a: number; b: string; c: boolean; }"); 76AssertType(a, "number"); 77AssertType(b, "string"); 78AssertType(c, "boolean"); 79 80 { c: false, ...o 81AssertType({ c: false, ...o }, "{ a: number; b: string; c: false; }"); 82 83AssertType(c, "boolean"); 84 85AssertType(false, "boolean"); 86 87AssertType(o, "{ a: number; b: string; }"); 88} 89 90let override: { a: number, b: string } = 91AssertType(override, "{ a: number; b: string; }"); 92AssertType(a, "number"); 93AssertType(b, "string"); 94 95 { ...o, b: 'override' 96AssertType({ ...o, b: 'override' }, "{ b: string; a: number; }"); 97 98AssertType(o, "{ a: number; b: string; }"); 99 100AssertType(b, "string"); 101 102AssertType('override', "string"); 103} 104 105let nested: { a: number, b: boolean, c: string } = 106AssertType(nested, "{ a: number; b: boolean; c: string; }"); 107AssertType(a, "number"); 108AssertType(b, "boolean"); 109AssertType(c, "string"); 110 111 { ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' 112AssertType({ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' }, "{ c: string; b: false; a: number; }"); 113 114AssertType({ a: 3, ...{ b: false, c: 'overriden' } }, "{ b: false; c: string; a: number; }"); 115 116AssertType(a, "number"); 117 118AssertType(3, "int"); 119 120AssertType({ b: false, c: 'overriden' }, "{ b: false; c: string; }"); 121 122AssertType(b, "boolean"); 123 124AssertType(false, "boolean"); 125 126AssertType(c, "string"); 127 128AssertType('overriden', "string"); 129 130AssertType(c, "string"); 131 132AssertType('whatever', "string"); 133} 134 135let combined: { a: number, b: string, c: boolean } = 136AssertType(combined, "{ a: number; b: string; c: boolean; }"); 137AssertType(a, "number"); 138AssertType(b, "string"); 139AssertType(c, "boolean"); 140 141 { ...o, ...o2 142AssertType({ ...o, ...o2 }, "{ b: string; c: boolean; a: number; }"); 143 144AssertType(o, "{ a: number; b: string; }"); 145 146AssertType(o2, "{ b: string; c: boolean; }"); 147} 148 149let combinedAfter: { a: number, b: string, c: boolean } = 150AssertType(combinedAfter, "{ a: number; b: string; c: boolean; }"); 151AssertType(a, "number"); 152AssertType(b, "string"); 153AssertType(c, "boolean"); 154 155 { ...o, ...o2, b: 'ok' 156AssertType({ ...o, ...o2, b: 'ok' }, "{ b: string; c: boolean; a: number; }"); 157 158AssertType(o, "{ a: number; b: string; }"); 159 160AssertType(o2, "{ b: string; c: boolean; }"); 161 162AssertType(b, "string"); 163 164AssertType('ok', "string"); 165} 166 167let combinedNestedChangeType: { a: number, b: boolean, c: number } = 168AssertType(combinedNestedChangeType, "{ a: number; b: boolean; c: number; }"); 169AssertType(a, "number"); 170AssertType(b, "boolean"); 171AssertType(c, "number"); 172 173 { ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 174AssertType({ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 }, "{ c: number; b: false; a: number; }"); 175 176AssertType({ a: 1, ...{ b: false, c: 'overriden' } }, "{ b: false; c: string; a: number; }"); 177 178AssertType(a, "number"); 179 180AssertType(1, "int"); 181 182AssertType({ b: false, c: 'overriden' }, "{ b: false; c: string; }"); 183 184AssertType(b, "boolean"); 185 186AssertType(false, "boolean"); 187 188AssertType(c, "string"); 189 190AssertType('overriden', "string"); 191 192AssertType(c, "number"); 193 194AssertType(-1, "int"); 195 196AssertType(1, "int"); 197} 198 199let propertyNested: { a: { a: number, b: string } } = 200AssertType(propertyNested, "{ a: { a: number; b: string;}; }"); 201AssertType(a, "{ a: number; b: string; }"); 202AssertType(a, "number"); 203AssertType(b, "string"); 204 205 { a: { ... o } 206AssertType({ a: { ... o } }, "{ a: { a: number; b: string; }; }"); 207 208AssertType(a, "{ a: number; b: string; }"); 209 210AssertType({ ... o }, "{ a: number; b: string; }"); 211 212AssertType(o, "{ a: number; b: string; }"); 213} 214 215// accessors don't copy the descriptor 216// (which means that readonly getters become read/write properties) 217let op = { get a () { 218AssertType(op, "{ readonly a: number; }"); 219AssertType({ get a () { return 6 } }, "{ readonly a: number; }"); 220AssertType(a, "number"); 221AssertType(6, "int"); 222return 6 } }; 223 224let getter: { a: number, c: number } = 225AssertType(getter, "{ a: number; c: number; }"); 226AssertType(a, "number"); 227AssertType(c, "number"); 228 229 { ...op, c: 7 230AssertType({ ...op, c: 7 }, "{ c: number; a: number; }"); 231 232AssertType(op, "{ readonly a: number; }"); 233 234AssertType(c, "number"); 235 236AssertType(7, "int"); 237} 238 239getter.a = 12; 240AssertType(getter.a = 12, "int"); 241AssertType(getter.a, "number"); 242AssertType(12, "int"); 243 244// functions result in { } 245let spreadFunc = { ...(function () { }) }; 246AssertType(spreadFunc, "{}"); 247AssertType({ ...(function () { }) }, "{}"); 248AssertType((function () { }), "() => void"); 249AssertType(function () { }, "() => void"); 250 251type Header = { head: string, body: string, authToken: string } 252function from16326(this: { header: Header }, header: Header, authToken: string): Header { 253AssertType({ ...this.header, ...header, ...authToken && { authToken } }, "{ authToken: string; head: string; body: string; }"); 254 return { 255 256 ...this.header, 257AssertType(this.header, "Header"); 258AssertType(this, "{ header: Header; }"); 259 260 ...header, 261AssertType(header, "Header"); 262 263 ...authToken && { authToken 264AssertType(authToken && { authToken }, "union"); 265 266AssertType(authToken, "string"); 267 268AssertType({ authToken }, "{ authToken: string; }"); 269 270AssertType(authToken, "string"); 271} 272 } 273} 274// boolean && T results in Partial<T> 275function conditionalSpreadBoolean(b: boolean) : { x: number, y: number } { 276 let o = { x: 12, y: 13 277AssertType(o, "{ x: number; y: number; }"); 278 279AssertType({ x: 12, y: 13 }, "{ x: number; y: number; }"); 280 281AssertType(x, "number"); 282 283AssertType(12, "int"); 284 285AssertType(y, "number"); 286 287AssertType(13, "int"); 288} 289 290 o = { 291AssertType(o = { ...o, ...b && { x: 14 } }, "{ x: number; y: number; }"); 292AssertType(o, "{ x: number; y: number; }"); 293AssertType({ ...o, ...b && { x: 14 } }, "{ x: number; y: number; }"); 294 295 ...o, 296AssertType(o, "{ x: number; y: number; }"); 297 298 ...b && { x: 14 299AssertType(b && { x: 14 }, "union"); 300 301AssertType(b, "boolean"); 302 303AssertType({ x: 14 }, "{ x: number; }"); 304 305AssertType(x, "number"); 306 307AssertType(14, "int"); 308} 309 } 310 let o2 = { ...b && { x: 21 } 311AssertType(o2, "{ x?: union; }"); 312 313AssertType({ ...b && { x: 21 }}, "{ x?: union; }"); 314 315AssertType(b && { x: 21 }, "union"); 316 317AssertType(b, "boolean"); 318 319AssertType({ x: 21 }, "{ x: number; }"); 320 321AssertType(x, "number"); 322 323AssertType(21, "int"); 324} 325 326AssertType(o, "{ x: number; y: number; }"); 327 return o; 328} 329function conditionalSpreadNumber(nt: number): { x: number, y: number } { 330 let o = { x: 15, y: 16 331AssertType(o, "{ x: number; y: number; }"); 332 333AssertType({ x: 15, y: 16 }, "{ x: number; y: number; }"); 334 335AssertType(x, "number"); 336 337AssertType(15, "int"); 338 339AssertType(y, "number"); 340 341AssertType(16, "int"); 342} 343 344 o = { 345AssertType(o = { ...o, ...nt && { x: nt } }, "{ x: number; y: number; }"); 346AssertType(o, "{ x: number; y: number; }"); 347AssertType({ ...o, ...nt && { x: nt } }, "{ x: number; y: number; }"); 348 349 ...o, 350AssertType(o, "{ x: number; y: number; }"); 351 352 ...nt && { x: nt 353AssertType(nt && { x: nt }, "union"); 354 355AssertType(nt, "number"); 356 357AssertType({ x: nt }, "{ x: number; }"); 358 359AssertType(x, "number"); 360 361AssertType(nt, "number"); 362} 363 } 364 let o2 = { ...nt && { x: nt } 365AssertType(o2, "{ x?: union; }"); 366 367AssertType({ ...nt && { x: nt }}, "{ x?: union; }"); 368 369AssertType(nt && { x: nt }, "union"); 370 371AssertType(nt, "number"); 372 373AssertType({ x: nt }, "{ x: number; }"); 374 375AssertType(x, "number"); 376 377AssertType(nt, "number"); 378} 379 380AssertType(o, "{ x: number; y: number; }"); 381 return o; 382} 383function conditionalSpreadString(st: string): { x: string, y: number } { 384 let o = { x: 'hi', y: 17 385AssertType(o, "{ x: string; y: number; }"); 386 387AssertType({ x: 'hi', y: 17 }, "{ x: string; y: number; }"); 388 389AssertType(x, "string"); 390 391AssertType('hi', "string"); 392 393AssertType(y, "number"); 394 395AssertType(17, "int"); 396} 397 398 o = { 399AssertType(o = { ...o, ...st && { x: st } }, "{ x: string; y: number; }"); 400AssertType(o, "{ x: string; y: number; }"); 401AssertType({ ...o, ...st && { x: st } }, "{ x: string; y: number; }"); 402 403 ...o, 404AssertType(o, "{ x: string; y: number; }"); 405 406 ...st && { x: st 407AssertType(st && { x: st }, "union"); 408 409AssertType(st, "string"); 410 411AssertType({ x: st }, "{ x: string; }"); 412 413AssertType(x, "string"); 414 415AssertType(st, "string"); 416} 417 } 418 let o2 = { ...st && { x: st } 419AssertType(o2, "{ x?: union; }"); 420 421AssertType({ ...st && { x: st }}, "{ x?: union; }"); 422 423AssertType(st && { x: st }, "union"); 424 425AssertType(st, "string"); 426 427AssertType({ x: st }, "{ x: string; }"); 428 429AssertType(x, "string"); 430 431AssertType(st, "string"); 432} 433 434AssertType(o, "{ x: string; y: number; }"); 435 return o; 436} 437 438// any results in any 439let anything: any; 440AssertType(anything, "any"); 441 442let spreadAny = { ...anything }; 443AssertType(spreadAny, "any"); 444AssertType({ ...anything }, "any"); 445AssertType(anything, "any"); 446 447// methods are not enumerable 448class C { p = 1; m() { } } 449let c: C = new C() 450AssertType(c, "C"); 451AssertType(new C(), "C"); 452AssertType(C, "typeof C"); 453 454let spreadC: { p: number } = { ...c 455AssertType(spreadC, "{ p: number; }"); 456 457AssertType(p, "number"); 458 459AssertType({ ...c }, "{ p: number; }"); 460 461AssertType(c, "C"); 462} 463 464// own methods are enumerable 465let cplus: { p: number, plus(): void } = { ...c, plus() { 466AssertType(cplus, "{ p: number; plus(): void; }"); 467AssertType(p, "number"); 468AssertType(plus, "() => void"); 469AssertType({ ...c, plus() { return this.p + 1; } }, "{ plus(): any; p: number; }"); 470AssertType(c, "C"); 471AssertType(plus, "() => any"); 472AssertType(this.p + 1, "any"); 473AssertType(this.p, "any"); 474AssertType(this, "any"); 475AssertType(1, "int"); 476return this.p + 1; } }; 477 478cplus.plus(); 479AssertType(cplus.plus(), "void"); 480AssertType(cplus.plus, "() => void"); 481 482// new field's type conflicting with existing field is OK 483let changeTypeAfter: { a: string, b: string } = 484AssertType(changeTypeAfter, "{ a: string; b: string; }"); 485AssertType(a, "string"); 486AssertType(b, "string"); 487 488 { ...o, a: 'wrong type?' 489AssertType({ ...o, a: 'wrong type?' }, "{ a: string; b: string; }"); 490 491AssertType(o, "{ a: number; b: string; }"); 492 493AssertType(a, "string"); 494 495AssertType('wrong type?', "string"); 496} 497 498let changeTypeBoth: { a: string, b: number } = 499AssertType(changeTypeBoth, "{ a: string; b: number; }"); 500AssertType(a, "string"); 501AssertType(b, "number"); 502 503 { ...o, ...swap }; 504AssertType({ ...o, ...swap }, "{ a: string; b: number; }"); 505AssertType(o, "{ a: number; b: string; }"); 506AssertType(swap, "{ a: string; b: number; }"); 507 508// optional 509function container( 510 definiteBoolean: { sn: boolean }, 511 definiteString: { sn: string }, 512 optionalString: { sn?: string }, 513 optionalNumber: { sn?: number }) { 514 let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber }; 515AssertType(optionalUnionStops, "{ sn: union; }"); 516AssertType(sn, "union"); 517AssertType({ ...definiteBoolean, ...definiteString, ...optionalNumber }, "{ sn: union; }"); 518AssertType(definiteBoolean, "{ sn: boolean; }"); 519AssertType(definiteString, "{ sn: string; }"); 520AssertType(optionalNumber, "{ sn?: union; }"); 521 522 let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }; 523AssertType(optionalUnionDuplicates, "{ sn: union; }"); 524AssertType(sn, "union"); 525AssertType({ ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber }, "{ sn: union; }"); 526AssertType(definiteBoolean, "{ sn: boolean; }"); 527AssertType(definiteString, "{ sn: string; }"); 528AssertType(optionalString, "{ sn?: union; }"); 529AssertType(optionalNumber, "{ sn?: union; }"); 530 531 let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber }; 532AssertType(allOptional, "{ sn?: union; }"); 533AssertType(sn, "union"); 534AssertType({ ...optionalString, ...optionalNumber }, "{ sn?: union; }"); 535AssertType(optionalString, "{ sn?: union; }"); 536AssertType(optionalNumber, "{ sn?: union; }"); 537 538 // computed property 539 let computedFirst: { a: number, b: string, "before everything": number } = 540AssertType(computedFirst, "{ a: number; b: string; "before everything": number; }"); 541AssertType(a, "number"); 542AssertType(b, "string"); 543AssertType("before everything", "number"); 544 545 { ['before everything']: 12, ...o, b: 'yes' 546AssertType({ ['before everything']: 12, ...o, b: 'yes' }, "{ b: string; a: number; "before everything": number; }"); 547 548AssertType(['before everything'], "number"); 549 550AssertType('before everything', "string"); 551 552AssertType(12, "int"); 553 554AssertType(o, "{ a: number; b: string; }"); 555 556AssertType(b, "string"); 557 558AssertType('yes', "string"); 559} 560 561 let computedAfter: { a: number, b: string, "at the end": number } = 562AssertType(computedAfter, "{ a: number; b: string; "at the end": number; }"); 563AssertType(a, "number"); 564AssertType(b, "string"); 565AssertType("at the end", "number"); 566 567 { ...o, b: 'yeah', ['at the end']: 14 568AssertType({ ...o, b: 'yeah', ['at the end']: 14 }, "{ b: string; "at the end": number; a: number; }"); 569 570AssertType(o, "{ a: number; b: string; }"); 571 572AssertType(b, "string"); 573 574AssertType('yeah', "string"); 575 576AssertType(['at the end'], "number"); 577 578AssertType('at the end', "string"); 579 580AssertType(14, "int"); 581} 582} 583// shortcut syntax 584let a = 12; 585AssertType(a, "number"); 586AssertType(12, "int"); 587 588let shortCutted: { a: number, b: string } = { ...o, a 589AssertType(shortCutted, "{ a: number; b: string; }"); 590 591AssertType(a, "number"); 592 593AssertType(b, "string"); 594 595AssertType({ ...o, a }, "{ a: number; b: string; }"); 596 597AssertType(o, "{ a: number; b: string; }"); 598 599AssertType(a, "number"); 600} 601 602// non primitive 603let spreadNonPrimitive = { ...<object>{}}; 604AssertType(spreadNonPrimitive, "{}"); 605AssertType({ ...<object>{}}, "{}"); 606AssertType(<object>{}, "object"); 607AssertType({}, "{}"); 608 609// generic spreads 610 611function f<T, U>(t: T, u: U) { 612AssertType({ ...t, ...u, id: 'id' }, "T & U & { id: string; }"); 613AssertType(t, "T"); 614AssertType(u, "U"); 615AssertType(id, "string"); 616AssertType('id', "string"); 617 return { ...t, ...u, id: 'id' }; 618} 619 620let exclusive: { id: string, a: number, b: string, c: string, d: boolean } = 621AssertType(exclusive, "{ id: string; a: number; b: string; c: string; d: boolean; }"); 622AssertType(id, "string"); 623AssertType(a, "number"); 624AssertType(b, "string"); 625AssertType(c, "string"); 626AssertType(d, "boolean"); 627 628 f({ a: 1, b: 'yes' }, { c: 'no', d: false }) 629AssertType(f({ a: 1, b: 'yes' }, { c: 'no', d: false }), "{ a: number; b: string; } & { c: string; d: boolean; } & { id: string; }"); 630AssertType(f, "<T, U>(T, U) => T & U & { id: string; }"); 631AssertType({ a: 1, b: 'yes' }, "{ a: number; b: string; }"); 632AssertType(a, "number"); 633AssertType(1, "int"); 634AssertType(b, "string"); 635AssertType('yes', "string"); 636AssertType({ c: 'no', d: false }, "{ c: string; d: false; }"); 637AssertType(c, "string"); 638AssertType('no', "string"); 639AssertType(d, "boolean"); 640AssertType(false, "boolean"); 641 642let overlap: { id: string, a: number, b: string } = 643AssertType(overlap, "{ id: string; a: number; b: string; }"); 644AssertType(id, "string"); 645AssertType(a, "number"); 646AssertType(b, "string"); 647 648 f({ a: 1 }, { a: 2, b: 'extra' }) 649AssertType(f({ a: 1 }, { a: 2, b: 'extra' }), "{ a: number; } & { a: number; b: string; } & { id: string; }"); 650AssertType(f, "<T, U>(T, U) => T & U & { id: string; }"); 651AssertType({ a: 1 }, "{ a: number; }"); 652AssertType(a, "number"); 653AssertType(1, "int"); 654AssertType({ a: 2, b: 'extra' }, "{ a: number; b: string; }"); 655AssertType(a, "number"); 656AssertType(2, "int"); 657AssertType(b, "string"); 658AssertType('extra', "string"); 659 660let overlapConflict: { id:string, a: string } = 661AssertType(overlapConflict, "{ id: string; a: string; }"); 662AssertType(id, "string"); 663AssertType(a, "string"); 664 665 f({ a: 1 }, { a: 'mismatch' }) 666AssertType(f({ a: 1 }, { a: 'mismatch' }), "{ a: number; } & { a: string; } & { id: string; }"); 667AssertType(f, "<T, U>(T, U) => T & U & { id: string; }"); 668AssertType({ a: 1 }, "{ a: number; }"); 669AssertType(a, "number"); 670AssertType(1, "int"); 671AssertType({ a: 'mismatch' }, "{ a: string; }"); 672AssertType(a, "string"); 673AssertType('mismatch', "string"); 674 675let overwriteId: { id: string, a: number, c: number, d: string } = 676AssertType(overwriteId, "{ id: string; a: number; c: number; d: string; }"); 677AssertType(id, "string"); 678AssertType(a, "number"); 679AssertType(c, "number"); 680AssertType(d, "string"); 681 682 f({ a: 1, id: true }, { c: 1, d: 'no' }) 683AssertType(f({ a: 1, id: true }, { c: 1, d: 'no' }), "never"); 684AssertType(f, "<T, U>(T, U) => T & U & { id: string; }"); 685AssertType({ a: 1, id: true }, "{ a: number; id: true; }"); 686AssertType(a, "number"); 687AssertType(1, "int"); 688AssertType(id, "boolean"); 689AssertType(true, "boolean"); 690AssertType({ c: 1, d: 'no' }, "{ c: number; d: string; }"); 691AssertType(c, "number"); 692AssertType(1, "int"); 693AssertType(d, "string"); 694AssertType('no', "string"); 695 696function genericSpread<T, U>(t: T, u: U, v: T | U, w: T | { s: string }, obj: { x: number }) { 697 let x01 = { ...t }; 698AssertType(x01, "T"); 699AssertType({ ...t }, "T"); 700AssertType(t, "T"); 701 702 let x02 = { ...t, ...t }; 703AssertType(x02, "T"); 704AssertType({ ...t, ...t }, "T"); 705AssertType(t, "T"); 706AssertType(t, "T"); 707 708 let x03 = { ...t, ...u }; 709AssertType(x03, "T & U"); 710AssertType({ ...t, ...u }, "T & U"); 711AssertType(t, "T"); 712AssertType(u, "U"); 713 714 let x04 = { ...u, ...t }; 715AssertType(x04, "U & T"); 716AssertType({ ...u, ...t }, "U & T"); 717AssertType(u, "U"); 718AssertType(t, "T"); 719 720 let x05 = { a: 5, b: 'hi', ...t }; 721AssertType(x05, "{ a: number; b: string; } & T"); 722AssertType({ a: 5, b: 'hi', ...t }, "{ a: number; b: string; } & T"); 723AssertType(a, "number"); 724AssertType(5, "int"); 725AssertType(b, "string"); 726AssertType('hi', "string"); 727AssertType(t, "T"); 728 729 let x06 = { ...t, a: 5, b: 'hi' }; 730AssertType(x06, "T & { a: number; b: string; }"); 731AssertType({ ...t, a: 5, b: 'hi' }, "T & { a: number; b: string; }"); 732AssertType(t, "T"); 733AssertType(a, "number"); 734AssertType(5, "int"); 735AssertType(b, "string"); 736AssertType('hi', "string"); 737 738 let x07 = { a: 5, b: 'hi', ...t, c: true, ...obj }; 739AssertType(x07, "{ a: number; b: string; } & T & { x: number; c: boolean; }"); 740AssertType({ a: 5, b: 'hi', ...t, c: true, ...obj }, "{ a: number; b: string; } & T & { x: number; c: boolean; }"); 741AssertType(a, "number"); 742AssertType(5, "int"); 743AssertType(b, "string"); 744AssertType('hi', "string"); 745AssertType(t, "T"); 746AssertType(c, "boolean"); 747AssertType(true, "boolean"); 748AssertType(obj, "{ x: number; }"); 749 750 let x09 = { a: 5, ...t, b: 'hi', c: true, ...obj }; 751AssertType(x09, "{ a: number; } & T & { x: number; b: string; c: boolean; }"); 752AssertType({ a: 5, ...t, b: 'hi', c: true, ...obj }, "{ a: number; } & T & { x: number; b: string; c: boolean; }"); 753AssertType(a, "number"); 754AssertType(5, "int"); 755AssertType(t, "T"); 756AssertType(b, "string"); 757AssertType('hi', "string"); 758AssertType(c, "boolean"); 759AssertType(true, "boolean"); 760AssertType(obj, "{ x: number; }"); 761 762 let x10 = { a: 5, ...t, b: 'hi', ...u, ...obj }; 763AssertType(x10, "{ a: number; } & T & { b: string; } & U & { x: number; }"); 764AssertType({ a: 5, ...t, b: 'hi', ...u, ...obj }, "{ a: number; } & T & { b: string; } & U & { x: number; }"); 765AssertType(a, "number"); 766AssertType(5, "int"); 767AssertType(t, "T"); 768AssertType(b, "string"); 769AssertType('hi', "string"); 770AssertType(u, "U"); 771AssertType(obj, "{ x: number; }"); 772 773 let x11 = { ...v }; 774AssertType(x11, "union"); 775AssertType({ ...v }, "union"); 776AssertType(v, "union"); 777 778 let x12 = { ...v, ...obj }; 779AssertType(x12, "union"); 780AssertType({ ...v, ...obj }, "union"); 781AssertType(v, "union"); 782AssertType(obj, "{ x: number; }"); 783 784 let x13 = { ...w }; 785AssertType(x13, "union"); 786AssertType({ ...w }, "union"); 787AssertType(w, "union"); 788 789 let x14 = { ...w, ...obj }; 790AssertType(x14, "union"); 791AssertType({ ...w, ...obj }, "union"); 792AssertType(w, "union"); 793AssertType(obj, "{ x: number; }"); 794 795 let x15 = { ...t, ...v }; 796AssertType(x15, "union"); 797AssertType({ ...t, ...v }, "union"); 798AssertType(t, "T"); 799AssertType(v, "union"); 800 801 let x16 = { ...t, ...w }; 802AssertType(x16, "union"); 803AssertType({ ...t, ...w }, "union"); 804AssertType(t, "T"); 805AssertType(w, "union"); 806 807 let x17 = { ...t, ...w, ...obj }; 808AssertType(x17, "union"); 809AssertType({ ...t, ...w, ...obj }, "union"); 810AssertType(t, "T"); 811AssertType(w, "union"); 812AssertType(obj, "{ x: number; }"); 813 814 let x18 = { ...t, ...v, ...w }; 815AssertType(x18, "union"); 816AssertType({ ...t, ...v, ...w }, "union"); 817AssertType(t, "T"); 818AssertType(v, "union"); 819AssertType(w, "union"); 820} 821 822 823