diff --git a/tests/baselines/reference/typeInferenceLiteralUnion.js b/tests/baselines/reference/typeInferenceLiteralUnion.js new file mode 100644 index 0000000000..07776d2606 --- /dev/null +++ b/tests/baselines/reference/typeInferenceLiteralUnion.js @@ -0,0 +1,59 @@ +//// [typeInferenceLiteralUnion.ts] +// Repro from #10901 +/** + * Administrivia: JavaScript primitive types and Date + */ +export type Primitive = number | string | boolean | Date; + +/** + * Administrivia: anything with a valueOf(): number method is comparable, so we allow it in numeric operations + */ +interface Numeric { + valueOf(): number; +} + +// Not very useful, but meets Numeric +class NumCoercible { + public a: number; + + constructor(a: number) { + this.a = a; + } + public valueOf() { + return this.a; + } +} + +/** + * Return the min and max simultaneously. + */ +export function extent(array: Array): [T | Primitive, T | Primitive] | [undefined, undefined] { + return [undefined, undefined]; +} + + +let extentMixed: [Primitive | NumCoercible, Primitive | NumCoercible] | [undefined, undefined]; +extentMixed = extent([new NumCoercible(10), 13, '12', true]); + + +//// [typeInferenceLiteralUnion.js] +"use strict"; +// Not very useful, but meets Numeric +var NumCoercible = (function () { + function NumCoercible(a) { + this.a = a; + } + NumCoercible.prototype.valueOf = function () { + return this.a; + }; + return NumCoercible; +}()); +/** + * Return the min and max simultaneously. + */ +function extent(array) { + return [undefined, undefined]; +} +exports.extent = extent; +var extentMixed; +extentMixed = extent([new NumCoercible(10), 13, '12', true]); diff --git a/tests/baselines/reference/typeInferenceLiteralUnion.symbols b/tests/baselines/reference/typeInferenceLiteralUnion.symbols new file mode 100644 index 0000000000..51fc4c828e --- /dev/null +++ b/tests/baselines/reference/typeInferenceLiteralUnion.symbols @@ -0,0 +1,79 @@ +=== tests/cases/compiler/typeInferenceLiteralUnion.ts === +// Repro from #10901 +/** + * Administrivia: JavaScript primitive types and Date + */ +export type Primitive = number | string | boolean | Date; +>Primitive : Symbol(Primitive, Decl(typeInferenceLiteralUnion.ts, 0, 0)) +>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +/** + * Administrivia: anything with a valueOf(): number method is comparable, so we allow it in numeric operations + */ +interface Numeric { +>Numeric : Symbol(Numeric, Decl(typeInferenceLiteralUnion.ts, 4, 57)) + + valueOf(): number; +>valueOf : Symbol(Numeric.valueOf, Decl(typeInferenceLiteralUnion.ts, 9, 19)) +} + +// Not very useful, but meets Numeric +class NumCoercible { +>NumCoercible : Symbol(NumCoercible, Decl(typeInferenceLiteralUnion.ts, 11, 1)) + + public a: number; +>a : Symbol(NumCoercible.a, Decl(typeInferenceLiteralUnion.ts, 14, 20)) + + constructor(a: number) { +>a : Symbol(a, Decl(typeInferenceLiteralUnion.ts, 17, 16)) + + this.a = a; +>this.a : Symbol(NumCoercible.a, Decl(typeInferenceLiteralUnion.ts, 14, 20)) +>this : Symbol(NumCoercible, Decl(typeInferenceLiteralUnion.ts, 11, 1)) +>a : Symbol(NumCoercible.a, Decl(typeInferenceLiteralUnion.ts, 14, 20)) +>a : Symbol(a, Decl(typeInferenceLiteralUnion.ts, 17, 16)) + } + public valueOf() { +>valueOf : Symbol(NumCoercible.valueOf, Decl(typeInferenceLiteralUnion.ts, 19, 5)) + + return this.a; +>this.a : Symbol(NumCoercible.a, Decl(typeInferenceLiteralUnion.ts, 14, 20)) +>this : Symbol(NumCoercible, Decl(typeInferenceLiteralUnion.ts, 11, 1)) +>a : Symbol(NumCoercible.a, Decl(typeInferenceLiteralUnion.ts, 14, 20)) + } +} + +/** + * Return the min and max simultaneously. + */ +export function extent(array: Array): [T | Primitive, T | Primitive] | [undefined, undefined] { +>extent : Symbol(extent, Decl(typeInferenceLiteralUnion.ts, 23, 1)) +>T : Symbol(T, Decl(typeInferenceLiteralUnion.ts, 28, 23)) +>Numeric : Symbol(Numeric, Decl(typeInferenceLiteralUnion.ts, 4, 57)) +>array : Symbol(array, Decl(typeInferenceLiteralUnion.ts, 28, 42)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(typeInferenceLiteralUnion.ts, 28, 23)) +>Primitive : Symbol(Primitive, Decl(typeInferenceLiteralUnion.ts, 0, 0)) +>T : Symbol(T, Decl(typeInferenceLiteralUnion.ts, 28, 23)) +>Primitive : Symbol(Primitive, Decl(typeInferenceLiteralUnion.ts, 0, 0)) +>T : Symbol(T, Decl(typeInferenceLiteralUnion.ts, 28, 23)) +>Primitive : Symbol(Primitive, Decl(typeInferenceLiteralUnion.ts, 0, 0)) + + return [undefined, undefined]; +>undefined : Symbol(undefined) +>undefined : Symbol(undefined) +} + + +let extentMixed: [Primitive | NumCoercible, Primitive | NumCoercible] | [undefined, undefined]; +>extentMixed : Symbol(extentMixed, Decl(typeInferenceLiteralUnion.ts, 33, 3)) +>Primitive : Symbol(Primitive, Decl(typeInferenceLiteralUnion.ts, 0, 0)) +>NumCoercible : Symbol(NumCoercible, Decl(typeInferenceLiteralUnion.ts, 11, 1)) +>Primitive : Symbol(Primitive, Decl(typeInferenceLiteralUnion.ts, 0, 0)) +>NumCoercible : Symbol(NumCoercible, Decl(typeInferenceLiteralUnion.ts, 11, 1)) + +extentMixed = extent([new NumCoercible(10), 13, '12', true]); +>extentMixed : Symbol(extentMixed, Decl(typeInferenceLiteralUnion.ts, 33, 3)) +>extent : Symbol(extent, Decl(typeInferenceLiteralUnion.ts, 23, 1)) +>NumCoercible : Symbol(NumCoercible, Decl(typeInferenceLiteralUnion.ts, 11, 1)) + diff --git a/tests/baselines/reference/typeInferenceLiteralUnion.types b/tests/baselines/reference/typeInferenceLiteralUnion.types new file mode 100644 index 0000000000..0416820604 --- /dev/null +++ b/tests/baselines/reference/typeInferenceLiteralUnion.types @@ -0,0 +1,89 @@ +=== tests/cases/compiler/typeInferenceLiteralUnion.ts === +// Repro from #10901 +/** + * Administrivia: JavaScript primitive types and Date + */ +export type Primitive = number | string | boolean | Date; +>Primitive : Primitive +>Date : Date + +/** + * Administrivia: anything with a valueOf(): number method is comparable, so we allow it in numeric operations + */ +interface Numeric { +>Numeric : Numeric + + valueOf(): number; +>valueOf : () => number +} + +// Not very useful, but meets Numeric +class NumCoercible { +>NumCoercible : NumCoercible + + public a: number; +>a : number + + constructor(a: number) { +>a : number + + this.a = a; +>this.a = a : number +>this.a : number +>this : this +>a : number +>a : number + } + public valueOf() { +>valueOf : () => number + + return this.a; +>this.a : number +>this : this +>a : number + } +} + +/** + * Return the min and max simultaneously. + */ +export function extent(array: Array): [T | Primitive, T | Primitive] | [undefined, undefined] { +>extent : (array: (string | number | boolean | Date | T)[]) => [string | number | boolean | Date | T, string | number | boolean | Date | T] | [undefined, undefined] +>T : T +>Numeric : Numeric +>array : (string | number | boolean | Date | T)[] +>Array : T[] +>T : T +>Primitive : Primitive +>T : T +>Primitive : Primitive +>T : T +>Primitive : Primitive + + return [undefined, undefined]; +>[undefined, undefined] : [undefined, undefined] +>undefined : undefined +>undefined : undefined +} + + +let extentMixed: [Primitive | NumCoercible, Primitive | NumCoercible] | [undefined, undefined]; +>extentMixed : [undefined, undefined] | [string | number | boolean | Date | NumCoercible, string | number | boolean | Date | NumCoercible] +>Primitive : Primitive +>NumCoercible : NumCoercible +>Primitive : Primitive +>NumCoercible : NumCoercible + +extentMixed = extent([new NumCoercible(10), 13, '12', true]); +>extentMixed = extent([new NumCoercible(10), 13, '12', true]) : [undefined, undefined] | [string | number | boolean | Date | NumCoercible, string | number | boolean | Date | NumCoercible] +>extentMixed : [undefined, undefined] | [string | number | boolean | Date | NumCoercible, string | number | boolean | Date | NumCoercible] +>extent([new NumCoercible(10), 13, '12', true]) : [undefined, undefined] | [string | number | boolean | Date | NumCoercible, string | number | boolean | Date | NumCoercible] +>extent : (array: (string | number | boolean | Date | T)[]) => [string | number | boolean | Date | T, string | number | boolean | Date | T] | [undefined, undefined] +>[new NumCoercible(10), 13, '12', true] : (true | NumCoercible | 13 | "12")[] +>new NumCoercible(10) : NumCoercible +>NumCoercible : typeof NumCoercible +>10 : 10 +>13 : 13 +>'12' : "12" +>true : true + diff --git a/tests/cases/compiler/typeInferenceLiteralUnion.ts b/tests/cases/compiler/typeInferenceLiteralUnion.ts new file mode 100644 index 0000000000..735954e96b --- /dev/null +++ b/tests/cases/compiler/typeInferenceLiteralUnion.ts @@ -0,0 +1,35 @@ +// Repro from #10901 +/** + * Administrivia: JavaScript primitive types and Date + */ +export type Primitive = number | string | boolean | Date; + +/** + * Administrivia: anything with a valueOf(): number method is comparable, so we allow it in numeric operations + */ +interface Numeric { + valueOf(): number; +} + +// Not very useful, but meets Numeric +class NumCoercible { + public a: number; + + constructor(a: number) { + this.a = a; + } + public valueOf() { + return this.a; + } +} + +/** + * Return the min and max simultaneously. + */ +export function extent(array: Array): [T | Primitive, T | Primitive] | [undefined, undefined] { + return [undefined, undefined]; +} + + +let extentMixed: [Primitive | NumCoercible, Primitive | NumCoercible] | [undefined, undefined]; +extentMixed = extent([new NumCoercible(10), 13, '12', true]);