fix: [Symbol.iterator]() lost on union with never (#62661)

This commit is contained in:
Nico Rainhart 2025-11-10 20:11:13 -03:00 committed by GitHub
parent efca03ffed
commit 48244d89f8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 539 additions and 0 deletions

View File

@ -45842,6 +45842,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
* the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method.
*/
function getIterationTypesOfIterable(type: Type, use: IterationUse, errorNode: Node | undefined) {
type = getReducedType(type);
if (type === silentNeverType) {
return silentNeverIterationTypes;
}

View File

@ -0,0 +1,94 @@
//// [tests/cases/compiler/iterableWithNeverAsUnionMember.ts] ////
=== iterableWithNeverAsUnionMember.ts ===
declare const o1: { a: "foo" } & { a: "bar" };
>o1 : Symbol(o1, Decl(iterableWithNeverAsUnionMember.ts, 0, 13))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 0, 19))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 0, 34))
const [el1] = o1; // error
>el1 : Symbol(el1, Decl(iterableWithNeverAsUnionMember.ts, 1, 7))
>o1 : Symbol(o1, Decl(iterableWithNeverAsUnionMember.ts, 0, 13))
// https://github.com/microsoft/TypeScript/issues/62462
declare var x: number[] | ({ t: "a" } & { t: "b" });
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 4, 11))
>t : Symbol(t, Decl(iterableWithNeverAsUnionMember.ts, 4, 28))
>t : Symbol(t, Decl(iterableWithNeverAsUnionMember.ts, 4, 41))
let [el2] = x; // ok
>el2 : Symbol(el2, Decl(iterableWithNeverAsUnionMember.ts, 5, 5))
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 4, 11))
for (const elem of x) { // ok
>elem : Symbol(elem, Decl(iterableWithNeverAsUnionMember.ts, 7, 10))
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 4, 11))
elem.toFixed();
>elem.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
>elem : Symbol(elem, Decl(iterableWithNeverAsUnionMember.ts, 7, 10))
>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
}
type Shape =
>Shape : Symbol(Shape, Decl(iterableWithNeverAsUnionMember.ts, 9, 1))
| { kind: "circle"; radius: number }
>kind : Symbol(kind, Decl(iterableWithNeverAsUnionMember.ts, 12, 5))
>radius : Symbol(radius, Decl(iterableWithNeverAsUnionMember.ts, 12, 21))
| { kind: "rectangle"; width: number; height: number };
>kind : Symbol(kind, Decl(iterableWithNeverAsUnionMember.ts, 13, 5))
>width : Symbol(width, Decl(iterableWithNeverAsUnionMember.ts, 13, 24))
>height : Symbol(height, Decl(iterableWithNeverAsUnionMember.ts, 13, 39))
type Circle = Shape & { kind: "circle" };
>Circle : Symbol(Circle, Decl(iterableWithNeverAsUnionMember.ts, 13, 57))
>Shape : Symbol(Shape, Decl(iterableWithNeverAsUnionMember.ts, 9, 1))
>kind : Symbol(kind, Decl(iterableWithNeverAsUnionMember.ts, 15, 23))
function doStuffWithCircle(arg: Circle | [Circle, (newValue: Circle) => void]) {
>doStuffWithCircle : Symbol(doStuffWithCircle, Decl(iterableWithNeverAsUnionMember.ts, 15, 41))
>arg : Symbol(arg, Decl(iterableWithNeverAsUnionMember.ts, 17, 27))
>Circle : Symbol(Circle, Decl(iterableWithNeverAsUnionMember.ts, 13, 57))
>Circle : Symbol(Circle, Decl(iterableWithNeverAsUnionMember.ts, 13, 57))
>newValue : Symbol(newValue, Decl(iterableWithNeverAsUnionMember.ts, 17, 51))
>Circle : Symbol(Circle, Decl(iterableWithNeverAsUnionMember.ts, 13, 57))
if (Array.isArray(arg)) {
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(iterableWithNeverAsUnionMember.ts, 17, 27))
let [value, setValue] = arg; // ok
>value : Symbol(value, Decl(iterableWithNeverAsUnionMember.ts, 19, 9))
>setValue : Symbol(setValue, Decl(iterableWithNeverAsUnionMember.ts, 19, 15))
>arg : Symbol(arg, Decl(iterableWithNeverAsUnionMember.ts, 17, 27))
}
}
function f1<T extends { a: "foo" } & { a: "bar" }>(x: T) {
>f1 : Symbol(f1, Decl(iterableWithNeverAsUnionMember.ts, 21, 1))
>T : Symbol(T, Decl(iterableWithNeverAsUnionMember.ts, 23, 12))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 23, 23))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 23, 38))
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 23, 51))
>T : Symbol(T, Decl(iterableWithNeverAsUnionMember.ts, 23, 12))
let [y] = x; // error
>y : Symbol(y, Decl(iterableWithNeverAsUnionMember.ts, 24, 7))
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 23, 51))
}
declare const o2: ({ a: "foo" } & { a: "bar" }) | ({ b: "qwe" } & { b: "rty" });
>o2 : Symbol(o2, Decl(iterableWithNeverAsUnionMember.ts, 27, 13))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 27, 20))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 27, 35))
>b : Symbol(b, Decl(iterableWithNeverAsUnionMember.ts, 27, 52))
>b : Symbol(b, Decl(iterableWithNeverAsUnionMember.ts, 27, 67))
const [el3] = o2; // error
>el3 : Symbol(el3, Decl(iterableWithNeverAsUnionMember.ts, 28, 7))
>o2 : Symbol(o2, Decl(iterableWithNeverAsUnionMember.ts, 27, 13))

