microsoft / microsoft/TypeScript
Array.from(it: Iterable<X> | Iterable<Y>) fails; […it] works but returns Array<X | Y>; both should return Array<X> | Array<Y>
还没有人认领这个 Issue。
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
### 🔎 Search Terms
Array.from is currently declared as
```ts
from(iterable: Iterable | ArrayLike): T[];
```
This means that unions of distinct iterable types cannot be turned into arrays of the same type.
```ts
let foo: Iterable | Iterable = /* ... */;
let q: Array | Array = Array.from(foo); // Fails type checking, cannot find overload (2769)
```
The array splat operator has a different problem: it tries to create an array that is a union of both types.
```ts
let foo: Iterable | Iterable = /* ... */;
let q: Array | Array = [...foo]; // Fails type checking, not assignable to type (2322)
```
My instinct is that there should be some way to use variadic types here, but tbh I don't really know how.
Does this need new syntax? Or does it work within the existing type system?
### 🕗 Version & Regression Information
Since at least 4.0; prior to 4.0 it still fails but Array.from did not support taking an Iterable.
Still around in 6.0.0-dev.20251009
### ⏯ Playground Link
https://www.typescriptlang.org/play/?ts=5.9.3&ssl=19&ssc=1&pln=11&pc=1#code/PTAEHUFMBsGMHsC2lQBd5oBYoCoE8AHSAZVgCcBLA1UABWgEM8BzM+AVwDsATAGiwoBnUENANQAd0gAjQRVSQAUCEmYKsTKGYUAbpGF4OY0BoadYKdJMoL+gzAzIoz3UNEiPOofEVKVqAHSKymAAmkYI7NCuqGqcANag8ABmIjQUXrFOKBJMggBcISGgoAC0oACCbvCwDKgU8JkY7p7ehCTkVDQS2E6gnPCxGcwmZqDSTgzxxWWVoASMFmgYkAAeRJTInN3ymj4d-jSCeNsMq-wuoPaOltigAKoASgAywhK7SbGQZIIz5VWCFzSeCrZagNYbChbHaxUDcCjJZLfSDbExIAgUdxkUBIursJzCFJtXydajBVDtUAAMXgGAAvKAAJIKMgMaTuAA8glQlE4zAAfKAAD5MllszmcdiIaTffkAbmCyS4sHqjTQZDwFTIrLwVLYiAAFMlaflqbSAJSgADeihKJXcNAAjqatTquTzhoKRa6mBzJdLZaAGT68AFkvqjRaFQBfRXK1WZDXEBZ1SPwU00+CWm12tyQJ0u7W+7m8gXCypFvB+qUysiChkAbQCzeN8AAujHgiocM0PGQvIh4H02RwaF83GZmOwGMxIPxYNB1IkR3oRF4AEQAUVWDEQC3066S2PX4AcqAA5MIAHKQCTroIqADyXzI70Ec60+auqEcClc0jwUAnEHHRhiwfQUAQRBoWES5xwkIdohEAwOGxFMWDYLhuCCEogA
### 💻 Code
```ts
type Foo = Iterable | Iterable;
function tryArrayFrom(foo: Foo) {
let q: Array | Array = Array.from(foo);
}
function trySplat(foo: Foo) {
let q: Array | Array = [...foo];
}
```
### 🙁 Actual behavior
_for tryArrayFrom_
No overload matches this call.
Overload 1 of 4, '(iterable: Iterable | ArrayLike): string[]', gave the following error.
Argument of type 'Foo' is not assignable to parameter of type 'Iterable | ArrayLike'.
Type 'Iterable' is not assignable to type 'Iterable | ArrayLike'.
Type 'Iterable' is not assignable to type 'Iterable'.
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
Type 'IteratorResult' is not assignable to type 'IteratorResult'.
Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'.
Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'.
Type 'number' is not assignable to type 'string'.
Overload 2 of 4, '(arrayLike: ArrayLike): (string | number)[]', gave the following error.
Argument of type 'Foo' is not assignable to parameter of type 'ArrayLike'.
Property 'length' is missing in type 'Iterable' but required in type 'ArrayLike'.
_for trySplat_
Type '(string | number)[]' is not assignable to type 'string[] | number[]'.
Type '(string | number)[]' is not assignable to type 'string[]'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
### 🙂 Expected behavior
Array.from a union of Iterables should return a union of Arrays.
### Additional information about the issue
_No response_
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
首先在链接的 TypeScript Playground 中重现两个示例,并比较已声明的 Array.from 重载与展开行为。调查 Iterable 和 Iterable 的联合类型是如何推断的,然后确定现有的类型系统机制是否能够在不引入新语法的情况下生成 Array | Array。当两个示例都能以预期的联合类型通过类型检查,并且涵盖相关回归时,即视为完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- typescript
- 领域
- compilers
- Issue 类型
- 功能
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100