Permit reverse mapped types to be created from partially inferable types

This commit is contained in:
Anders Hejlsberg 2019-05-02 15:15:03 -07:00
parent a86fa20b02
commit 8891d4f375

View file

@ -14887,10 +14887,22 @@ namespace ts {
return type;
}
// We consider a type to be partially inferable if it isn't marked non-inferable or if it is
// an object literal type with at least one property of an inferable type. For example, an object
// literal { a: 123, b: x => true } is marked non-inferable because it contains a context sensitive
// arrow function, but is considered partially inferable because property 'a' has an inferable type.
function isPartiallyInferableType(type: Type): boolean {
return !(getObjectFlags(type) & ObjectFlags.NonInferrableType) ||
isObjectLiteralType(type) && some(getPropertiesOfType(type), prop => isPartiallyInferableType(getTypeOfSymbol(prop)));
}
function createReverseMappedType(source: Type, target: MappedType, constraint: IndexType) {
// If any property contains context sensitive functions that have been skipped, the source type
// is incomplete and we can't infer a meaningful input type.
if (getObjectFlags(source) & ObjectFlags.NonInferrableType || getPropertiesOfType(source).length === 0 && !getIndexInfoOfType(source, IndexKind.String)) {
// 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) {
return undefined;
}
// For arrays and tuples we infer new arrays and tuples where the reverse mapping has been