Description
Bug Report
π Search Terms
Mapped Types, Conditionals, Template Types, Index Types, Index Signature
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about Mapped Types
β― Playground Link
Playground link with relevant code
π» Code
Below we use the following as a placeholder type. The specific "value" type in these examples is immaterial.
type AValue = { hello: 'world' };
Example 1
In the below example, t0
will be of type string because T
will have type string
instead of the narrower string literal type you might expect. This is the result with or without as T
in the index signature but is even more surprising given the cast.
This example is important only in that it establishes how T
has type string
, the ramifications of this are more clear in the examples following.
type MappedTypeWithKeyReturn = {
[T in string as T]: T;
}
// type should be 'aKey' not string
type t0 = MappedTypeWithKeyReturn['aKey'];
Example 2
A slightly more complex example showing we cant use extends in the value portion as might be expected. This example fails even if we do T in string as T
for the index signature, and fails even when V
is not a generic but statically known.
type MappedTypeWithConditionalValue<V extends string, R> = {
[T in string]: T extends V ? R : unknown;
}
// type should be { hello: 'world' } not unknown
type t1 = MappedTypeWithConditionalValue<'aKey', AValue>['aKey'];
Example 3
This example shows we cannot use an extends check properly within the index signature for any V
that
is not simply string
.
type MappedTypeWithConstraint<V extends string, R> = {
[T in string as T extends V ? T : never]: R;
}
// type should be { hello: 'world' } not an error
type t2 = MappedTypeWithConstraint<'aKey', AValue>['aKey'];
Example 4
A more complex example showing that the above issues prevent using a template string check
with a mapped type, via either index or value approach.
type IndexStr = `com.some.thing.${string}`;
// type should be { hello: 'world' } not unknown
type t3 = MappedTypeWithConditionalValue<IndexStr, AValue>['com.some.thing.foo'];
// type should be { hello: 'world' } not an error
type t4 = MappedTypeWithConstraint<IndexStr, AValue>['com.some.thing.foo'];
π Actual behavior
Was not able utilize a conditional type within either the index signature or the value of a mapped type.
π Expected behavior
Should be able utilize a conditional type within either the index signature or the value of a mapped type.