Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Lower priority for inferences made from partial reverse mapped types
  • Loading branch information
ahejlsberg committed May 8, 2019
1 parent 6aaeb52 commit 4af3a3b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
13 changes: 7 additions & 6 deletions src/compiler/checker.ts
Expand Up @@ -14898,11 +14898,8 @@ namespace ts {

function createReverseMappedType(source: Type, target: MappedType, constraint: IndexType) {
// We consider a source type reverse mappable if it has a string index signature or if
// it has one or more properties and all properties have inferable types.
const properties = getPropertiesOfType(source);
const isReverseMappable = getIndexInfoOfType(source, IndexKind.String) ||
properties.length !== 0 && every(properties, prop => isPartiallyInferableType(getTypeOfSymbol(prop)));
if (!isReverseMappable) {
// it has one or more properties and is of a partially inferable type.
if (!(getIndexInfoOfType(source, IndexKind.String) || getPropertiesOfType(source).length !== 0 && isPartiallyInferableType(source))) {
return undefined;
}
// For arrays and tuples we infer new arrays and tuples where the reverse mapping has been
Expand Down Expand Up @@ -15287,7 +15284,11 @@ namespace ts {
const inferredType = inferTypeForHomomorphicMappedType(source, target, <IndexType>constraintType);
if (inferredType) {
const savePriority = priority;
priority |= InferencePriority.HomomorphicMappedType;
// We assign a lower priority to inferences made from types containing non-inferrable
// types because we may only have a partial result (i.e. we may have failed to make
// reverse inferences for some properties).
priority |= getObjectFlags(source) & ObjectFlags.NonInferrableType ?
InferencePriority.PartialHomomorphicMappedType : InferencePriority.HomomorphicMappedType;
inferFromTypes(inferredType, inference.typeParameter);
priority = savePriority;
}
Expand Down
19 changes: 10 additions & 9 deletions src/compiler/types.ts
Expand Up @@ -4405,15 +4405,16 @@ namespace ts {
export type TypeMapper = (t: TypeParameter) => Type;

export const enum InferencePriority {
NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type
HomomorphicMappedType = 1 << 1, // Reverse inference for homomorphic mapped type
MappedTypeConstraint = 1 << 2, // Reverse inference for mapped type
ReturnType = 1 << 3, // Inference made from return type of generic function
LiteralKeyof = 1 << 4, // Inference made from a string literal to a keyof T
NoConstraints = 1 << 5, // Don't infer from constraints of instantiable types
AlwaysStrict = 1 << 6, // Always use strict rules for contravariant inferences

PriorityImpliesCombination = ReturnType | MappedTypeConstraint | LiteralKeyof, // These priorities imply that the resulting type should be a combination of all candidates
NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type
HomomorphicMappedType = 1 << 1, // Reverse inference for homomorphic mapped type
PartialHomomorphicMappedType = 1 << 2, // Partial reverse inference for homomorphic mapped type
MappedTypeConstraint = 1 << 3, // Reverse inference for mapped type
ReturnType = 1 << 4, // Inference made from return type of generic function
LiteralKeyof = 1 << 5, // Inference made from a string literal to a keyof T
NoConstraints = 1 << 6, // Don't infer from constraints of instantiable types
AlwaysStrict = 1 << 7, // Always use strict rules for contravariant inferences

PriorityImpliesCombination = ReturnType | MappedTypeConstraint | LiteralKeyof, // These priorities imply that the resulting type should be a combination of all candidates
}

/* @internal */
Expand Down

0 comments on commit 4af3a3b

Please sign in to comment.