View File

@ -0,0 +1,138 @@
//// [tests/cases/compiler/iterableWithNeverAsUnionMember.ts] ////
=== iterableWithNeverAsUnionMember.ts ===
declare const o1: { a: "foo" } & { a: "bar" };
>o1 : never
> : ^^^^^
>a : "foo"
> : ^^^^^
>a : "bar"
> : ^^^^^
const [el1] = o1; // error
>el1 : never
> : ^^^^^
>o1 : never
> : ^^^^^
// https://github.com/microsoft/TypeScript/issues/62462
declare var x: number[] | ({ t: "a" } & { t: "b" });
>x : number[]
> : ^^^^^^^^
>t : "a"
> : ^^^
>t : "b"
> : ^^^
let [el2] = x; // ok
>el2 : number
> : ^^^^^^
>x : number[]
> : ^^^^^^^^
for (const elem of x) { // ok
>elem : number
> : ^^^^^^
>x : number[]
> : ^^^^^^^^
elem.toFixed();
>elem.toFixed() : string
> : ^^^^^^
>elem.toFixed : (fractionDigits?: number) => string
> : ^ ^^^ ^^^^^
>elem : number
> : ^^^^^^
>toFixed : (fractionDigits?: number) => string
> : ^ ^^^ ^^^^^
}
type Shape =
>Shape : Shape
> : ^^^^^
| { kind: "circle"; radius: number }
>kind : "circle"
> : ^^^^^^^^
>radius : number
> : ^^^^^^
| { kind: "rectangle"; width: number; height: number };
>kind : "rectangle"
> : ^^^^^^^^^^^
>width : number
> : ^^^^^^
>height : number
> : ^^^^^^
type Circle = Shape & { kind: "circle" };
>Circle : { kind: "circle"; radius: number; } & { kind: "circle"; }
> : ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^
>kind : "circle"
> : ^^^^^^^^
function doStuffWithCircle(arg: Circle | [Circle, (newValue: Circle) => void]) {
>doStuffWithCircle : (arg: Circle | [Circle, (newValue: Circle) => void]) => void
> : ^ ^^ ^^^^^^^^^
>arg : ({ kind: "circle"; radius: number; } & { kind: "circle"; }) | [{ kind: "circle"; radius: number; } & { kind: "circle"; }, (newValue: Circle) => void]
> : ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^ ^^ ^^^^^ ^
>newValue : { kind: "circle"; radius: number; } & { kind: "circle"; }
> : ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^
if (Array.isArray(arg)) {
>Array.isArray(arg) : boolean
> : ^^^^^^^
>Array.isArray : (arg: any) => arg is any[]
> : ^ ^^ ^^^^^
>Array : ArrayConstructor
> : ^^^^^^^^^^^^^^^^
>isArray : (arg: any) => arg is any[]
> : ^ ^^ ^^^^^
>arg : ({ kind: "circle"; radius: number; } & { kind: "circle"; }) | [{ kind: "circle"; radius: number; } & { kind: "circle"; }, (newValue: Circle) => void]
> : ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^ ^^ ^^^^^ ^
let [value, setValue] = arg; // ok
>value : { kind: "circle"; radius: number; } & { kind: "circle"; }
> : ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^
>setValue : (newValue: Circle) => void
> : ^ ^^ ^^^^^
>arg : [{ kind: "circle"; radius: number; } & { kind: "circle"; }, (newValue: Circle) => void]
> : ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^ ^^ ^^^^^ ^
}
}
function f1<T extends { a: "foo" } & { a: "bar" }>(x: T) {
>f1 : <T extends { a: "foo"; } & { a: "bar"; }>(x: T) => void
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^
>a : "foo"
> : ^^^^^
>a : "bar"
> : ^^^^^
>x : T
> : ^
let [y] = x; // error
>y : never
> : ^^^^^
>x : T
> : ^
}
declare const o2: ({ a: "foo" } & { a: "bar" }) | ({ b: "qwe" } & { b: "rty" });
>o2 : never
> : ^^^^^
>a : "foo"
> : ^^^^^
>a : "bar"
> : ^^^^^
>b : "qwe"
> : ^^^^^
>b : "rty"
> : ^^^^^
const [el3] = o2; // error
>el3 : never
> : ^^^^^
>o2 : never
> : ^^^^^

