mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 21:06:50 -05:00
Preserve the homomorphism of inlined mapped types in declaration emit (#48091)
This commit is contained in:
@@ -5079,10 +5079,16 @@ namespace ts {
|
||||
const readonlyToken = type.declaration.readonlyToken ? factory.createToken(type.declaration.readonlyToken.kind) as ReadonlyKeyword | PlusToken | MinusToken : undefined;
|
||||
const questionToken = type.declaration.questionToken ? factory.createToken(type.declaration.questionToken.kind) as QuestionToken | PlusToken | MinusToken : undefined;
|
||||
let appropriateConstraintTypeNode: TypeNode;
|
||||
let newTypeVariable: TypeReferenceNode | undefined;
|
||||
if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
|
||||
// We have a { [P in keyof T]: X }
|
||||
// We do this to ensure we retain the toplevel keyof-ness of the type which may be lost due to keyof distribution during `getConstraintTypeFromMappedType`
|
||||
appropriateConstraintTypeNode = factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context));
|
||||
if (!(getModifiersTypeFromMappedType(type).flags & TypeFlags.TypeParameter) && context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) {
|
||||
const newParam = createTypeParameter(createSymbol(SymbolFlags.TypeParameter, "T" as __String));
|
||||
const name = typeParameterToName(newParam, context);
|
||||
newTypeVariable = factory.createTypeReferenceNode(name);
|
||||
}
|
||||
appropriateConstraintTypeNode = factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, newTypeVariable || typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context));
|
||||
}
|
||||
else {
|
||||
appropriateConstraintTypeNode = typeToTypeNodeHelper(getConstraintTypeFromMappedType(type), context);
|
||||
@@ -5092,7 +5098,19 @@ namespace ts {
|
||||
const templateTypeNode = typeToTypeNodeHelper(removeMissingType(getTemplateTypeFromMappedType(type), !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), context);
|
||||
const mappedTypeNode = factory.createMappedTypeNode(readonlyToken, typeParameterNode, nameTypeNode, questionToken, templateTypeNode, /*members*/ undefined);
|
||||
context.approximateLength += 10;
|
||||
return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine);
|
||||
const result = setEmitFlags(mappedTypeNode, EmitFlags.SingleLine);
|
||||
if (isMappedTypeWithKeyofConstraintDeclaration(type) && !(getModifiersTypeFromMappedType(type).flags & TypeFlags.TypeParameter) && context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) {
|
||||
// homomorphic mapped type with a non-homomorphic naive inlining
|
||||
// wrap it with a conditional like `SomeModifiersType extends infer U ? {..the mapped type...} : never` to ensure the resulting
|
||||
// type stays homomorphic
|
||||
return factory.createConditionalTypeNode(
|
||||
typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context),
|
||||
factory.createInferTypeNode(factory.createTypeParameterDeclaration(factory.cloneNode(newTypeVariable!.typeName) as Identifier)),
|
||||
result,
|
||||
factory.createKeywordTypeNode(SyntaxKind.NeverKeyword)
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function createAnonymousTypeNode(type: ObjectType): TypeNode {
|
||||
|
||||
Reference in New Issue
Block a user