Description
TypeScript Version: 4.0.2
Search Terms: array element type inference callback
Code
Found a problem with type inference when tried to implement functions and array methods taking callbacks, where the array element type will be inferred from the actual array type.
What I have:
- a helper type
ElemT
that extracts the element type from an array type. - a function type
FuncT
to be used in array iteration functions. - a global function taking an array and a callback.
- a new array class with a method taking a callback.
The callback wants to pass the array with its actual type as parameter. Therefore, FuncT
needs the array type as generic parameter, and must infer the element type for its first parameter.
// helper type to infer element type from array type
type ElemT<AT extends any[]> = AT extends (infer T)[] ? T : never;
// callback function taking element type and array type
type FuncT<AT extends any[]> = (v: ElemT<AT>, a: AT) => void;
// global function
function example<AT extends any[]>(arr: AT, cb: FuncT<AT>) {
cb(arr[0], arr); // <==== works
}
// class method
class MyArr<T> extends Array<T> {
public example(cb: FuncT<this>) {
cb(this[0], this); // <==== fails
}
}
However, I fond a workaround: When I bake the ElemT
into the FuncT
it works as expected. But that's a little inconvenient because this has to be done for multiple callback types in my real code.
// callback function taking element type and array type
type FuncT<AT extends any[]> = AT extends (infer T)[] ? (v: T, a: AT) => void : never;
// global function
function example<AT extends any[]>(arr: AT, cb: FuncT<AT>) {
cb(arr[0], arr); // <==== works
}
// class method
class MyArr<T> extends Array<T> {
public example(cb: FuncT<this>) {
cb(this[0], this); // <==== works now
}
}
Expected behavior:
In MyArr#example
, ElemType<this>
resolves to T
.
Actual behavior:
In MyArr#example
, this[0]
(with type T
) cannot be assigned to ElemT<this>
.