How to find the type of a typedArray?

Viewed 1313

To test if an object is an array, there is a method -

const myarray = [1,2,3,4]; 
Array.isArray(myarray); 
//returns true

Is there a similar method for typed arrays (for example, Uint8Array)?

const int8 = new Uint8Array([0,1,2,3]);
Array.isArray(int8); //returns false

How can I find out if an object is a typed array, and what kind of typed array?

4 Answers

You can use a comparison with its constructor 1:

const int8 = new Uint8Array([0,1,2,3]);
console.log(int8.constructor === Uint8Array);

// so you can do
function checkTypedArrayType(someTypedArray) {
  const typedArrayTypes = [
    Int8Array,
    Uint8Array,
    Uint8ClampedArray,
    Int16Array,
    Uint16Array,
    Int32Array,
    Uint32Array,
    Float32Array,
    Float64Array,
    BigInt64Array,
    BigUint64Array
  ];
  const checked = typedArrayTypes.filter(ta => someTypedArray.constructor === ta);
  return checked.length && checked[0].name || null;
}

console.log(checkTypedArrayType(int8));

// but this can be hugely simplified
function checkTypedArrayType2(someTypedArray) {
  return someTypedArray && 
    someTypedArray.constructor && 
    someTypedArray.constructor.name || 
    null;
}

console.log(checkTypedArrayType2(int8));

// which can actually be generalized to
const whatsMyType = someObject => 
  someObject && 
    someObject.constructor && 
    someObject.constructor.name && 
    someObject.constructor.name || 
    null;

console.log(whatsMyType(int8));
console.log(whatsMyType([1,2,3,4]));
console.log(whatsMyType("hello!"))
console.log(whatsMyType(/[a-z]/i))

1 Note that no version of Internet Explorer supports the name property. See MDN. See also

There is actually an equivalent to Array.isArray for TypedArrays, accessible on the ArrayBuffer constructor:

ArrayBuffer.isView.

However note that it will also return true for DataView objects, so if you really want to know if an object is a TypedArray, you can simply do:

function isTypedArray( arr ) {
  return ArrayBuffer.isView( arr ) && !(arr instanceof DataView);
}

function test( val ) {
  console.log( isTypedArray( val ) );
}

test( false ); // false
test( null ); // false
test( [] ); // false
test( new ArrayBuffer( 12 ) ); // false
test( new DataView( new ArrayBuffer( 12 ) ) ); // false
test( new Uint8Array( 12 ) ); // true;
test( new BigInt64Array( 12 ) ); // true;

But this won't give you the particular type of that TypedArray.

TypedArray's prototype exposes a BYTES_PER_ELEMENT property, but that's about it...

There is a .name property accessible on the constructor, which is itself accessible through the .constructor property of each instance, but that can be set and is not supported by IE. But if it's not a problem for you all it takes is:

function getType( arr ) {
  return isTypedArray( arr ) && arr.constructor.name;
}
function isTypedArray( arr ) {
  return ArrayBuffer.isView( arr ) && !(arr instanceof DataView);
}

function test( val ) {
  console.log( getType( val ) );
}

test( [] ); // false
test( new ArrayBuffer( 12 ) ); // false
test( new DataView( new ArrayBuffer( 12 ) ) ); // false
test( new Uint8Array( 12 ) ); // "Uint8Array";
test( new BigInt64Array( 12 ) ); // "BigInt64Array";

And if you need to support IE, testing all possible TypedArrays Constructors independently with instanceof is also an option:

const typedArrays = [
 'Int8',
 'Uint8',
 'Uint8Clamped',
 'Int16',
 'Uint16',
 'Int32',
 'Uint32',
 'Float32',
 'Float64',
 'BigInt64',
 'BigUint64'
].map( (pre) => pre + 'Array' );

function getType( arr ) {
  return isTypedArray( arr ) &&
    typedArrays.find( (type) => arr instanceof window[ type ] );
}

function isTypedArray( arr ) {
  return ArrayBuffer.isView( arr ) && !(arr instanceof DataView);
}

function test( val ) {
  console.log( getType( val ) );
}

test( [] ); // false
test( new Uint8Array( 12 ) ); // Uint8Array
test( new Int16Array( 12 ) ); // Int16Array
test( new Float32Array( 12 ) ); // Float32Array

Another approach could be, You could make use of BYTES_PER_ELEMENT property of a typed Array

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT

Array.isTypedArray = function(inArray) {
  if (inArray) {
    const prototype = Object.getPrototypeOf(inArray);
    return prototype ? prototype.hasOwnProperty("BYTES_PER_ELEMENT") : false;
  }
  return false;
};

As mentioned in other answers, to get the actual type you can use the constructor.name. Reusing the above isTypedArray function, you could write like.

function getType(obj){
    return Array.isTypedArray(obj) ? obj.constructor.name: (typeof obj)
}

Sample code & console.logs

Array.isTypedArray = function(inArray){
    if(inArray){
        const prototype = Object.getPrototypeOf(inArray);
        return prototype ? prototype.hasOwnProperty("BYTES_PER_ELEMENT") : false;
    }
    return false;
}

console.log(" 'Iam' a typed array  ", Array.isTypedArray([1,2,3]));
console.log("[1,2,3] is typed array  ", Array.isTypedArray([1,2,3]));
console.log("new Int8Array([1,2,3]) is typed array  ", Array.isTypedArray(new Int8Array([1,2,3])));
console.log("new BigUint64Array() is typed array  ", Array.isTypedArray(new BigUint64Array()));
console.log("new Uint8ClampedArray([1,2,3]) is typed array  ", Array.isTypedArray(new Uint8ClampedArray([1,2,3])));
console.log("new Float32Array([1,2,3]) is typed array  ", Array.isTypedArray(new Float32Array([1,2,3])));
console.log("new BigUint64Array() is typed array  ", Array.isTypedArray(new BigUint64Array()));
console.log("new Set() is typed array  ", Array.isTypedArray(new Set()));
console.log("null is typed array  ", Array.isTypedArray(null));
console.log("undedined is typed array  ", Array.isTypedArray(undefined));
console.log("{} is typed array  ",Array.isTypedArray({}));


function getType(obj){
    return Array.isTypedArray(obj) ? obj.constructor.name: (typeof obj)
}

console.log("Type of Array  ", getType(new Array()));
console.log("Type of Int8Array  ", getType(new Int8Array()));
console.log("Type of Uint8Array  ",getType( new Uint8Array()));
console.log("Type of Uint8ClampedArray  ",getType( new Uint8ClampedArray()));
console.log("Type of Int16Array  ", getType(new Int16Array()));
console.log("Type of Float32Array  ", getType(new Float32Array()));
console.log("Type of BigInt64Array  ", getType(new BigInt64Array()));
console.log("Type of BigUint64Array  ", getType(new BigUint64Array()));

Related