In TypeScript this is not compiling:
export interface Generic<T extends string> {
}
export interface Class<T extends string[]> {
readonly prop: { [P in keyof T]: Generic<T[P]> }
}
Particularly, the Generic<T[P]>
fails with Type 'T[P]' does not satisfy the constraint 'string'.
. However, since T extends string[]
, it can be certain, that T[P] extends string
for any P in keyof T
.
What am I doing wrong here?
I know I can fix the problem with a conditional type:
export interface Class<T extends string[]> {
readonly prop: { [P in keyof T]: T[P] extends string ? Generic<T[P]> : never }
}
But I don't see, why this should be necessary.
If you look at the full error, the third line has a big clue:
The problem is that
keyof
any array type (or tuple type) will be more likestring | number | symbol
. And an array also has more than it's member type on those keys. For instance:See this snippet. There's a lot more than just numbers in array keys:
And
Generic<T>
requiresT
to be a string, but, as shown, not all values of all keys of an array are strings.Playground
You can fix the mapped type very simply by intersecting the array keys with
number
, informing typescript that you only care about the number keys (which are the array indices):Playground