a299d2dd1c
* isDeclarationName: support ComputedPropertyName * update additional baseline
585 lines
16 KiB
Plaintext
585 lines
16 KiB
Plaintext
=== tests/cases/conformance/types/spread/objectSpread.ts ===
|
|
let o = { a: 1, b: 'no' }
|
|
>o : { a: number; b: string; }
|
|
>{ a: 1, b: 'no' } : { a: number; b: string; }
|
|
>a : number
|
|
>1 : 1
|
|
>b : string
|
|
>'no' : "no"
|
|
|
|
let o2 = { b: 'yes', c: true }
|
|
>o2 : { b: string; c: boolean; }
|
|
>{ b: 'yes', c: true } : { b: string; c: boolean; }
|
|
>b : string
|
|
>'yes' : "yes"
|
|
>c : boolean
|
|
>true : true
|
|
|
|
let swap = { a: 'yes', b: -1 };
|
|
>swap : { a: string; b: number; }
|
|
>{ a: 'yes', b: -1 } : { a: string; b: number; }
|
|
>a : string
|
|
>'yes' : "yes"
|
|
>b : number
|
|
>-1 : -1
|
|
>1 : 1
|
|
|
|
let addAfter: { a: number, b: string, c: boolean } =
|
|
>addAfter : { a: number; b: string; c: boolean; }
|
|
>a : number
|
|
>b : string
|
|
>c : boolean
|
|
|
|
{ ...o, c: false }
|
|
>{ ...o, c: false } : { c: false; a: number; b: string; }
|
|
>o : { a: number; b: string; }
|
|
>c : false
|
|
>false : false
|
|
|
|
let addBefore: { a: number, b: string, c: boolean } =
|
|
>addBefore : { a: number; b: string; c: boolean; }
|
|
>a : number
|
|
>b : string
|
|
>c : boolean
|
|
|
|
{ c: false, ...o }
|
|
>{ c: false, ...o } : { a: number; b: string; c: false; }
|
|
>c : false
|
|
>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
|
|
>b : string
|
|
|
|
{ ...o, b: 'override' }
|
|
>{ ...o, b: 'override' } : { b: string; a: number; }
|
|
>o : { a: number; b: string; }
|
|
>b : string
|
|
>'override' : "override"
|
|
|
|
let nested: { a: number, b: boolean, c: string } =
|
|
>nested : { a: number; b: boolean; c: string; }
|
|
>a : number
|
|
>b : boolean
|
|
>c : string
|
|
|
|
{ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' }
|
|
>{ ...{ a: 3, ...{ b: false, c: 'overriden' } }, c: 'whatever' } : { c: string; b: false; a: number; }
|
|
>{ a: 3, ...{ b: false, c: 'overriden' } } : { b: false; c: string; a: number; }
|
|
>a : number
|
|
>3 : 3
|
|
>{ b: false, c: 'overriden' } : { b: false; c: string; }
|
|
>b : false
|
|
>false : false
|
|
>c : string
|
|
>'overriden' : "overriden"
|
|
>c : string
|
|
>'whatever' : "whatever"
|
|
|
|
let combined: { a: number, b: string, c: boolean } =
|
|
>combined : { a: number; b: string; c: boolean; }
|
|
>a : number
|
|
>b : string
|
|
>c : boolean
|
|
|
|
{ ...o, ...o2 }
|
|
>{ ...o, ...o2 } : { b: string; c: boolean; a: number; }
|
|
>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
|
|
>b : string
|
|
>c : boolean
|
|
|
|
{ ...o, ...o2, b: 'ok' }
|
|
>{ ...o, ...o2, b: 'ok' } : { b: string; c: boolean; a: number; }
|
|
>o : { a: number; b: string; }
|
|
>o2 : { 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
|
|
>b : boolean
|
|
>c : number
|
|
|
|
{ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 }
|
|
>{ ...{ a: 1, ...{ b: false, c: 'overriden' } }, c: -1 } : { c: number; b: false; a: number; }
|
|
>{ a: 1, ...{ b: false, c: 'overriden' } } : { b: false; c: string; a: number; }
|
|
>a : number
|
|
>1 : 1
|
|
>{ b: false, c: 'overriden' } : { b: false; c: string; }
|
|
>b : false
|
|
>false : false
|
|
>c : string
|
|
>'overriden' : "overriden"
|
|
>c : number
|
|
>-1 : -1
|
|
>1 : 1
|
|
|
|
let propertyNested: { a: { a: number, b: string } } =
|
|
>propertyNested : { a: { a: number; b: string; }; }
|
|
>a : { a: number; b: string; }
|
|
>a : number
|
|
>b : string
|
|
|
|
{ a: { ... o } }
|
|
>{ a: { ... o } } : { a: { a: number; b: string; }; }
|
|
>a : { a: number; b: string; }
|
|
>{ ... o } : { a: number; b: string; }
|
|
>o : { a: number; b: string; }
|
|
|
|
// accessors don't copy the descriptor
|
|
// (which means that readonly getters become read/write properties)
|
|
let op = { get a () { return 6 } };
|
|
>op : { readonly a: number; }
|
|
>{ get a () { return 6 } } : { readonly a: number; }
|
|
>a : number
|
|
>6 : 6
|
|
|
|
let getter: { a: number, c: number } =
|
|
>getter : { a: number; c: number; }
|
|
>a : number
|
|
>c : number
|
|
|
|
{ ...op, c: 7 }
|
|
>{ ...op, c: 7 } : { c: number; a: number; }
|
|
>op : { readonly a: number; }
|
|
>c : number
|
|
>7 : 7
|
|
|
|
getter.a = 12;
|
|
>getter.a = 12 : 12
|
|
>getter.a : number
|
|
>getter : { a: number; c: number; }
|
|
>a : number
|
|
>12 : 12
|
|
|
|
// functions result in { }
|
|
let spreadFunc = { ...(function () { }) };
|
|
>spreadFunc : {}
|
|
>{ ...(function () { }) } : {}
|
|
>(function () { }) : () => void
|
|
>function () { } : () => void
|
|
|
|
type Header = { head: string, body: string, authToken: string }
|
|
>Header : Header
|
|
>head : string
|
|
>body : string
|
|
>authToken : string
|
|
|
|
function from16326(this: { header: Header }, header: Header, authToken: string): Header {
|
|
>from16326 : (this: { header: Header; }, header: Header, authToken: string) => Header
|
|
>this : { header: Header; }
|
|
>header : Header
|
|
>Header : Header
|
|
>header : Header
|
|
>Header : Header
|
|
>authToken : string
|
|
>Header : Header
|
|
|
|
return {
|
|
>{ ...this.header, ...header, ...authToken && { authToken } } : { head: string; body: string; authToken: string; } | { authToken: string; head: string; body: string; }
|
|
|
|
...this.header,
|
|
>this.header : Header
|
|
>this : { header: Header; }
|
|
>header : Header
|
|
|
|
...header,
|
|
>header : Header
|
|
|
|
...authToken && { authToken }
|
|
>authToken && { authToken } : "" | { authToken: string; }
|
|
>authToken : string
|
|
>{ authToken } : { authToken: string; }
|
|
>authToken : string
|
|
}
|
|
}
|
|
// boolean && T results in Partial<T>
|
|
function conditionalSpreadBoolean(b: boolean) : { x: number, y: number } {
|
|
>conditionalSpreadBoolean : (b: boolean) => { x: number; y: number; }
|
|
>b : boolean
|
|
>x : number
|
|
>y : number
|
|
|
|
let o = { x: 12, y: 13 }
|
|
>o : { x: number; y: number; }
|
|
>{ x: 12, y: 13 } : { x: number; y: number; }
|
|
>x : number
|
|
>12 : 12
|
|
>y : number
|
|
>13 : 13
|
|
|
|
o = {
|
|
>o = { ...o, ...b && { x: 14 } } : { x: number; y: number; } | { x: number; y: number; }
|
|
>o : { x: number; y: number; }
|
|
>{ ...o, ...b && { x: 14 } } : { x: number; y: number; } | { x: number; y: number; }
|
|
|
|
...o,
|
|
>o : { x: number; y: number; }
|
|
|
|
...b && { x: 14 }
|
|
>b && { x: 14 } : false | { x: number; }
|
|
>b : boolean
|
|
>{ x: 14 } : { x: number; }
|
|
>x : number
|
|
>14 : 14
|
|
}
|
|
let o2 = { ...b && { x: 21 }}
|
|
>o2 : {}
|
|
>{ ...b && { x: 21 }} : {} | { x: number; }
|
|
>b && { x: 21 } : false | { x: number; }
|
|
>b : boolean
|
|
>{ x: 21 } : { x: number; }
|
|
>x : number
|
|
>21 : 21
|
|
|
|
return o;
|
|
>o : { x: number; y: number; }
|
|
}
|
|
function conditionalSpreadNumber(nt: number): { x: number, y: number } {
|
|
>conditionalSpreadNumber : (nt: number) => { x: number; y: number; }
|
|
>nt : number
|
|
>x : number
|
|
>y : number
|
|
|
|
let o = { x: 15, y: 16 }
|
|
>o : { x: number; y: number; }
|
|
>{ x: 15, y: 16 } : { x: number; y: number; }
|
|
>x : number
|
|
>15 : 15
|
|
>y : number
|
|
>16 : 16
|
|
|
|
o = {
|
|
>o = { ...o, ...nt && { x: nt } } : { x: number; y: number; } | { x: number; y: number; }
|
|
>o : { x: number; y: number; }
|
|
>{ ...o, ...nt && { x: nt } } : { x: number; y: number; } | { x: number; y: number; }
|
|
|
|
...o,
|
|
>o : { x: number; y: number; }
|
|
|
|
...nt && { x: nt }
|
|
>nt && { x: nt } : 0 | { x: number; }
|
|
>nt : number
|
|
>{ x: nt } : { x: number; }
|
|
>x : number
|
|
>nt : number
|
|
}
|
|
let o2 = { ...nt && { x: nt }}
|
|
>o2 : {}
|
|
>{ ...nt && { x: nt }} : {} | { x: number; }
|
|
>nt && { x: nt } : 0 | { x: number; }
|
|
>nt : number
|
|
>{ x: nt } : { x: number; }
|
|
>x : number
|
|
>nt : number
|
|
|
|
return o;
|
|
>o : { x: number; y: number; }
|
|
}
|
|
function conditionalSpreadString(st: string): { x: string, y: number } {
|
|
>conditionalSpreadString : (st: string) => { x: string; y: number; }
|
|
>st : string
|
|
>x : string
|
|
>y : number
|
|
|
|
let o = { x: 'hi', y: 17 }
|
|
>o : { x: string; y: number; }
|
|
>{ x: 'hi', y: 17 } : { x: string; y: number; }
|
|
>x : string
|
|
>'hi' : "hi"
|
|
>y : number
|
|
>17 : 17
|
|
|
|
o = {
|
|
>o = { ...o, ...st && { x: st } } : { x: string; y: number; } | { x: string; y: number; }
|
|
>o : { x: string; y: number; }
|
|
>{ ...o, ...st && { x: st } } : { x: string; y: number; } | { x: string; y: number; }
|
|
|
|
...o,
|
|
>o : { x: string; y: number; }
|
|
|
|
...st && { x: st }
|
|
>st && { x: st } : "" | { x: string; }
|
|
>st : string
|
|
>{ x: st } : { x: string; }
|
|
>x : string
|
|
>st : string
|
|
}
|
|
let o2 = { ...st && { x: st }}
|
|
>o2 : {}
|
|
>{ ...st && { x: st }} : {} | { x: string; }
|
|
>st && { x: st } : "" | { x: string; }
|
|
>st : string
|
|
>{ x: st } : { x: string; }
|
|
>x : string
|
|
>st : string
|
|
|
|
return o;
|
|
>o : { x: string; y: number; }
|
|
}
|
|
|
|
// any results in any
|
|
let anything: any;
|
|
>anything : any
|
|
|
|
let spreadAny = { ...anything };
|
|
>spreadAny : any
|
|
>{ ...anything } : any
|
|
>anything : any
|
|
|
|
// methods are not enumerable
|
|
class C { p = 1; m() { } }
|
|
>C : C
|
|
>p : number
|
|
>1 : 1
|
|
>m : () => void
|
|
|
|
let c: C = new C()
|
|
>c : C
|
|
>C : C
|
|
>new C() : C
|
|
>C : typeof C
|
|
|
|
let spreadC: { p: number } = { ...c }
|
|
>spreadC : { p: number; }
|
|
>p : number
|
|
>{ ...c } : { p: number; }
|
|
>c : C
|
|
|
|
// own methods are enumerable
|
|
let cplus: { p: number, plus(): void } = { ...c, plus() { return this.p + 1; } };
|
|
>cplus : { p: number; plus(): void; }
|
|
>p : number
|
|
>plus : () => void
|
|
>{ ...c, plus() { return this.p + 1; } } : { plus(): any; p: number; }
|
|
>c : C
|
|
>plus : () => any
|
|
>this.p + 1 : any
|
|
>this.p : any
|
|
>this : any
|
|
>p : any
|
|
>1 : 1
|
|
|
|
cplus.plus();
|
|
>cplus.plus() : void
|
|
>cplus.plus : () => void
|
|
>cplus : { p: number; plus(): void; }
|
|
>plus : () => void
|
|
|
|
// new field's type conflicting with existing field is OK
|
|
let changeTypeAfter: { a: string, b: string } =
|
|
>changeTypeAfter : { a: string; b: string; }
|
|
>a : string
|
|
>b : string
|
|
|
|
{ ...o, a: 'wrong type?' }
|
|
>{ ...o, a: 'wrong type?' } : { a: string; b: string; }
|
|
>o : { a: number; 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
|
|
>b : number
|
|
|
|
{ ...o, ...swap };
|
|
>{ ...o, ...swap } : { a: string; b: number; }
|
|
>o : { a: number; b: string; }
|
|
>swap : { a: string; b: number; }
|
|
|
|
// optional
|
|
function container(
|
|
>container : (definiteBoolean: { sn: boolean; }, definiteString: { sn: string; }, optionalString: { sn?: string | undefined; }, optionalNumber: { sn?: number | undefined; }) => void
|
|
|
|
definiteBoolean: { sn: boolean },
|
|
>definiteBoolean : { sn: boolean; }
|
|
>sn : boolean
|
|
|
|
definiteString: { sn: string },
|
|
>definiteString : { sn: string; }
|
|
>sn : string
|
|
|
|
optionalString: { sn?: string },
|
|
>optionalString : { sn?: string | undefined; }
|
|
>sn : string | undefined
|
|
|
|
optionalNumber: { sn?: number }) {
|
|
>optionalNumber : { sn?: number | undefined; }
|
|
>sn : number | undefined
|
|
|
|
let optionalUnionStops: { sn: string | number | boolean } = { ...definiteBoolean, ...definiteString, ...optionalNumber };
|
|
>optionalUnionStops : { sn: string | number | boolean; }
|
|
>sn : string | number | boolean
|
|
>{ ...definiteBoolean, ...definiteString, ...optionalNumber } : { sn: string | number; }
|
|
>definiteBoolean : { sn: boolean; }
|
|
>definiteString : { sn: string; }
|
|
>optionalNumber : { sn?: number | undefined; }
|
|
|
|
let optionalUnionDuplicates: { sn: string | number } = { ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber };
|
|
>optionalUnionDuplicates : { sn: string | number; }
|
|
>sn : string | number
|
|
>{ ...definiteBoolean, ...definiteString, ...optionalString, ...optionalNumber } : { sn: string | number; }
|
|
>definiteBoolean : { sn: boolean; }
|
|
>definiteString : { sn: string; }
|
|
>optionalString : { sn?: string | undefined; }
|
|
>optionalNumber : { sn?: number | undefined; }
|
|
|
|
let allOptional: { sn?: string | number } = { ...optionalString, ...optionalNumber };
|
|
>allOptional : { sn?: string | number | undefined; }
|
|
>sn : string | number | undefined
|
|
>{ ...optionalString, ...optionalNumber } : { sn?: string | number | undefined; }
|
|
>optionalString : { sn?: string | undefined; }
|
|
>optionalNumber : { sn?: number | undefined; }
|
|
|
|
// computed property
|
|
let computedFirst: { a: number, b: string, "before everything": number } =
|
|
>computedFirst : { a: number; b: string; "before everything": number; }
|
|
>a : number
|
|
>b : string
|
|
>"before everything" : number
|
|
|
|
{ ['before everything']: 12, ...o, b: 'yes' }
|
|
>{ ['before everything']: 12, ...o, b: 'yes' } : { b: string; a: number; ['before everything']: number; }
|
|
>['before everything'] : number
|
|
>'before everything' : "before everything"
|
|
>12 : 12
|
|
>o : { a: number; b: string; }
|
|
>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
|
|
>b : string
|
|
>"at the end" : number
|
|
|
|
{ ...o, b: 'yeah', ['at the end']: 14 }
|
|
>{ ...o, b: 'yeah', ['at the end']: 14 } : { b: string; ['at the end']: number; a: number; }
|
|
>o : { a: number; b: string; }
|
|
>b : string
|
|
>'yeah' : "yeah"
|
|
>['at the end'] : number
|
|
>'at the end' : "at the end"
|
|
>14 : 14
|
|
}
|
|
// shortcut syntax
|
|
let a = 12;
|
|
>a : number
|
|
>12 : 12
|
|
|
|
let shortCutted: { a: number, b: string } = { ...o, a }
|
|
>shortCutted : { a: number; b: string; }
|
|
>a : number
|
|
>b : string
|
|
>{ ...o, a } : { a: number; b: string; }
|
|
>o : { a: number; b: string; }
|
|
>a : number
|
|
|
|
// non primitive
|
|
let spreadNonPrimitive = { ...<object>{}};
|
|
>spreadNonPrimitive : {}
|
|
>{ ...<object>{}} : {}
|
|
><object>{} : object
|
|
>{} : {}
|
|
|