Repository navigation
lib.es5.d.ts: Default ArrayConstructor generic parameter to undefined #59379
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Labels
DeclinedThe issue was declined as something which matches the TypeScript visionThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScriptAn idea for TypeScript
Description
⚙ Compilation target
ES2015
⚙ Library
lib.es5.d.ts
Missing / Incorrect Definition
The two constructor declaration lines without generics (new (arrayLength?: number): any[]; and (arrayLength?: number): any[];)
Lines 1488 to 1497 in 903e82b
| interface ArrayConstructor { | |
| new (arrayLength?: number): any[]; | |
| new <T>(arrayLength: number): T[]; | |
| new <T>(...items: T[]): T[]; | |
| (arrayLength?: number): any[]; | |
| <T>(arrayLength: number): T[]; | |
| <T>(...items: T[]): T[]; | |
| isArray(arg: any): arg is any[]; | |
| readonly prototype: any[]; | |
| } |
Suggestion:
interface ArrayConstructor {
- new (arrayLength?: number): any[];
- new <T>(arrayLength: number): T[];
+ new <T = undefined>(arrayLength: number): T[];
new <T>(...items: T[]): T[];
- (arrayLength?: number): any[];
- <T>(arrayLength: number): T[];
+ <T = undefined>(arrayLength: number): T[];
<T>(...items: T[]): T[];
isArray(arg: any): arg is any[];
readonly prototype: any[];
}Sample Code
Using the @typescript-eslint/no-unsafe-assignment ESLint rule
const arr: undefined[] = Array(10); // 💥 Unsafe assignment of type `any[]` to a variable of type `undefined[]`. eslint (@typescript-eslint/no-unsafe-assignment)Documentation Link
In some operations, empty slots behave as if they are filled with undefined.
const arr = [1, 2, , , 5]; // Create a sparse array // Indexed access console.log(arr[2]); // undefined // For...of for (const i of arr) { console.log(i); } // Logs: 1 2 undefined undefined 5 // Spreading const another = [...arr]; // "another" is [ 1, 2, undefined, undefined, 5 ]
Since TypeScript does not have a primitive for "empty slot", undefined seems like the closest default.
cc Josh Ghoulberg 👻 (@JoshuaKGoldberg) Brad Zacher (@bradzacher)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
DeclinedThe issue was declined as something which matches the TypeScript visionThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScriptAn idea for TypeScript
Activity
karlhorky commentedon Jul 21, 2024
Workaround
To address the problem in the
@typescript-eslint/no-unsafe-assignmentESLint rule without changing thelib.es5.d.tsdeclarations, pass in a generic type argumentundefinedto theArrayconstructor (which I'm arguing should be the default):MartinJohns commentedon Jul 21, 2024
Somewhat related: #24834
Your suggestion would be quite a breaking change.
I don't see how this is relevant at all to your suggested change.
RyanCavanaugh commentedon Jul 29, 2024
I don't see why someone would initialize an array with a length except in the rare case where they were about to fill it. This would break a number of cases, especially in JS where you can't easily specify type arguments.
karlhorky commentedon Jul 29, 2024
My original motivation was actually that - spreading a newly-initialized array into a new array literal:
typescript-eslintPlaygroundProviding the
undefinedtype argument makes this problem disappear:typescript-eslintPlaygroundUpon first thinking about it, it seemed like a logical default to me.
typescript-bot commentedon Aug 1, 2024
This issue has been marked as "Declined" and has seen no recent activity. It has been automatically closed for house-keeping purposes.