Skip to content

Suggestion: a built-in TypedArray interface #15402

Open
@mcmath

Description

@mcmath

I would have expected a TypedArray interface to exist in
the built-in declaration libraries. Instead, there are independent types for
Int8Array, etc, with no common base type.

interface Int8Array { /* ... */ }
interface Int8ArrayConstructor { /* ... */ }
declare const Int8Array: Int8ArrayConstructor;

interface Uint8Array { /* ... */ }
interface Uint8ArrayConstructor { /* ... */ }
declare const Uint8Array: Uint8ArrayConstructor;

// ...

It seems sensible that there should be a common TypedArray type, both because

  • a TypeScript user might want to declare a variable as a TypedArray, and
  • it would reduce repetition in the built-in declaration files
interface TypedArray { /* ... */ }

interface Int8Array extends TypedArray { }
interface Int8ArrayConstructor { /* ... */ }
declare const Int8Array: Int8ArrayConstructor;

interface Uint8Array extends TypedArray { }
interface Uint8ArrayConstructor { /* ... */ }
declare const Uint8Array: Uint8ArrayConstructor;

// ...

Is there a good reason why there is no TypedArray type? If not, I can submit a PR.

Use case

Consider the isTypedArray() function from lodash.
Currently, it is declared as follows:

function isTypedArray(value: any): boolean;

This proposal would enable an appropriate type-guard, without declaring
a convoluted union type:

function isTypedArray(value: any): value is TypedArray;

Activity

mhegazy

mhegazy commented on Apr 26, 2017

@mhegazy
Contributor

You can achieve the same behavior today by defining:

type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;

but in general define one TypedArray interface and use this types should reduce the duplication.

added
SuggestionAn idea for TypeScript
Domain: lib.d.tsThe issue relates to the different libraries shipped with TypeScript
on Apr 26, 2017
added this to the Community milestone on Apr 26, 2017
mcmath

mcmath commented on Apr 26, 2017

@mcmath
Author

@mhegazy Yes, that's the solution I'm using now, but it seems a bit unnecessary. I'll submit a PR shortly.

added a commit that references this issue on Apr 27, 2017
67c9ec0
marcusjwhelan

marcusjwhelan commented on Apr 27, 2017

@marcusjwhelan

Would asking for types for 0x, 0b, and 0o be a different request on this? The reason I would like these type is to use with TypedArrays. Currently there is no guard on inserting any number into those typedArrays. Which shouldn't be allowed. Lets say you wanted to put a value 255 into a Int8Array field, this should have a type guard for

type int8 = -0x80 to 0x7F | -0b10000000 to 0b1111111 | -0o200 to 0o177
type hex = any 0xFFFFF...;
type binary = any 0b1001010101...;
type octal = any 0o17235...;

Something that would prevent a programmer from inserting numbers that will be converted within the typed arrays.

mcmath

mcmath commented on Apr 27, 2017

@mcmath
Author

@marcusjwhelan That is a very different proposal, and far beyond the scope of this one. This is just about adding another interface to the declaration files, not about introducing new syntax.

saschanaz

saschanaz commented on May 7, 2017

@saschanaz
Contributor

There already is ArrayBufferView interface in lib.d.ts for this exact purpose, which is a supertype of all typed arrays.

interface ArrayBufferView {
    /**
      * The ArrayBuffer instance referenced by the array.
      */
    buffer: ArrayBuffer;

    /**
      * The length in bytes of the array.
      */
    byteLength: number;

    /**
      * The offset in bytes of the array.
      */
    byteOffset: number;
}

interface ArrayBufferConstructor {
    readonly prototype: ArrayBuffer;
    new (byteLength: number): ArrayBuffer;
    isView(arg: any): arg is ArrayBufferView;
}
declare const ArrayBuffer: ArrayBufferConstructor;

ArrayBuffer.isView(new Uint8Array()); // true

On Web IDL:

typedef (Int8Array or Int16Array or Int32Array or
         Uint8Array or Uint16Array or Uint32Array or Uint8ClampedArray or
         Float32Array or Float64Array or DataView) ArrayBufferView;
ulrikstrid

ulrikstrid commented on Jun 12, 2017

@ulrikstrid

The solution that @mhegazy gives might be okay in some cases. But I'm writing code that is something like this:

type Arr<T> = T[] | Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;

function isSame<T>(first: Arr<T>, second: Arr<T>) {
  return first.every((ele: T, index: number): boolean => {
    return ele === second[index];
  });
}

And it just will not compile because every has this type def (it is copied for each type of array):

every(callbackfn: (this: void, value: number, index: number, array: Float64Array) => boolean): boolean;
zenmumbler

zenmumbler commented on Jun 23, 2017

@zenmumbler

FWIW, I have this concept in my library as I have to deal with TypedArrays a lot, see:
https://github.com/stardazed/stardazed/blob/master/src/core/array.ts#L36
I split it into a base and mutable and readonly extended interfaces, code as added works only in 2.4+ as the SharedArrayBuffer type was modified in the std declarations.

I also made a TS fork of gl-matrix (https://github.com/stardazed/veclib) where I often had to deal with TypedArray or array inputs being returned and wanting TS to deduce the right return type, solved like so:

type AN = ArrayOfNumber; // an ArrayLike<number> with non-readonly subscript
type ACN = ArrayOfConstNumber; // ArrayLike<number>

export function min(out: number[], a: ACN, b: ACN): number[];
export function min<T extends AN>(out: T, a: ACN, b: ACN): T;
export function min(out: AN, a: ACN, b: ACN) { ...code... }

This allows it to return the correct type info for both:

const a = min([], [1,2,3], [3,2,1]); // a: number[]
const b = min(new Int32Array(3), [1,2,3], [3,2,1]); // b: Int32Array
added 2 commits that reference this issue on Sep 18, 2017
359c676
e7ae252

40 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptFix AvailableA PR has been opened for this issueHelp WantedYou can do thisSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Participants

      @zenmumbler@alexburner@kyr0@corwin-of-amber@patrickroberts

      Issue actions

        Suggestion: a built-in TypedArray interface · Issue #15402 · microsoft/TypeScript