Consider the following mapped type definition:
type FeaturesMapEx<T> = {
[K in keyof T]?: T[K];
};
Which is a valid, generic mapped type, that uses generic type T and T's fields (keys) as an own index type. Those fields hold value of respective T[K] type, which basically translates to
"Here you have a generic FeaturesMapEx type of T. Use T to obtain it's fields and use them as your own. If T[K] is type X, then FeaturesMapEx<T>[K] is same type"
Ok. Now the thing I don't really get, why the declaration does not need to be like the following, using two generic parameters, one to represent Type, second to represent Keys of those Type:
export type FeaturesMapEx<T, K extends keyof T> = {
[K in keyof T]?: T[K];
};
The above declaration is valid, but K is unused, [K in keyof T] uses a different K, than the one defined in generic declaration.
Or even better (but not valid) declaration that makes more common sense for me:
export type FeaturesMapEx<T, K extends keyof T> = {
[K]?: T[K];
};
Which gives TypeScript error as following:
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.ts(1170)
'K'only refers to a type, but is being used as a value here.ts(2693)
While feeling comfortable with the usage of mapped types and generic this example always makes me a bit dizzy when I've got to write it on my own after some break, I'm always falling into later presented patterns (two generics or "type used as value" error)... can anyone explain is my confusion common or I'm missing something?
A bonus question is, from where does the type K comes into the first declaration, If it's not provided by the generic type parameter?