View File

@ -0,0 +1,41 @@
iterableWithNeverAsUnionMember.ts(2,7): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
iterableWithNeverAsUnionMember.ts(25,7): error TS2488: Type 'T' must have a '[Symbol.iterator]()' method that returns an iterator.
iterableWithNeverAsUnionMember.ts(29,7): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
==== iterableWithNeverAsUnionMember.ts (3 errors) ====
declare const o1: { a: "foo" } & { a: "bar" };
const [el1] = o1; // error
~~~~~
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
// https://github.com/microsoft/TypeScript/issues/62462
declare var x: number[] | ({ t: "a" } & { t: "b" });
let [el2] = x; // ok
for (const elem of x) { // ok
elem.toFixed();
}
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rectangle"; width: number; height: number };
type Circle = Shape & { kind: "circle" };
function doStuffWithCircle(arg: Circle | [Circle, (newValue: Circle) => void]) {
if (Array.isArray(arg)) {
let [value, setValue] = arg; // ok
}
}
function f1<T extends { a: "foo" } & { a: "bar" }>(x: T) {
let [y] = x; // error
~~~
!!! error TS2488: Type 'T' must have a '[Symbol.iterator]()' method that returns an iterator.
}
declare const o2: ({ a: "foo" } & { a: "bar" }) | ({ b: "qwe" } & { b: "rty" });
const [el3] = o2; // error
~~~~~
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.

View File

