Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

With TypeScript 5.7 getData returns ArrayBufferLike instead of ArrayBuffer #549

Open
Scarabol opened this issue Dec 23, 2024 · 9 comments
Open

Comments

@Scarabol
Copy link

Thank you all for this great library! I appreciate using it in my project. I just tried to update my TypeScript version from 5.6.3 to 5.7.2.

Starting with Typescript 5.7 typed arrays become generic. See:

This affects for example the type definition of Uint8ArrayWriter

Previously with TypeScript 5.6.3 the following code typed data as ArrayBuffer, but starting with TypeScript > 5.7 data has type ArrayBufferLike.

// TypeScript < 5.7
const data: ArrayBuffer = await entry.getData(new Uint8ArrayWriter());
// TypeScript >= 5.7
const data: ArrayBufferLike = await entry.getData(new Uint8ArrayWriter());

My tsconfig compiler target is and has been set to ES2021.

I'm not sure how this is solved properly. My guess would be to add generic type explicitly to all TypedArrays usages, since they use Uint8Array (Example) actually. Effectively changing type definition here into this:

export class Uint8ArrayWriter extends Writer<Uint8Array<ArrayBuffer>> { }

What do you think?

@gildas-lormeau
Copy link
Owner

Thank for the info. Actually, I don't use TS for development and I was not aware of this issue. I wonder how to deal with that. I guess somehow I would need to publish 2 index.d.ts files?

@UnsungHero97
Copy link
Contributor

UnsungHero97 commented Mar 27, 2025

I don't think it's necessary to publish 2 index.d.ts files. I don't see any uses of SharedArrayBuffer in the codebase so I think @Scarabol's suggestion is probably the way to do it, here's a pull request for that: #561

However, I'm not totally sure how this impacts TypeScript versions below 5.7.

@gildas-lormeau
Copy link
Owner

I accepted the PR, we'll see if it's a problem :p

@gildas-lormeau
Copy link
Owner

Unfortunately, I've reverted the commit because Angular 18 is depending on a older version of TypeScript, see #563.

@UnsungHero97
Copy link
Contributor

I'll try to spend some time this week to figure this out.

@gildas-lormeau
Copy link
Owner

gildas-lormeau commented Mar 31, 2025

Thanks! I wonder if waiting would be the easiest solution. It seems that this problem doesn't really bother developers who use TS 5.7+ today.

@gildas-lormeau
Copy link
Owner

gildas-lormeau commented Mar 31, 2025

Actually, I'm probably wrong. For the record, ChatGPT suggests these fixes:

  1. replace Uint8Array with Uint8Array<ArrayBufferLike>, or
  2. add a new CompatibleUint8Array type to handle the old and new syntax, i.e. type CompatibleUint8Array = Uint8Array extends Uint8Array<infer T> ? Uint8Array<T> : Uint8Array;

I have some doubts regarding the first suggestion. The second one is interesting, I'll try to test it.

EDIT:

None of these suggestions actually work in https://www.typescriptlang.org/play/. However ChatGPT is now saying me that I shouldn't need to change anything in fact...

EDIT 2:

The solution below seems to work.

type CompatibleUint8Array = 
  Uint8Array extends { new (...args: any[]): infer U } 
    ? U 
    : Uint8Array;

EDIT 3:
Indeed, the code below does not trigger any error.

type CompatibleUint8Array = 
  Uint8Array extends { new (...args: any[]): infer U } 
    ? U 
    : Uint8Array;

function test(val: CompatibleUint8Array): void {
  console.log(val);
}
  • in TS < 5.7
const val:Uint8Array = new Uint8Array([1, 2, 3]);
test(val);
  • in TS 5.7+
const val:Uint8Array<ArrayBufferLike> = new Uint8Array([1, 2, 3]);
test(val);

@gildas-lormeau
Copy link
Owner

This does not work actually.

The code below should not trigger an error in TS 5.7+ but it does.

type CompatibleUint8Array = 
  Uint8Array extends { new (...args: any[] ): infer U } 
    ? U 
    : Uint16Array;

function test(val: CompatibleUint8Array): void {
  console.log(val);
}

const val:Uint8Array = new Uint8Array([1, 2, 3]);
test(val);

@gildas-lormeau
Copy link
Owner

gildas-lormeau commented Mar 31, 2025

I'm wondering if it's really an issue. I mean that the code below runs fine in the TS playground with TS 5.7+. @Scarabol, any thoughts?

function test(val: Uint8Array): void {
  console.log(val);
}

const val:Uint8Array = new Uint8Array([1, 2, 3]);
test(val);

const val2:Uint8Array<ArrayBufferLike> = new Uint8Array([1, 2, 3]);
test(val2);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants