Merge pull request #32071 from andrewbranch/bug/31070

Allow assignability of non-empty object to generic mapped type
This commit is contained in:
Andrew Branch
2019-07-01 13:18:44 -07:00
committed by GitHub
8 changed files with 261 additions and 120 deletions

View File

@@ -13212,14 +13212,14 @@ namespace ts {
if (!isGenericMappedType(source)) {
const targetConstraint = getConstraintTypeFromMappedType(target);
const sourceKeys = getIndexType(source, /*stringsOnly*/ undefined, /*noIndexSignatures*/ true);
const hasOptionalUnionKeys = modifiers & MappedTypeModifiers.IncludeOptional && targetConstraint.flags & TypeFlags.Union;
const filteredByApplicability = hasOptionalUnionKeys ? filterType(targetConstraint, t => !!isRelatedTo(t, sourceKeys)) : undefined;
const includeOptional = modifiers & MappedTypeModifiers.IncludeOptional;
const filteredByApplicability = includeOptional ? intersectTypes(targetConstraint, sourceKeys) : undefined;
// A source type T is related to a target type { [P in Q]: X } if Q is related to keyof T and T[Q] is related to X.
// A source type T is related to a target type { [P in Q]?: X } if some constituent Q' of Q is related to keyof T and T[Q'] is related to X.
if (hasOptionalUnionKeys
if (includeOptional
? !(filteredByApplicability!.flags & TypeFlags.Never)
: isRelatedTo(targetConstraint, sourceKeys)) {
const indexingType = hasOptionalUnionKeys ? filteredByApplicability! : getTypeParameterFromMappedType(target);
const indexingType = filteredByApplicability || getTypeParameterFromMappedType(target);
const indexedAccessType = getIndexedAccessType(source, indexingType);
const templateType = getTemplateTypeFromMappedType(target);
if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {