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.)
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]>;
}
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