TypeScript/tests/baselines/reference/constAssertions.types
Anders Hejlsberg 6aeb8c12cc
Preserve type aliases for union and intersection types (#42149)
* Create separate types for equivalent aliased unions

* Accept new baselines

* Preserve original types for union types

* Accept new baselines

* Preserve intersection origin for union types

* Accept new baselines

* Accept new baselines

* Preserve aliases during relationship checks

* Accept new baselines

* Preserve aliases for intersection and indexed access types

* Accept new baselines

* Compute intersection-of-unions cross product without recursion

* Accept new baselines

* Use denormalized type objects for origin / support 'keyof' origins

* Accept new baselines

* Fix fourslash test

* Recursively extract named union types

* Accept new baselines

* Map on union origin in mapType to better preserve aliases and origins

* Remove redundant call

* Accept new baselines

* Revert back to declared type when branches produce equivalent union

* Accept new baselines

* Don't include denormal origin types in regular type statistics

* Fix issue with unions not being marked primitive-only

* Allow new alias to be associated with type alias instantiation

* Accept new baselines

* Revert "Accept new baselines"

This reverts commit 4507270cc1.

* Revert "Allow new alias to be associated with type alias instantiation"

This reverts commit 2c2d06dfe1.
2021-01-08 15:19:58 -10:00

543 lines
14 KiB
Plaintext

=== tests/cases/conformance/expressions/typeAssertions/constAssertions.ts ===
let v1 = 'abc' as const;
>v1 : "abc"
>'abc' as const : "abc"
>'abc' : "abc"
let v2 = `abc` as const;
>v2 : "abc"
>`abc` as const : "abc"
>`abc` : "abc"
let v3 = 10 as const;
>v3 : 10
>10 as const : 10
>10 : 10
let v4 = -10 as const;
>v4 : -10
>-10 as const : -10
>-10 : -10
>10 : 10
let v5 = +10 as const;
>v5 : 10
>+10 as const : 10
>+10 : 10
>10 : 10
let v6 = 10n as const;
>v6 : 10n
>10n as const : 10n
>10n : 10n
let v7 = -10n as const;
>v7 : -10n
>-10n as const : -10n
>-10n : -10n
>10n : 10n
let v8 = true as const;
>v8 : true
>true as const : true
>true : true
let v9 = false as const;
>v9 : false
>false as const : false
>false : false
let c1 = 'abc' as const;
>c1 : "abc"
>'abc' as const : "abc"
>'abc' : "abc"
let c2 = `abc` as const;
>c2 : "abc"
>`abc` as const : "abc"
>`abc` : "abc"
let c3 = 10 as const;
>c3 : 10
>10 as const : 10
>10 : 10
let c4 = -10 as const;
>c4 : -10
>-10 as const : -10
>-10 : -10
>10 : 10
let c5 = +10 as const;
>c5 : 10
>+10 as const : 10
>+10 : 10
>10 : 10
let c6 = 10n as const;
>c6 : 10n
>10n as const : 10n
>10n : 10n
let c7 = -10n as const;
>c7 : -10n
>-10n as const : -10n
>-10n : -10n
>10n : 10n
let c8 = true as const;
>c8 : true
>true as const : true
>true : true
let c9 = false as const;
>c9 : false
>false as const : false
>false : false
let vv1 = v1;
>vv1 : "abc"
>v1 : "abc"
let vc1 = c1;
>vc1 : "abc"
>c1 : "abc"
let a1 = [] as const;
>a1 : readonly []
>[] as const : readonly []
>[] : readonly []
let a2 = [1, 2, 3] as const;
>a2 : readonly [1, 2, 3]
>[1, 2, 3] as const : readonly [1, 2, 3]
>[1, 2, 3] : readonly [1, 2, 3]
>1 : 1
>2 : 2
>3 : 3
let a3 = [10, 'hello', true] as const;
>a3 : readonly [10, "hello", true]
>[10, 'hello', true] as const : readonly [10, "hello", true]
>[10, 'hello', true] : readonly [10, "hello", true]
>10 : 10
>'hello' : "hello"
>true : true
let a4 = [...[1, 2, 3]] as const;
>a4 : readonly [1, 2, 3]
>[...[1, 2, 3]] as const : readonly [1, 2, 3]
>[...[1, 2, 3]] : readonly [1, 2, 3]
>...[1, 2, 3] : 1 | 2 | 3
>[1, 2, 3] : readonly [1, 2, 3]
>1 : 1
>2 : 2
>3 : 3
let a5 = [1, 2, 3];
>a5 : number[]
>[1, 2, 3] : number[]
>1 : 1
>2 : 2
>3 : 3
let a6 = [...a5] as const;
>a6 : readonly number[]
>[...a5] as const : readonly number[]
>[...a5] : readonly number[]
>...a5 : number
>a5 : number[]
let a7 = [...a6];
>a7 : number[]
>[...a6] : number[]
>...a6 : number
>a6 : readonly number[]
let a8 = ['abc', ...a7] as const;
>a8 : readonly ["abc", ...number[]]
>['abc', ...a7] as const : readonly ["abc", ...number[]]
>['abc', ...a7] : readonly ["abc", ...number[]]
>'abc' : "abc"
>...a7 : number
>a7 : number[]
let a9 = [...a8];
>a9 : (number | "abc")[]
>[...a8] : (number | "abc")[]
>...a8 : number | "abc"
>a8 : readonly ["abc", ...number[]]
declare let d: { [x: string]: string };
>d : { [x: string]: string; }
>x : string
let o1 = { x: 10, y: 20 } as const;
>o1 : { readonly x: 10; readonly y: 20; }
>{ x: 10, y: 20 } as const : { readonly x: 10; readonly y: 20; }
>{ x: 10, y: 20 } : { readonly x: 10; readonly y: 20; }
>x : 10
>10 : 10
>y : 20
>20 : 20
let o2 = { a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } as const;
>o2 : { readonly [x: string]: 1 | 2 | 3 | (() => void) | 4; readonly a: 1; readonly b: 2; readonly c: 3; readonly d: () => void; }
>{ a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } as const : { readonly [x: string]: 1 | 2 | 3 | (() => void) | 4; readonly a: 1; readonly b: 2; readonly c: 3; readonly d: () => void; }
>{ a: 1, 'b': 2, ['c']: 3, d() {}, ['e' + '']: 4 } : { readonly [x: string]: 1 | 2 | 3 | (() => void) | 4; readonly a: 1; readonly b: 2; readonly c: 3; readonly d: () => void; }
>a : 1
>1 : 1
>'b' : 2
>2 : 2
>['c'] : 3
>'c' : "c"
>3 : 3
>d : () => void
>['e' + ''] : 4
>'e' + '' : string
>'e' : "e"
>'' : ""
>4 : 4
let o3 = { ...o1, ...o2 } as const;
>o3 : { readonly a: 1; readonly b: 2; readonly c: 3; readonly d: () => void; readonly x: 10; readonly y: 20; }
>{ ...o1, ...o2 } as const : { readonly a: 1; readonly b: 2; readonly c: 3; readonly d: () => void; readonly x: 10; readonly y: 20; }
>{ ...o1, ...o2 } : { readonly a: 1; readonly b: 2; readonly c: 3; readonly d: () => void; readonly x: 10; readonly y: 20; }
>o1 : { readonly x: 10; readonly y: 20; }
>o2 : { readonly [x: string]: 1 | 2 | 3 | (() => void) | 4; readonly a: 1; readonly b: 2; readonly c: 3; readonly d: () => void; }
let o4 = { a: 1, b: 2 };
>o4 : { a: number; b: number; }
>{ a: 1, b: 2 } : { a: number; b: number; }
>a : number
>1 : 1
>b : number
>2 : 2
let o5 = { ...o4 } as const;
>o5 : { readonly a: number; readonly b: number; }
>{ ...o4 } as const : { readonly a: number; readonly b: number; }
>{ ...o4 } : { readonly a: number; readonly b: number; }
>o4 : { a: number; b: number; }
let o6 = { ...o5 };
>o6 : { a: number; b: number; }
>{ ...o5 } : { a: number; b: number; }
>o5 : { readonly a: number; readonly b: number; }
let o7 = { ...d } as const;
>o7 : { readonly [x: string]: string; }
>{ ...d } as const : { readonly [x: string]: string; }
>{ ...d } : { readonly [x: string]: string; }
>d : { [x: string]: string; }
let o8 = { ...o7 };
>o8 : { [x: string]: string; }
>{ ...o7 } : { [x: string]: string; }
>o7 : { readonly [x: string]: string; }
let o9 = { x: 10, foo() { this.x = 20 } } as const; // Error
>o9 : { readonly x: 10; readonly foo: () => void; }
>{ x: 10, foo() { this.x = 20 } } as const : { readonly x: 10; readonly foo: () => void; }
>{ x: 10, foo() { this.x = 20 } } : { readonly x: 10; readonly foo: () => void; }
>x : 10
>10 : 10
>foo : () => void
>this.x = 20 : 20
>this.x : any
>this : { readonly x: 10; readonly foo: () => void; }
>x : any
>20 : 20
let p1 = (10) as const;
>p1 : 10
>(10) as const : 10
>(10) : 10
>10 : 10
let p2 = ((-10)) as const;
>p2 : -10
>((-10)) as const : -10
>((-10)) : -10
>(-10) : -10
>-10 : -10
>10 : 10
let p3 = ([(10)]) as const;
>p3 : readonly [10]
>([(10)]) as const : readonly [10]
>([(10)]) : readonly [10]
>[(10)] : readonly [10]
>(10) : 10
>10 : 10
let p4 = [[[[10]]]] as const;
>p4 : readonly [readonly [readonly [readonly [10]]]]
>[[[[10]]]] as const : readonly [readonly [readonly [readonly [10]]]]
>[[[[10]]]] : readonly [readonly [readonly [readonly [10]]]]
>[[[10]]] : readonly [readonly [readonly [10]]]
>[[10]] : readonly [readonly [10]]
>[10] : readonly [10]
>10 : 10
let x1 = { x: 10, y: [20, 30], z: { a: { b: 42 } } } as const;
>x1 : { readonly x: 10; readonly y: readonly [20, 30]; readonly z: { readonly a: { readonly b: 42; }; }; }
>{ x: 10, y: [20, 30], z: { a: { b: 42 } } } as const : { readonly x: 10; readonly y: readonly [20, 30]; readonly z: { readonly a: { readonly b: 42; }; }; }
>{ x: 10, y: [20, 30], z: { a: { b: 42 } } } : { readonly x: 10; readonly y: readonly [20, 30]; readonly z: { readonly a: { readonly b: 42; }; }; }
>x : 10
>10 : 10
>y : readonly [20, 30]
>[20, 30] : readonly [20, 30]
>20 : 20
>30 : 30
>z : { readonly a: { readonly b: 42; }; }
>{ a: { b: 42 } } : { readonly a: { readonly b: 42; }; }
>a : { readonly b: 42; }
>{ b: 42 } : { readonly b: 42; }
>b : 42
>42 : 42
let q1 = <const> 10;
>q1 : 10
><const> 10 : 10
>10 : 10
let q2 = <const> 'abc';
>q2 : "abc"
><const> 'abc' : "abc"
>'abc' : "abc"
let q3 = <const> true;
>q3 : true
><const> true : true
>true : true
let q4 = <const> [1, 2, 3];
>q4 : readonly [1, 2, 3]
><const> [1, 2, 3] : readonly [1, 2, 3]
>[1, 2, 3] : readonly [1, 2, 3]
>1 : 1
>2 : 2
>3 : 3
let q5 = <const> { x: 10, y: 20 };
>q5 : { readonly x: 10; readonly y: 20; }
><const> { x: 10, y: 20 } : { readonly x: 10; readonly y: 20; }
>{ x: 10, y: 20 } : { readonly x: 10; readonly y: 20; }
>x : 10
>10 : 10
>y : 20
>20 : 20
declare function id<T>(x: T): T;
>id : <T>(x: T) => T
>x : T
let e1 = v1 as const; // Error
>e1 : "abc"
>v1 as const : "abc"
>v1 : "abc"
let e2 = (true ? 1 : 0) as const; // Error
>e2 : 0 | 1
>(true ? 1 : 0) as const : 0 | 1
>(true ? 1 : 0) : 0 | 1
>true ? 1 : 0 : 0 | 1
>true : true
>1 : 1
>0 : 0
let e3 = id(1) as const; // Error
>e3 : 1
>id(1) as const : 1
>id(1) : 1
>id : <T>(x: T) => T
>1 : 1
let t1 = 'foo' as const;
>t1 : "foo"
>'foo' as const : "foo"
>'foo' : "foo"
let t2 = 'bar' as const;
>t2 : "bar"
>'bar' as const : "bar"
>'bar' : "bar"
let t3 = `${t1}-${t2}` as const;
>t3 : "foo-bar"
>`${t1}-${t2}` as const : "foo-bar"
>`${t1}-${t2}` : "foo-bar"
>t1 : "foo"
>t2 : "bar"
let t4 = `${`(${t1})`}-${`(${t2})`}` as const;
>t4 : "(foo)-(bar)"
>`${`(${t1})`}-${`(${t2})`}` as const : "(foo)-(bar)"
>`${`(${t1})`}-${`(${t2})`}` : "(foo)-(bar)"
>`(${t1})` : "(foo)"
>t1 : "foo"
>`(${t2})` : "(bar)"
>t2 : "bar"
function ff1(x: 'foo' | 'bar', y: 1 | 2) {
>ff1 : (x: 'foo' | 'bar', y: 1 | 2) => "foo-1" | "foo-2" | "bar-1" | "bar-2"
>x : "foo" | "bar"
>y : 1 | 2
return `${x}-${y}` as const;
>`${x}-${y}` as const : "foo-1" | "foo-2" | "bar-1" | "bar-2"
>`${x}-${y}` : "foo-1" | "foo-2" | "bar-1" | "bar-2"
>x : "foo" | "bar"
>y : 1 | 2
}
function ff2<T extends string, U extends string>(x: T, y: U) {
>ff2 : <T extends string, U extends string>(x: T, y: U) => `${T}-${U}`
>x : T
>y : U
return `${x}-${y}` as const;
>`${x}-${y}` as const : `${T}-${U}`
>`${x}-${y}` : `${T}-${U}`
>x : T
>y : U
}
const ts1 = ff2('foo', 'bar');
>ts1 : "foo-bar"
>ff2('foo', 'bar') : "foo-bar"
>ff2 : <T extends string, U extends string>(x: T, y: U) => `${T}-${U}`
>'foo' : "foo"
>'bar' : "bar"
const ts2 = ff2('foo', !!true ? '0' : '1');
>ts2 : "foo-1" | "foo-0"
>ff2('foo', !!true ? '0' : '1') : "foo-1" | "foo-0"
>ff2 : <T extends string, U extends string>(x: T, y: U) => `${T}-${U}`
>'foo' : "foo"
>!!true ? '0' : '1' : "0" | "1"
>!!true : true
>!true : false
>true : true
>'0' : "0"
>'1' : "1"
const ts3 = ff2(!!true ? 'top' : 'bottom', !!true ? 'left' : 'right');
>ts3 : "top-left" | "top-right" | "bottom-left" | "bottom-right"
>ff2(!!true ? 'top' : 'bottom', !!true ? 'left' : 'right') : "top-left" | "top-right" | "bottom-left" | "bottom-right"
>ff2 : <T extends string, U extends string>(x: T, y: U) => `${T}-${U}`
>!!true ? 'top' : 'bottom' : "top" | "bottom"
>!!true : true
>!true : false
>true : true
>'top' : "top"
>'bottom' : "bottom"
>!!true ? 'left' : 'right' : "left" | "right"
>!!true : true
>!true : false
>true : true
>'left' : "left"
>'right' : "right"
function ff3(x: 'foo' | 'bar', y: object) {
>ff3 : (x: 'foo' | 'bar', y: object) => `foo${string}` | `bar${string}`
>x : "foo" | "bar"
>y : object
return `${x}${y}` as const;
>`${x}${y}` as const : `foo${string}` | `bar${string}`
>`${x}${y}` : `foo${string}` | `bar${string}`
>x : "foo" | "bar"
>y : object
}
type Action = "verify" | "write";
>Action : Action
type ContentMatch = "match" | "nonMatch";
>ContentMatch : ContentMatch
type Outcome = `${Action}_${ContentMatch}`;
>Outcome : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
function ff4(verify: boolean, contentMatches: boolean) {
>ff4 : (verify: boolean, contentMatches: boolean) => "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
>verify : boolean
>contentMatches : boolean
const action : Action = verify ? `verify` : `write`;
>action : Action
>verify ? `verify` : `write` : "verify" | "write"
>verify : boolean
>`verify` : "verify"
>`write` : "write"
const contentMatch: ContentMatch = contentMatches ? `match` : `nonMatch`;
>contentMatch : ContentMatch
>contentMatches ? `match` : `nonMatch` : "match" | "nonMatch"
>contentMatches : boolean
>`match` : "match"
>`nonMatch` : "nonMatch"
const outcome: Outcome = `${action}_${contentMatch}` as const;
>outcome : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
>`${action}_${contentMatch}` as const : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
>`${action}_${contentMatch}` : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
>action : Action
>contentMatch : ContentMatch
return outcome;
>outcome : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
}
function ff5(verify: boolean, contentMatches: boolean) {
>ff5 : (verify: boolean, contentMatches: boolean) => "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
>verify : boolean
>contentMatches : boolean
const action = verify ? `verify` : `write`;
>action : "verify" | "write"
>verify ? `verify` : `write` : "verify" | "write"
>verify : boolean
>`verify` : "verify"
>`write` : "write"
const contentMatch = contentMatches ? `match` : `nonMatch`;
>contentMatch : "match" | "nonMatch"
>contentMatches ? `match` : `nonMatch` : "match" | "nonMatch"
>contentMatches : boolean
>`match` : "match"
>`nonMatch` : "nonMatch"
const outcome = `${action}_${contentMatch}` as const;
>outcome : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
>`${action}_${contentMatch}` as const : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
>`${action}_${contentMatch}` : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
>action : "verify" | "write"
>contentMatch : "match" | "nonMatch"
return outcome;
>outcome : "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch"
}
function accessorNames<S extends string>(propName: S) {
>accessorNames : <S extends string>(propName: S) => readonly [`get-${S}`, `set-${S}`]
>propName : S
return [`get-${propName}`, `set-${propName}`] as const;
>[`get-${propName}`, `set-${propName}`] as const : readonly [`get-${S}`, `set-${S}`]
>[`get-${propName}`, `set-${propName}`] : readonly [`get-${S}`, `set-${S}`]
>`get-${propName}` : `get-${S}`
>propName : S
>`set-${propName}` : `set-${S}`
>propName : S
}
const ns1 = accessorNames('foo');
>ns1 : readonly ["get-foo", "set-foo"]
>accessorNames('foo') : readonly ["get-foo", "set-foo"]
>accessorNames : <S extends string>(propName: S) => readonly [`get-${S}`, `set-${S}`]
>'foo' : "foo"