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
相关产品推荐
相关产品推荐

