Reputation: 2649
I'm learning about generics, and hitting this issue with the compiler:
type FloatArray = Float32Array | Float64Array;
type IntegerArray =
| Int8Array
| Uint8Array
| Int16Array
| Uint16Array
| Int32Array
| Uint32Array
| Uint8ClampedArray;
type TypedArray = FloatArray | IntegerArray;
export function identityArray<T extends TypedArray>(array: T): T {
return array.subarray(0);
}
// Type 'TypedArray' is not assignable to type 'T'
What am I doing wrong here?
Upvotes: 2
Views: 459
Reputation: 74620
Alternative solution without a type assertion:
type TypedArray = FloatArray | IntegerArray;
type WithSubArray<T extends TypedArray> = { subarray(begin?: number, end?: number): T };
export function identityArray<T extends TypedArray>(array: WithSubArray<T>): T {
return array.subarray(0);
}
const res1 = identityArray(new Int8Array(2)) // Int8Array π
const res2 = identityArray(new Float32Array(2)) // Float32Array π
const res3 = identityArray([1, 2, 3]) // β
If T
is declared as function return type, make sure to also return T
exactly in the function body. By using WithSubArray
we can make it clear to the compiler, that array.subarray
returns T
and not TypedArray
.
Upvotes: 1
Reputation: 5760
From docs, just type cast your return line.
βtrust me, I know what Iβm doing.β A type assertion is like a type cast...
https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions
type FloatArray = Float32Array | Float64Array;
type IntegerArray =
| Int8Array
| Uint8Array
| Int16Array
| Uint16Array
| Int32Array
| Uint32Array
| Uint8ClampedArray;
type TypedArray = FloatArray | IntegerArray;
export function identityArray<T extends TypedArray>(array: T): T {
return <T>array.subarray(0);
}
Upvotes: 1