Pick<T, K> and similar mapped types propagate modifiers from T
This commit is contained in:
parent
798d080df1
commit
33b512548e
|
@ -4512,12 +4512,11 @@ namespace ts {
|
||||||
// Resolve upfront such that recursive references see an empty object type.
|
// Resolve upfront such that recursive references see an empty object type.
|
||||||
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||||
// In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
|
// In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
|
||||||
// and T as the template type. If K is of the form 'keyof S', the mapped type and S are
|
// and T as the template type.
|
||||||
// homomorphic and we copy property modifiers from corresponding properties in S.
|
|
||||||
const typeParameter = getTypeParameterFromMappedType(type);
|
const typeParameter = getTypeParameterFromMappedType(type);
|
||||||
const constraintType = getConstraintTypeFromMappedType(type);
|
const constraintType = getConstraintTypeFromMappedType(type);
|
||||||
const homomorphicType = getHomomorphicTypeFromMappedType(type);
|
|
||||||
const templateType = getTemplateTypeFromMappedType(type);
|
const templateType = getTemplateTypeFromMappedType(type);
|
||||||
|
const modifiersType = getModifiersTypeFromMappedType(type);
|
||||||
const templateReadonly = !!type.declaration.readonlyToken;
|
const templateReadonly = !!type.declaration.readonlyToken;
|
||||||
const templateOptional = !!type.declaration.questionToken;
|
const templateOptional = !!type.declaration.questionToken;
|
||||||
// First, if the constraint type is a type parameter, obtain the base constraint. Then,
|
// First, if the constraint type is a type parameter, obtain the base constraint. Then,
|
||||||
|
@ -4536,11 +4535,11 @@ namespace ts {
|
||||||
// Otherwise, for type string create a string index signature.
|
// Otherwise, for type string create a string index signature.
|
||||||
if (t.flags & TypeFlags.StringLiteral) {
|
if (t.flags & TypeFlags.StringLiteral) {
|
||||||
const propName = (<LiteralType>t).text;
|
const propName = (<LiteralType>t).text;
|
||||||
const homomorphicProp = homomorphicType && getPropertyOfType(homomorphicType, propName);
|
const modifiersProp = getPropertyOfType(modifiersType, propName);
|
||||||
const isOptional = templateOptional || !!(homomorphicProp && homomorphicProp.flags & SymbolFlags.Optional);
|
const isOptional = templateOptional || !!(modifiersProp && modifiersProp.flags & SymbolFlags.Optional);
|
||||||
const prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName);
|
const prop = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | (isOptional ? SymbolFlags.Optional : 0), propName);
|
||||||
prop.type = propType;
|
prop.type = propType;
|
||||||
prop.isReadonly = templateReadonly || homomorphicProp && isReadonlySymbol(homomorphicProp);
|
prop.isReadonly = templateReadonly || modifiersProp && isReadonlySymbol(modifiersProp);
|
||||||
members[propName] = prop;
|
members[propName] = prop;
|
||||||
}
|
}
|
||||||
else if (t.flags & TypeFlags.String) {
|
else if (t.flags & TypeFlags.String) {
|
||||||
|
@ -4567,9 +4566,16 @@ namespace ts {
|
||||||
unknownType);
|
unknownType);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHomomorphicTypeFromMappedType(type: MappedType) {
|
function getModifiersTypeFromMappedType(type: MappedType) {
|
||||||
const constraint = getConstraintDeclaration(getTypeParameterFromMappedType(type));
|
if (!type.modifiersType) {
|
||||||
return constraint.kind === SyntaxKind.TypeOperator ? instantiateType(getTypeFromTypeNode((<TypeOperatorNode>constraint).type), type.mapper || identityMapper) : undefined;
|
// If the mapped type was declared as { [P in keyof T]: X } or as { [P in K]: X }, where
|
||||||
|
// K is constrained to 'K extends keyof T', then we will copy property modifiers from T.
|
||||||
|
const declaredType = <MappedType>getTypeFromMappedTypeNode(type.declaration);
|
||||||
|
const constraint = getConstraintTypeFromMappedType(declaredType);
|
||||||
|
const extendedConstraint = constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>constraint) : constraint;
|
||||||
|
type.modifiersType = extendedConstraint.flags & TypeFlags.Index ? instantiateType((<IndexType>extendedConstraint).type, type.mapper || identityMapper) : emptyObjectType;
|
||||||
|
}
|
||||||
|
return type.modifiersType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getErasedTemplateTypeFromMappedType(type: MappedType) {
|
function getErasedTemplateTypeFromMappedType(type: MappedType) {
|
||||||
|
|
|
@ -2933,6 +2933,7 @@ namespace ts {
|
||||||
typeParameter?: TypeParameter;
|
typeParameter?: TypeParameter;
|
||||||
constraintType?: Type;
|
constraintType?: Type;
|
||||||
templateType?: Type;
|
templateType?: Type;
|
||||||
|
modifiersType?: Type;
|
||||||
mapper?: TypeMapper; // Instantiation mapper
|
mapper?: TypeMapper; // Instantiation mapper
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue