Skip to content

Commit

Permalink
Bring back resolving apparent type for mapped types with tuple constr…
Browse files Browse the repository at this point in the history
…aints but avoid resolving the apparent type of mapped types for contextual types
  • Loading branch information
Andarist committed Mar 19, 2023
1 parent 29d4bb9 commit 940e1ad
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 4 deletions.
12 changes: 10 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13861,7 +13861,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const typeVariable = getHomomorphicTypeVariable(type);
if (typeVariable && !type.declaration.nameType) {
const constraint = getConstraintOfTypeParameter(typeVariable);
if (constraint && everyType(constraint, isArrayType)) {
if (constraint && everyType(constraint, isArrayOrTupleType)) {
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
}
}
Expand Down Expand Up @@ -29205,7 +29205,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
getContextualType(node, contextFlags);
const instantiatedType = instantiateContextualType(contextualType, node, contextFlags);
if (instantiatedType && !(contextFlags && contextFlags & ContextFlags.NoConstraints && instantiatedType.flags & TypeFlags.TypeVariable)) {
const apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true);
const apparentType = mapType(
instantiatedType,
// When obtaining apparent type of *contextual* type we don't want to get apparent type of mapped types.
// That would evaluate mapped types with array or tuple type constraints too eagerly
// and thus it would prevent `getTypeOfPropertyOfContextualType` from obtaining per-position contextual type for elements of array literal expressions.
// Apparent type of other mapped types is already the mapped type itself so we can just avoid calling `getApparentType` here for all mapped types.
t => getObjectFlags(t) & ObjectFlags.Mapped ? t : getApparentType(t),
/*noReductions*/ true
);
return apparentType.flags & TypeFlags.Union && isObjectLiteralExpression(node) ? discriminateContextualTypeByObjectMembers(node, apparentType as UnionType) :
apparentType.flags & TypeFlags.Union && isJsxAttributes(node) ? discriminateContextualTypeByJSXAttributes(node, apparentType as UnionType) :
apparentType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
=== tests/cases/compiler/mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts ===
type HomomorphicMappedType<T> = { [P in keyof T]: T[P] extends string ? boolean : null }
>HomomorphicMappedType : HomomorphicMappedType<T>
>null : null

function test1<T extends [number] | [string]>(args: T) {
>test1 : <T extends [number] | [string]>(args: T) => void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

type HomomorphicMappedType<T> = { [P in keyof T]: T[P] extends string ? boolean : null }
>HomomorphicMappedType : HomomorphicMappedType<T>
>null : null

declare function test<T extends [number] | [string]>(
>test : <T extends [number] | [string]>(args: T, fn: (...args: HomomorphicMappedType<T>) => void) => void
Expand Down

0 comments on commit 940e1ad

Please sign in to comment.