@ -0,0 +1,94 @@
//// [tests/cases/compiler/iterableWithNeverAsUnionMember.ts] ////
=== iterableWithNeverAsUnionMember.ts ===
declare const o1: { a: "foo" } & { a: "bar" };
>o1 : Symbol(o1, Decl(iterableWithNeverAsUnionMember.ts, 0, 13))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 0, 19))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 0, 34))
const [el1] = o1; // error
>el1 : Symbol(el1, Decl(iterableWithNeverAsUnionMember.ts, 1, 7))
>o1 : Symbol(o1, Decl(iterableWithNeverAsUnionMember.ts, 0, 13))
// https://github.com/microsoft/TypeScript/issues/62462
declare var x: number[] | ({ t: "a" } & { t: "b" });
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 4, 11))
>t : Symbol(t, Decl(iterableWithNeverAsUnionMember.ts, 4, 28))
>t : Symbol(t, Decl(iterableWithNeverAsUnionMember.ts, 4, 41))
let [el2] = x; // ok
>el2 : Symbol(el2, Decl(iterableWithNeverAsUnionMember.ts, 5, 5))
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 4, 11))
for (const elem of x) { // ok
>elem : Symbol(elem, Decl(iterableWithNeverAsUnionMember.ts, 7, 10))
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 4, 11))
elem.toFixed();
>elem.toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
>elem : Symbol(elem, Decl(iterableWithNeverAsUnionMember.ts, 7, 10))
>toFixed : Symbol(Number.toFixed, Decl(lib.es5.d.ts, --, --))
}
type Shape =
>Shape : Symbol(Shape, Decl(iterableWithNeverAsUnionMember.ts, 9, 1))
| { kind: "circle"; radius: number }
>kind : Symbol(kind, Decl(iterableWithNeverAsUnionMember.ts, 12, 5))
>radius : Symbol(radius, Decl(iterableWithNeverAsUnionMember.ts, 12, 21))
| { kind: "rectangle"; width: number; height: number };
>kind : Symbol(kind, Decl(iterableWithNeverAsUnionMember.ts, 13, 5))
>width : Symbol(width, Decl(iterableWithNeverAsUnionMember.ts, 13, 24))
>height : Symbol(height, Decl(iterableWithNeverAsUnionMember.ts, 13, 39))
type Circle = Shape & { kind: "circle" };
>Circle : Symbol(Circle, Decl(iterableWithNeverAsUnionMember.ts, 13, 57))
>Shape : Symbol(Shape, Decl(iterableWithNeverAsUnionMember.ts, 9, 1))
>kind : Symbol(kind, Decl(iterableWithNeverAsUnionMember.ts, 15, 23))
function doStuffWithCircle(arg: Circle | [Circle, (newValue: Circle) => void]) {
>doStuffWithCircle : Symbol(doStuffWithCircle, Decl(iterableWithNeverAsUnionMember.ts, 15, 41))
>arg : Symbol(arg, Decl(iterableWithNeverAsUnionMember.ts, 17, 27))
>Circle : Symbol(Circle, Decl(iterableWithNeverAsUnionMember.ts, 13, 57))
>Circle : Symbol(Circle, Decl(iterableWithNeverAsUnionMember.ts, 13, 57))
>newValue : Symbol(newValue, Decl(iterableWithNeverAsUnionMember.ts, 17, 51))
>Circle : Symbol(Circle, Decl(iterableWithNeverAsUnionMember.ts, 13, 57))
if (Array.isArray(arg)) {
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 4 more)
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.es5.d.ts, --, --))
>arg : Symbol(arg, Decl(iterableWithNeverAsUnionMember.ts, 17, 27))
let [value, setValue] = arg; // ok
>value : Symbol(value, Decl(iterableWithNeverAsUnionMember.ts, 19, 9))
>setValue : Symbol(setValue, Decl(iterableWithNeverAsUnionMember.ts, 19, 15))
>arg : Symbol(arg, Decl(iterableWithNeverAsUnionMember.ts, 17, 27))
}
}
function f1<T extends { a: "foo" } & { a: "bar" }>(x: T) {
>f1 : Symbol(f1, Decl(iterableWithNeverAsUnionMember.ts, 21, 1))
>T : Symbol(T, Decl(iterableWithNeverAsUnionMember.ts, 23, 12))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 23, 23))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 23, 38))
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 23, 51))
>T : Symbol(T, Decl(iterableWithNeverAsUnionMember.ts, 23, 12))
let [y] = x; // error
>y : Symbol(y, Decl(iterableWithNeverAsUnionMember.ts, 24, 7))
>x : Symbol(x, Decl(iterableWithNeverAsUnionMember.ts, 23, 51))
}
declare const o2: ({ a: "foo" } & { a: "bar" }) | ({ b: "qwe" } & { b: "rty" });
>o2 : Symbol(o2, Decl(iterableWithNeverAsUnionMember.ts, 27, 13))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 27, 20))
>a : Symbol(a, Decl(iterableWithNeverAsUnionMember.ts, 27, 35))
>b : Symbol(b, Decl(iterableWithNeverAsUnionMember.ts, 27, 52))
>b : Symbol(b, Decl(iterableWithNeverAsUnionMember.ts, 27, 67))
const [el3] = o2; // error
>el3 : Symbol(el3, Decl(iterableWithNeverAsUnionMember.ts, 28, 7))
>o2 : Symbol(o2, Decl(iterableWithNeverAsUnionMember.ts, 27, 13))

View File

