Skip to content

Generic TypedArray constructors have only one overload #61680

Open
@gordonmleigh

Description

@gordonmleigh

πŸ”Ž Search Terms

Uint8Array

πŸ•— Version & Regression Information

  • This is the behavior in versions 5.8.3 and 5.7.3
  • I was unable to test this on prior versions because Uint8Array is not generic in earlier versions

⏯ Playground Link

https://www.typescriptlang.org/play/?target=11&ts=5.8.3#code/MYewdgzgLgBBIFcBOwCmMC8MyoO4wFUBLMKADgEEkkBDATwAoBGABgEoBuAKC9EllAAHOk0zY8hEuSq1G8ZGk69w0GELoAmMTnzFSlavQA8M+gCEEAM0uokAGSIBrVAD4G8lKiV9V6gMzaEnrShnQmoRbWtm4eitxAA

πŸ’» Code

const source = new Uint8Array(10);

const copy1 = new Uint8Array(source); // OK
const copy2 = new Uint8Array<ArrayBufferLike>(source); // TS 2345
const copy3 = new Uint8Array<ArrayBuffer>(source); // TS 2345

πŸ™ Actual behavior

Only the generic constructor overload of Uint8Array is available when using Uint8Array with a generic parameter, i.e. the one which accepts a TArrayBuffer as the first argument. It is therefore not possible to pass a Uint8Array as the first argument without a compile error, even though this is valid.

πŸ™‚ Expected behavior

It should be possible to use all the valid overloads of Uint8Array (and friends) constructor without a compiler error.

Additional information about the issue

This seems to only affect target value of ES2024 or ESNext, but I can't figure out why from looking at the types.

I assume this behaviour occurs for the same reason as given in this comment. In that case I assume the fix would be adding copies of all the constructor overloads to the Uint8ArrayConstructor interface, but with type parameters.

For example, the following works (TS Playground):

interface Uint8ArrayConstructor {
    // this is just a copy of existing overloads, with `TArrayBuffer` param added
    new <TArrayBuffer extends ArrayBufferLike = ArrayBuffer>(
      length: number,
    ): Uint8Array<TArrayBuffer>;
    new <TArrayBuffer extends ArrayBufferLike = ArrayBuffer>(
      array: ArrayLike<number>,
    ): Uint8Array<TArrayBuffer>;
    new <TArrayBuffer extends ArrayBufferLike = ArrayBuffer>(
      buffer: ArrayBuffer,
      byteOffset?: number,
      length?: number,
    ): Uint8Array<TArrayBuffer>;
    new <TArrayBuffer extends ArrayBufferLike = ArrayBuffer>(
      array: ArrayLike<number> | ArrayBuffer,
    ): Uint8Array<TArrayBuffer>;
}

const source = new Uint8Array(10);

const copy1 = new Uint8Array(source);
const copy2 = new Uint8Array<ArrayBufferLike>(source);
const copy3 = new Uint8Array<ArrayBuffer>(source);

I think this is basically the opposite problem to that which was fixed by #60934.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Help WantedYou can do thisPossible ImprovementThe current behavior isn't wrong, but it's possible to see that it might be better in some cases

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions