Add assignability rule relaxing the assignability of partial mapped types (#30112)
* Add assignability rule relaxing the assignability of partial mapped types * Update comment
This commit is contained in:
parent
45a6cb7066
commit
58e847abb5
|
@ -12725,16 +12725,26 @@ namespace ts {
|
|||
(<IndexedAccessType>template).indexType === getTypeParameterFromMappedType(target)) {
|
||||
return Ternary.True;
|
||||
}
|
||||
// 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.
|
||||
if (!isGenericMappedType(source) && isRelatedTo(getConstraintTypeFromMappedType(target), getIndexType(source))) {
|
||||
const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target));
|
||||
const templateType = getTemplateTypeFromMappedType(target);
|
||||
if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
|
||||
return result;
|
||||
if (!isGenericMappedType(source)) {
|
||||
const targetConstraint = getConstraintTypeFromMappedType(target);
|
||||
const sourceKeys = getIndexType(source);
|
||||
const hasOptionalUnionKeys = modifiers & MappedTypeModifiers.IncludeOptional && targetConstraint.flags & TypeFlags.Union;
|
||||
const filteredByApplicability = hasOptionalUnionKeys ? filterType(targetConstraint, t => !!isRelatedTo(t, 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
|
||||
? !(filteredByApplicability!.flags & TypeFlags.Never)
|
||||
: isRelatedTo(targetConstraint, sourceKeys)) {
|
||||
const indexingType = hasOptionalUnionKeys ? filteredByApplicability! : getTypeParameterFromMappedType(target);
|
||||
const indexedAccessType = getIndexedAccessType(source, indexingType);
|
||||
const templateType = getTemplateTypeFromMappedType(target);
|
||||
if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
originalErrorInfo = errorInfo;
|
||||
errorInfo = saveErrorInfo;
|
||||
}
|
||||
originalErrorInfo = errorInfo;
|
||||
errorInfo = saveErrorInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
//// [mappedTypePartialNonHomomorphicBaseConstraint.ts]
|
||||
export type Errors<D> = { readonly [K in keyof D | "base"]?: string[] };
|
||||
|
||||
class Model<D> {
|
||||
getErrors(): Errors<D> {
|
||||
return { base: ["some base error"] };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypePartialNonHomomorphicBaseConstraint.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var Model = /** @class */ (function () {
|
||||
function Model() {
|
||||
}
|
||||
Model.prototype.getErrors = function () {
|
||||
return { base: ["some base error"] };
|
||||
};
|
||||
return Model;
|
||||
}());
|
|
@ -0,0 +1,21 @@
|
|||
=== tests/cases/compiler/mappedTypePartialNonHomomorphicBaseConstraint.ts ===
|
||||
export type Errors<D> = { readonly [K in keyof D | "base"]?: string[] };
|
||||
>Errors : Symbol(Errors, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 0, 0))
|
||||
>D : Symbol(D, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 0, 19))
|
||||
>K : Symbol(K, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 0, 36))
|
||||
>D : Symbol(D, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 0, 19))
|
||||
|
||||
class Model<D> {
|
||||
>Model : Symbol(Model, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 0, 72))
|
||||
>D : Symbol(D, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 2, 12))
|
||||
|
||||
getErrors(): Errors<D> {
|
||||
>getErrors : Symbol(Model.getErrors, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 2, 16))
|
||||
>Errors : Symbol(Errors, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 0, 0))
|
||||
>D : Symbol(D, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 2, 12))
|
||||
|
||||
return { base: ["some base error"] };
|
||||
>base : Symbol(base, Decl(mappedTypePartialNonHomomorphicBaseConstraint.ts, 4, 12))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
=== tests/cases/compiler/mappedTypePartialNonHomomorphicBaseConstraint.ts ===
|
||||
export type Errors<D> = { readonly [K in keyof D | "base"]?: string[] };
|
||||
>Errors : Errors<D>
|
||||
|
||||
class Model<D> {
|
||||
>Model : Model<D>
|
||||
|
||||
getErrors(): Errors<D> {
|
||||
>getErrors : () => Errors<D>
|
||||
|
||||
return { base: ["some base error"] };
|
||||
>{ base: ["some base error"] } : { base: string[]; }
|
||||
>base : string[]
|
||||
>["some base error"] : string[]
|
||||
>"some base error" : "some base error"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export type Errors<D> = { readonly [K in keyof D | "base"]?: string[] };
|
||||
|
||||
class Model<D> {
|
||||
getErrors(): Errors<D> {
|
||||
return { base: ["some base error"] };
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue