Home > Back-end >  Typescript: Typed Array connect input to output in a function
Typescript: Typed Array connect input to output in a function

Time:11-30

I am trying to type a function that does this

  • Takes a string corresponding to a number type,
  • returns a typed array
  • Upon execution the user receives information about the exact typed array returned

But after trying for a long while, I haven't been able to connect the input and output.

const typedArrays = {
  int8: Int8Array,
  uint8: Uint8Array,
  int16: Int16Array,
  uint16: Uint16Array,
};

type TypedArrays = typeof typedArrays

function doSomething<T extends keyof TypedArrays>(input:T): TypedArrays[T]{
    return new typedArrays[input]([1,2,3])
}

Edit: incorporated a few of the suggestions in answers (still do not solve the main problem.)

PLAYGROUND

CodePudding user response:

Your TypedArrays type would work if it was just a simple typeof typedArrays

type TypedArrays = typeof typedArrays;

Since you want to return instances of the typed arrays and your object contains constructors you need to use InstanceType for the return type of your function

function doSomething<T extends keyof typeof typedArrays>(input: T): InstanceType<TypedArrays[T]> {
    return new typedArrays[input]() as InstanceType<TypedArrays[T]>;
}

Playground

CodePudding user response:

The major problem is that TypedArrays is an interface declared as

{
  T: typeof typedArrays[T];
}

So input is typed as "T", but "T" is not assignable to keyof typeof typedArray

It is correct from the response above to type better TypedArrays, but you could even not use it:

const typedArrays = {
  int8: Int8Array,
  uint8: Uint8Array,
  int16: Int16Array,
  uint16: Uint16Array,
  int32: Int32Array,
  uint32: Uint32Array,
  uint64: BigUint64Array,
  int64: BigInt64Array,
  float32: Float32Array,
  float64: Float64Array,
};


function doSomething<T extends keyof typeof typedArrays>(
  input: T
): typeof typedArrays[T] {
  return typedArrays[input];
}

const a = doSomething("int8"); // Int8ArrayConstructor
const b = doSomething("float32"); // Float32ArrayConstructor

Also, please keep an eye about the use of new.

Take for example int8: Int8Array in typedArrays, remember that Int8Array is not a type, but a var:

var Int8Array: Int8ArrayConstructor

So this will result in an error:

function doSomething<T extends keyof TypedArray>(input: T): TypedArray[T] {
  return new typedArrays[input]; // Error
}

This is because we are returning a truly Int8Array from a function that should return Int8ArrayConstructor.

In order to avoid this, do the following:

const typedArrays = {
  int8: Int8Array,
  uint8: Uint8Array,
  int16: Int16Array,
  uint16: Uint16Array,
  int32: Int32Array,
  uint32: Uint32Array,
  uint64: BigUint64Array,
  int64: BigInt64Array,
  float32: Float32Array,
  float64: Float64Array,
};

type TypedArray = typeof typedArrays;

function doSomething<T extends keyof TypedArray>(input: T): TypedArray[T] {
  return typedArrays[input];
}

const a = new (doSomething("int8"))(); // Int8Array
const b = doSomething("float32"); // Float32ArrayConstructor
  • Related