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
keyofany 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>requiresTto 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