You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript稀疏与非稀疏数组交叉类型推断不一致问题排查

问题描述

TypeScript 4.8 的静态类型推断/检查似乎存在不一致性:

type A = number[] & (number|undefined)[];
type B = (number|undefined)[] & number[];

function arrayAccess_A(a: A) { return a[0]; }  // 返回类型为'number'
function arrayAccess_B(b: B) { return b[0]; }  // 返回类型为'number'

function mapFirst_A(a: A) { return a.map(it => it)[0]; }  // 返回类型为'number'
function mapFirst_B(b: B) { return b.map(it => it)[0]; }  // 返回类型为'number | undefined'

我发现其中一个方法的返回类型不同,这是什么原因?

旧问题文本(已废弃)

(可停止阅读以下内容,这是我最初帖子的内容,在jcalz的反馈后,我觉得表述不够清晰。)

我尝试使用类型交叉WithSparseData & { data: number[] }来声明某个类型WithSparseData中有时为稀疏数组的字段{ data: (number|undefined)[] }现在不再是稀疏数组。

// 包含稀疏数组字段的类型
type WithSparseData = {
  data: (number | undefined)[];
  moreData: any;
};

// 两种表示数组字段不再是稀疏数组的方式
type WithContiguousData_A = { data: number[] } & WithSparseData;
type WithContiguousData_B =                    WithSparseData & { data: number[] };

// 被静态类型检查器合理拒绝
const assignFirstToNotNull_1 = ( numbers: WithSparseData ): { first: number } => ({ first: numbers.data[0] });
const mapAllToDouble_1       = ( numbers: WithSparseData ) => ({...numbers, data: numbers.data.map(it => 2*it) });

// 被静态类型检查器接受
const assignFirstToNotNull_A = ( numbers: WithContiguousData_A ): { first: number } => ({ first: numbers.data[0] });
const assignFirstToNotNull_B = ( numbers: WithContiguousData_B ): { first: number } => ({ first: numbers.data[0] });

// 也被静态类型检查器接受
const mapAllToDouble_A       = ( numbers: WithContiguousData_A ) => ({...numbers, data: numbers.data.map(it => 2*it) });

// 被静态类型检查器拒绝!!!
const mapAllToDouble_B       = ( numbers: WithContiguousData_B ) => ({...numbers, data: numbers.data.map(it => 2*it) });
                                                                       // 'it' 可能为 'undefined'.ts(18048) ^^

特别注意:第23行中it的类型被推断为undefined | number,而第17行中first的类型被推断为number;尽管两者都来自WithContiguousData_B,但推断的类型却不同。

问题:

  • 这是静态类型检查器的bug吗?
  • { data: number[] } & WithSparseData和WithSparseData & { data: number[] }的顺序是否应该有影响?这是有明确规定的,还是未来TypeScript编译器可能会改变行为?

内容的提问来源于stack exchange,提问作者Christian Fuchs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:40:25