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
