From 1fc7fdf0f53dd3dfef8ddf1ca4666548d68e1e99 Mon Sep 17 00:00:00 2001 From: Trent Millar Date: Fri, 6 Nov 2026 18:46:45 -0600 Subject: [PATCH] Add generic overloads to TypedArray constructors (#61680) --- .../bundled/libs/lib.es2015.iterable.d.ts | 9 ++ .../bundled/libs/lib.es2017.typedarrays.d.ts | 9 ++ .../bundled/libs/lib.es2020.bigint.d.ts | 6 + .../bundled/libs/lib.es2025.float16.d.ts | 3 + tsc/internal/bundled/libs/lib.es5.d.ts | 27 ++++ .../typedArrayConstructorOverloads.ts | 126 ++++++++++++++++++ 6 files changed, 180 insertions(+) diff --git a/tsc/internal/bundled/libs/lib.es2015.iterable.d.ts b/tsc/internal/bundled/libs/lib.es2015.iterable.d.ts index 4c57f556a800d..73c0aecc32027 100644 --- a/tsc/internal/bundled/libs/lib.es2015.iterable.d.ts +++ b/tsc/internal/bundled/libs/lib.es2015.iterable.d.ts @@ -290,6 +290,7 @@ interface Int8Array { interface Int8ArrayConstructor { new (elements: Iterable): Int8Array; + new (elements: Iterable): Int8Array; /** * Creates an array from an array-like or iterable object. @@ -327,6 +328,7 @@ interface Uint8Array { interface Uint8ArrayConstructor { new (elements: Iterable): Uint8Array; + new (elements: Iterable): Uint8Array; /** * Creates an array from an array-like or iterable object. @@ -364,6 +366,7 @@ interface Uint8ClampedArray { interface Uint8ClampedArrayConstructor { new (elements: Iterable): Uint8ClampedArray; + new (elements: Iterable): Uint8ClampedArray; /** * Creates an array from an array-like or iterable object. @@ -400,6 +403,7 @@ interface Int16Array { interface Int16ArrayConstructor { new (elements: Iterable): Int16Array; + new (elements: Iterable): Int16Array; /** * Creates an array from an array-like or iterable object. @@ -437,6 +441,7 @@ interface Uint16Array { interface Uint16ArrayConstructor { new (elements: Iterable): Uint16Array; + new (elements: Iterable): Uint16Array; /** * Creates an array from an array-like or iterable object. @@ -474,6 +479,7 @@ interface Int32Array { interface Int32ArrayConstructor { new (elements: Iterable): Int32Array; + new (elements: Iterable): Int32Array; /** * Creates an array from an array-like or iterable object. @@ -511,6 +517,7 @@ interface Uint32Array { interface Uint32ArrayConstructor { new (elements: Iterable): Uint32Array; + new (elements: Iterable): Uint32Array; /** * Creates an array from an array-like or iterable object. @@ -548,6 +555,7 @@ interface Float32Array { interface Float32ArrayConstructor { new (elements: Iterable): Float32Array; + new (elements: Iterable): Float32Array; /** * Creates an array from an array-like or iterable object. @@ -585,6 +593,7 @@ interface Float64Array { interface Float64ArrayConstructor { new (elements: Iterable): Float64Array; + new (elements: Iterable): Float64Array; /** * Creates an array from an array-like or iterable object. diff --git a/tsc/internal/bundled/libs/lib.es2017.typedarrays.d.ts b/tsc/internal/bundled/libs/lib.es2017.typedarrays.d.ts index 4ac9df4fb980a..d066c64853d05 100644 --- a/tsc/internal/bundled/libs/lib.es2017.typedarrays.d.ts +++ b/tsc/internal/bundled/libs/lib.es2017.typedarrays.d.ts @@ -15,36 +15,45 @@ and limitations under the License. interface Int8ArrayConstructor { new (): Int8Array; + new (): Int8Array; } interface Uint8ArrayConstructor { new (): Uint8Array; + new (): Uint8Array; } interface Uint8ClampedArrayConstructor { new (): Uint8ClampedArray; + new (): Uint8ClampedArray; } interface Int16ArrayConstructor { new (): Int16Array; + new (): Int16Array; } interface Uint16ArrayConstructor { new (): Uint16Array; + new (): Uint16Array; } interface Int32ArrayConstructor { new (): Int32Array; + new (): Int32Array; } interface Uint32ArrayConstructor { new (): Uint32Array; + new (): Uint32Array; } interface Float32ArrayConstructor { new (): Float32Array; + new (): Float32Array; } interface Float64ArrayConstructor { new (): Float64Array; + new (): Float64Array; } diff --git a/tsc/internal/bundled/libs/lib.es2020.bigint.d.ts b/tsc/internal/bundled/libs/lib.es2020.bigint.d.ts index ae31d07ab7ca3..c4d712f0cb416 100644 --- a/tsc/internal/bundled/libs/lib.es2020.bigint.d.ts +++ b/tsc/internal/bundled/libs/lib.es2020.bigint.d.ts @@ -390,6 +390,9 @@ interface BigInt64ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): BigInt64Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): BigInt64Array; new (array: ArrayLike | ArrayBuffer): BigInt64Array; + new (length?: number): BigInt64Array; + new (array: ArrayLike | Iterable): BigInt64Array; + new (array: ArrayLike | ArrayBuffer): BigInt64Array; /** The size in bytes of each element in the array. */ readonly BYTES_PER_ELEMENT: number; @@ -681,6 +684,9 @@ interface BigUint64ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): BigUint64Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): BigUint64Array; new (array: ArrayLike | ArrayBuffer): BigUint64Array; + new (length?: number): BigUint64Array; + new (array: ArrayLike | Iterable): BigUint64Array; + new (array: ArrayLike | ArrayBuffer): BigUint64Array; /** The size in bytes of each element in the array. */ readonly BYTES_PER_ELEMENT: number; diff --git a/tsc/internal/bundled/libs/lib.es2025.float16.d.ts b/tsc/internal/bundled/libs/lib.es2025.float16.d.ts index 9b670f8ede25a..d8976d7c1eba5 100644 --- a/tsc/internal/bundled/libs/lib.es2025.float16.d.ts +++ b/tsc/internal/bundled/libs/lib.es2025.float16.d.ts @@ -373,6 +373,9 @@ interface Float16ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Float16Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float16Array; new (array: ArrayLike | ArrayBuffer): Float16Array; + new (length?: number): Float16Array; + new (array: ArrayLike | Iterable): Float16Array; + new (array: ArrayLike | ArrayBuffer): Float16Array; /** * The size in bytes of each element in the array. diff --git a/tsc/internal/bundled/libs/lib.es5.d.ts b/tsc/internal/bundled/libs/lib.es5.d.ts index 87376e31ae242..3ed4077a0a6b6 100644 --- a/tsc/internal/bundled/libs/lib.es5.d.ts +++ b/tsc/internal/bundled/libs/lib.es5.d.ts @@ -2127,6 +2127,9 @@ interface Int8ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Int8Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int8Array; new (array: ArrayLike | ArrayBuffer): Int8Array; + new (length: number): Int8Array; + new (array: ArrayLike): Int8Array; + new (array: ArrayLike | ArrayBuffer): Int8Array; /** * The size in bytes of each element in the array. @@ -2409,6 +2412,9 @@ interface Uint8ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Uint8Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint8Array; new (array: ArrayLike | ArrayBuffer): Uint8Array; + new (length: number): Uint8Array; + new (array: ArrayLike): Uint8Array; + new (array: ArrayLike | ArrayBuffer): Uint8Array; /** * The size in bytes of each element in the array. @@ -2691,6 +2697,9 @@ interface Uint8ClampedArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Uint8ClampedArray; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint8ClampedArray; new (array: ArrayLike | ArrayBuffer): Uint8ClampedArray; + new (length: number): Uint8ClampedArray; + new (array: ArrayLike): Uint8ClampedArray; + new (array: ArrayLike | ArrayBuffer): Uint8ClampedArray; /** * The size in bytes of each element in the array. @@ -2972,6 +2981,9 @@ interface Int16ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Int16Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int16Array; new (array: ArrayLike | ArrayBuffer): Int16Array; + new (length: number): Int16Array; + new (array: ArrayLike): Int16Array; + new (array: ArrayLike | ArrayBuffer): Int16Array; /** * The size in bytes of each element in the array. @@ -3254,6 +3266,9 @@ interface Uint16ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Uint16Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint16Array; new (array: ArrayLike | ArrayBuffer): Uint16Array; + new (length: number): Uint16Array; + new (array: ArrayLike): Uint16Array; + new (array: ArrayLike | ArrayBuffer): Uint16Array; /** * The size in bytes of each element in the array. @@ -3535,6 +3550,9 @@ interface Int32ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Int32Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Int32Array; new (array: ArrayLike | ArrayBuffer): Int32Array; + new (length: number): Int32Array; + new (array: ArrayLike): Int32Array; + new (array: ArrayLike | ArrayBuffer): Int32Array; /** * The size in bytes of each element in the array. @@ -3816,6 +3834,9 @@ interface Uint32ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Uint32Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Uint32Array; new (array: ArrayLike | ArrayBuffer): Uint32Array; + new (length: number): Uint32Array; + new (array: ArrayLike): Uint32Array; + new (array: ArrayLike | ArrayBuffer): Uint32Array; /** * The size in bytes of each element in the array. @@ -4098,6 +4119,9 @@ interface Float32ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Float32Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float32Array; new (array: ArrayLike | ArrayBuffer): Float32Array; + new (length: number): Float32Array; + new (array: ArrayLike): Float32Array; + new (array: ArrayLike | ArrayBuffer): Float32Array; /** * The size in bytes of each element in the array. @@ -4380,6 +4404,9 @@ interface Float64ArrayConstructor { new (buffer: TArrayBuffer, byteOffset?: number, length?: number): Float64Array; new (buffer: ArrayBuffer, byteOffset?: number, length?: number): Float64Array; new (array: ArrayLike | ArrayBuffer): Float64Array; + new (length: number): Float64Array; + new (array: ArrayLike): Float64Array; + new (array: ArrayLike | ArrayBuffer): Float64Array; /** * The size in bytes of each element in the array. diff --git a/tsc/testdata/tests/cases/compiler/typedArrayConstructorOverloads.ts b/tsc/testdata/tests/cases/compiler/typedArrayConstructorOverloads.ts index 63fbfb07a9df0..fce46789e70aa 100644 --- a/tsc/testdata/tests/cases/compiler/typedArrayConstructorOverloads.ts +++ b/tsc/testdata/tests/cases/compiler/typedArrayConstructorOverloads.ts @@ -22,3 +22,129 @@ export function makeTypedArray(buffer: ArrayBuffer, ctr: TypedArrayConstructor) new ctr(buffer); new ctr(buffer, 0, 0); } + +// https://github.com/microsoft/TypeScript/issues/61680 + +export function makeGenericTypedArrays( + numIterable: Iterable, + numUnion: ArrayLike | ArrayBuffer, + bigintIterable: Iterable, + bigintUnion: ArrayLike | ArrayBuffer, +) { + const source = new Uint8Array(10); + const copy1: Uint8Array = new Uint8Array(source); + const copy2: Uint8Array = new Uint8Array(source); + const copy3: Uint8Array = new Uint8Array(source); + + new Int8Array(); + new Int8Array(10); + new Int8Array(source); + new Int8Array(numIterable); + new Int8Array(numUnion); + + new Uint8Array(); + new Uint8Array(10); + new Uint8Array(source); + new Uint8Array(numIterable); + new Uint8Array(numUnion); + + new Uint8ClampedArray(); + new Uint8ClampedArray(10); + new Uint8ClampedArray(source); + new Uint8ClampedArray(numIterable); + new Uint8ClampedArray(numUnion); + + new Int16Array(); + new Int16Array(10); + new Int16Array(source); + new Int16Array(numIterable); + new Int16Array(numUnion); + + new Uint16Array(); + new Uint16Array(10); + new Uint16Array(source); + new Uint16Array(numIterable); + new Uint16Array(numUnion); + + new Int32Array(); + new Int32Array(10); + new Int32Array(source); + new Int32Array(numIterable); + new Int32Array(numUnion); + + new Uint32Array(); + new Uint32Array(10); + new Uint32Array(source); + new Uint32Array(numIterable); + new Uint32Array(numUnion); + + new Float16Array(); + new Float16Array(10); + new Float16Array(source); + new Float16Array(numIterable); + new Float16Array(numUnion); + + new Float32Array(); + new Float32Array(10); + new Float32Array(source); + new Float32Array(numIterable); + new Float32Array(numUnion); + + new Float64Array(); + new Float64Array(10); + new Float64Array(source); + new Float64Array(numIterable); + new Float64Array(numUnion); + + const bigintSource = new BigInt64Array(10); + new BigInt64Array(); + new BigInt64Array(10); + new BigInt64Array(bigintSource); + new BigInt64Array(bigintIterable); + new BigInt64Array(bigintUnion); + + new BigUint64Array(); + new BigUint64Array(10); + new BigUint64Array(bigintSource); + new BigUint64Array(bigintIterable); + new BigUint64Array(bigintUnion); +} + +export class EncodedString extends Uint8Array { + static encode(value: string): Uint8Array { + return new Uint8Array(value.length); + } + + constructor(value: string); + constructor(value: ArrayBufferLike, byteOffset?: number, byteLength?: number); + constructor(value: string | ArrayBufferLike, byteOffset?: number, byteLength?: number) { + if (typeof value === "string") { + const encoded = EncodedString.encode(value); + super(encoded); + } + else { + super(value, byteOffset, byteLength); + } + } +} + +export class GenericSubUint8Array extends Uint8Array { + constructor(value?: number | ArrayLike | Iterable | TArrayBuffer) { + if (value === undefined) { + super(); + } + else if (typeof value === "number") { + super(value); + } + else if ("maxByteLength" in value) { + super(value); + } + else if (Symbol.iterator in value) { + super(value); + } + else { + super(value); + } + } +} +