Description
Bug Report
π Search Terms
Mapped array types
π Version & Regression Information
I noticed now in TS 4.1.2.
β― Code and Playground Links
There are two problems.
The following has an error in the mapped type despite that I did it just like in #26063 (as far as I know):
type Constructor<T = object, A extends any[] = any[], Static = {}> = (new (...a: A) => T) & Static
type ElementTypeArrayToInstArray<T extends Constructor[]> = {
[K in keyof T]: InstanceType<T[K]> // <----------- ERROR
}
type ArrayValues<T extends any[]> = T[keyof T]
type ElementTypes<T extends Constructor[]> = ArrayValues<ElementTypeArrayToInstArray<T>>
type test = ElementTypes<[typeof HTMLAnchorElement, typeof HTMLDivElement]>
Playground link with relevant code
But notice that when you hover on test
, it is a union of all the values of the array including values from non-numeric keys, which is unlike the examples in #26063.
There seems to some sort of special casing happening.
I had to specify that I want number
keys only in order(unlike #26063) to get rid of the error:
type Constructor<T = object, A extends any[] = any[], Static = {}> = (new (...a: A) => T) & Static
type ElementTypeArrayToInstArray<T extends Constructor[]> = {
[K in keyof T]: InstanceType<T[number & K]> // <----------- GOOD
}
type ArrayValues<T extends any[]> = T[keyof T]
type ElementTypes<T extends Constructor[]> = ArrayValues<ElementTypeArrayToInstArray<T>>
type test = ElementTypes<[typeof HTMLAnchorElement, typeof HTMLDivElement]>
Playground link with relevant code
But notice that test
still contains all the values of all keys, not just array values.
Finally, I had to specify numeric keys for ArrayValues
:
type Constructor<T = object, A extends any[] = any[], Static = {}> = (new (...a: A) => T) & Static
type ElementTypeArrayToInstArray<T extends Constructor[]> = {
[K in keyof T]: InstanceType<T[number & K]>
}
type ArrayValues<T extends any[]> = T[number & keyof T] // <-------- number
type ElementTypes<T extends Constructor[]> = ArrayValues<ElementTypeArrayToInstArray<T>>
type test = ElementTypes<[typeof HTMLAnchorElement, typeof HTMLDivElement]>
Playground link with relevant code
But notice if I use Promise
instead of InstanceType
, the first issues goes away, although number
is still needed in ArrayValues
:
type Constructor<T = object, A extends any[] = any[], Static = {}> = (new (...a: A) => T) & Static
type ElementTypeArrayToInstArray<T extends Constructor[]> = {
[K in keyof T]: Promise<T[K]> // <-------- no number
}
type ArrayValues<T extends any[]> = T[number & keyof T] // <-------- number still needed
type ElementTypes<T extends Constructor[]> = ArrayValues<ElementTypeArrayToInstArray<T>>
type test = ElementTypes<[typeof HTMLAnchorElement, typeof HTMLDivElement]>
Playground link with relevant code
π Actual behavior
Does not work like #26063
π Expected behavior
Works like #26063
There seems to be some sort of special casing going on.