@ -0,0 +1,138 @@
//// [tests/cases/compiler/iterableWithNeverAsUnionMember.ts] ////
=== iterableWithNeverAsUnionMember.ts ===
declare const o1: { a: "foo" } & { a: "bar" };
>o1 : never
> : ^^^^^
>a : "foo"
> : ^^^^^
>a : "bar"
> : ^^^^^
const [el1] = o1; // error
>el1 : never
> : ^^^^^
>o1 : never
> : ^^^^^
// https://github.com/microsoft/TypeScript/issues/62462
declare var x: number[] | ({ t: "a" } & { t: "b" });
>x : number[]
> : ^^^^^^^^
>t : "a"
> : ^^^
>t : "b"
> : ^^^
let [el2] = x; // ok
>el2 : number
> : ^^^^^^
>x : number[]
> : ^^^^^^^^
for (const elem of x) { // ok
>elem : number
> : ^^^^^^
>x : number[]
> : ^^^^^^^^
elem.toFixed();
>elem.toFixed() : string
> : ^^^^^^
>elem.toFixed : (fractionDigits?: number) => string
> : ^ ^^^ ^^^^^
>elem : number
> : ^^^^^^
>toFixed : (fractionDigits?: number) => string
> : ^ ^^^ ^^^^^
}
type Shape =
>Shape : Shape
> : ^^^^^
| { kind: "circle"; radius: number }
>kind : "circle"
> : ^^^^^^^^
>radius : number
> : ^^^^^^
| { kind: "rectangle"; width: number; height: number };
>kind : "rectangle"
> : ^^^^^^^^^^^
>width : number
> : ^^^^^^
>height : number
> : ^^^^^^
type Circle = Shape & { kind: "circle" };
>Circle : { kind: "circle"; radius: number; } & { kind: "circle"; }
> : ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^
>kind : "circle"
> : ^^^^^^^^
function doStuffWithCircle(arg: Circle | [Circle, (newValue: Circle) => void]) {
>doStuffWithCircle : (arg: Circle | [Circle, (newValue: Circle) => void]) => void
> : ^ ^^ ^^^^^^^^^
>arg : ({ kind: "circle"; radius: number; } & { kind: "circle"; }) | [{ kind: "circle"; radius: number; } & { kind: "circle"; }, (newValue: Circle) => void]
> : ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^ ^^ ^^^^^ ^
>newValue : { kind: "circle"; radius: number; } & { kind: "circle"; }
> : ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^
if (Array.isArray(arg)) {
>Array.isArray(arg) : boolean
> : ^^^^^^^
>Array.isArray : (arg: any) => arg is any[]
> : ^ ^^ ^^^^^
>Array : ArrayConstructor
> : ^^^^^^^^^^^^^^^^
>isArray : (arg: any) => arg is any[]
> : ^ ^^ ^^^^^
>arg : ({ kind: "circle"; radius: number; } & { kind: "circle"; }) | [{ kind: "circle"; radius: number; } & { kind: "circle"; }, (newValue: Circle) => void]
> : ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^ ^^ ^^^^^ ^
let [value, setValue] = arg; // ok
>value : { kind: "circle"; radius: number; } & { kind: "circle"; }
> : ^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^
>setValue : (newValue: Circle) => void
> : ^ ^^ ^^^^^
>arg : [{ kind: "circle"; radius: number; } & { kind: "circle"; }, (newValue: Circle) => void]
> : ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^ ^^ ^^^^^ ^
}
}
function f1<T extends { a: "foo" } & { a: "bar" }>(x: T) {
>f1 : <T extends { a: "foo"; } & { a: "bar"; }>(x: T) => void
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^
>a : "foo"
> : ^^^^^
>a : "bar"
> : ^^^^^
>x : T
> : ^
let [y] = x; // error
>y : never
> : ^^^^^
>x : T
> : ^
}
declare const o2: ({ a: "foo" } & { a: "bar" }) | ({ b: "qwe" } & { b: "rty" });
>o2 : never
> : ^^^^^
>a : "foo"
> : ^^^^^
>a : "bar"
> : ^^^^^
>b : "qwe"
> : ^^^^^
>b : "rty"
> : ^^^^^
const [el3] = o2; // error
>el3 : never
> : ^^^^^
>o2 : never
> : ^^^^^

View File

@ -0,0 +1,33 @@
// @strict: true
// @noEmit: true
// @target: es5,esnext
declare const o1: { a: "foo" } & { a: "bar" };
const [el1] = o1; // error
// https://github.com/microsoft/TypeScript/issues/62462
declare var x: number[] | ({ t: "a" } & { t: "b" });
let [el2] = x; // ok
for (const elem of x) { // ok
elem.toFixed();
}
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rectangle"; width: number; height: number };
type Circle = Shape & { kind: "circle" };
function doStuffWithCircle(arg: Circle | [Circle, (newValue: Circle) => void]) {
if (Array.isArray(arg)) {
let [value, setValue] = arg; // ok
}
}
function f1<T extends { a: "foo" } & { a: "bar" }>(x: T) {
let [y] = x; // error
}
declare const o2: ({ a: "foo" } & { a: "bar" }) | ({ b: "qwe" } & { b: "rty" });
const [el3] = o2; // error