Closed
Description
TypeScript Version: master (b2bae85)
Search Terms: mapped type parameter member index signature constraint constrained union
Code (with noImplicitAny)
function foo1<K extends string>(arg: { [P in K]: string }) {
// Actual: Error: Element implicitly has an 'any' type because type '{ [P in K]: string; }' has no index signature.
return arg["test"];
}
function foo2<K extends string | number>(arg: { [P in K]: string }) {
// Actual: No error
return arg["test"];
}
function foo3<K extends "foo">(arg: { [P in K]: string }) {
// Actual: Error: Property 'foo' does not exist on type '{ [P in K]: string; }'.
return arg.foo;
}
function foo4<K extends "foo" | "bar">(arg: { [P in K]: string }) {
// Actual: No error
return arg.foo;
}
Expected behavior: Consistent behavior between foo1
and foo2
and between foo3
and foo4
.
Actual behavior: As marked.
Playground Link: link (with noImplicitAny)
Related Issues: None found.
Looks like the cause is that this line in resolvedMappedTypeMembers
in the checker is using getApparentType
, which changes either string
or "foo"
to String
(which doesn't generate an index signature) but leaves unions alone. What was the thinking here??
const keyType = constraintType.flags & TypeFlags.InstantiableNonPrimitive ? getApparentType(constraintType) : constraintType;