Description
Bug Report
π Search Terms
mapped tuple type
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about mapped type
β― Playground Link
Playground link with relevant code
π» Code
class ValType {
#isValType = true;
}
class I32 extends ValType {
#isI32 = true;
}
class Externref extends ValType {
#isExternref = true;
}
class Local<T extends ValType> {
readonly #type: T;
constructor(type: T) {
this.#type = type;
}
get type(): T {
return this.#type;
}
}
type LocalsFor<Type extends ReadonlyArray<ValType>> = {
// Type 'Type[K]' does not satisfy the constraint 'ValType'.
// Type 'Type[keyof Type]' is not assignable to type 'ValType'.
// Type 'Type[string] | Type[number] | Type[symbol]' is not assignable to type 'ValType'.
// Type 'Type[string]' is not assignable to type 'ValType'.(2344)
[K in keyof Type]: Local<Type[K]>
};
// This is still the correct type, because mapped array/tuples still
// just map their values despite the above error
const locals: LocalsFor<[I32, Externref]> = [
new Local(new I32()),
new Local(new Externref()),
];
π Actual behavior
It produces an error in the mapped type that Type[K]
doesn't satisfy the constraint.
π Expected behavior
There should be no error, as mapped types do not map over all keys in the array/tuple, it should only consider Type[K]
to be the numeric keys of the tuple, i.e. Type[K]
in the mapped type will only ever be (subtypes of) ValType
because ultimately K
will only be assigned to the numeric keys of Type
as it's an array type.
In this particular case, we have an explicit Type extends ReadonlyArray<ValType>
so TypeScript should be able to deduce just fine that this particular mapped type will only ever be over an array, and hence should be able to deduce that Type[K]
will only ever be Type[number]
(or Type[`${ number }`]
for tuples).
I had another issue, however I closed it and opened this one because this is likely the fundamental cause of both problems.