mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-27 13:42:16 -05:00
Merge pull request #8159 from Microsoft/declFileFirstTypeArgumentIsGenericFunctionType
Fixes scenarios of generating declaration file when first type argument is generic function type
This commit is contained in:
@@ -1990,7 +1990,7 @@ namespace ts {
|
||||
}
|
||||
if (pos < end) {
|
||||
writePunctuation(writer, SyntaxKind.LessThanToken);
|
||||
writeType(typeArguments[pos], TypeFormatFlags.None);
|
||||
writeType(typeArguments[pos], TypeFormatFlags.InFirstTypeArgument);
|
||||
pos++;
|
||||
while (pos < end) {
|
||||
writePunctuation(writer, SyntaxKind.CommaToken);
|
||||
@@ -2143,6 +2143,19 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function shouldAddParenthesisAroundFunctionType(callSignature: Signature, flags: TypeFormatFlags) {
|
||||
if (flags & TypeFormatFlags.InElementType) {
|
||||
return true;
|
||||
}
|
||||
else if (flags & TypeFormatFlags.InFirstTypeArgument) {
|
||||
// Add parenthesis around function type for the first type argument to avoid ambiguity
|
||||
const typeParameters = callSignature.target && (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature) ?
|
||||
callSignature.target.typeParameters : callSignature.typeParameters;
|
||||
return typeParameters && typeParameters.length !== 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function writeLiteralType(type: ObjectType, flags: TypeFormatFlags) {
|
||||
const resolved = resolveStructuredTypeMembers(type);
|
||||
if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
|
||||
@@ -2153,11 +2166,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
|
||||
if (flags & TypeFormatFlags.InElementType) {
|
||||
const parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags);
|
||||
if (parenthesizeSignature) {
|
||||
writePunctuation(writer, SyntaxKind.OpenParenToken);
|
||||
}
|
||||
buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | TypeFormatFlags.WriteArrowStyleSignature, /*kind*/ undefined, symbolStack);
|
||||
if (flags & TypeFormatFlags.InElementType) {
|
||||
if (parenthesizeSignature) {
|
||||
writePunctuation(writer, SyntaxKind.CloseParenToken);
|
||||
}
|
||||
return;
|
||||
@@ -2317,12 +2331,14 @@ namespace ts {
|
||||
function buildDisplayForTypeArgumentsAndDelimiters(typeParameters: TypeParameter[], mapper: TypeMapper, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
if (typeParameters && typeParameters.length) {
|
||||
writePunctuation(writer, SyntaxKind.LessThanToken);
|
||||
let flags = TypeFormatFlags.InFirstTypeArgument;
|
||||
for (let i = 0; i < typeParameters.length; i++) {
|
||||
if (i > 0) {
|
||||
writePunctuation(writer, SyntaxKind.CommaToken);
|
||||
writeSpace(writer);
|
||||
flags = TypeFormatFlags.None;
|
||||
}
|
||||
buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, TypeFormatFlags.None);
|
||||
buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, flags);
|
||||
}
|
||||
writePunctuation(writer, SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
|
||||
@@ -1377,6 +1377,7 @@ namespace ts {
|
||||
function emitSignatureDeclaration(node: SignatureDeclaration) {
|
||||
const prevEnclosingDeclaration = enclosingDeclaration;
|
||||
enclosingDeclaration = node;
|
||||
let closeParenthesizedFunctionType = false;
|
||||
|
||||
if (node.kind === SyntaxKind.IndexSignature) {
|
||||
// Index signature can have readonly modifier
|
||||
@@ -1388,6 +1389,16 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.ConstructSignature || node.kind === SyntaxKind.ConstructorType) {
|
||||
write("new ");
|
||||
}
|
||||
else if (node.kind === SyntaxKind.FunctionType) {
|
||||
const currentOutput = writer.getText();
|
||||
// Do not generate incorrect type when function type with type parameters is type argument
|
||||
// This could happen if user used space between two '<' making it error free
|
||||
// e.g var x: A< <Tany>(a: Tany)=>Tany>;
|
||||
if (node.typeParameters && currentOutput.charAt(currentOutput.length - 1) === "<") {
|
||||
closeParenthesizedFunctionType = true;
|
||||
write("(");
|
||||
}
|
||||
}
|
||||
emitTypeParameters(node.typeParameters);
|
||||
write("(");
|
||||
}
|
||||
@@ -1421,6 +1432,9 @@ namespace ts {
|
||||
write(";");
|
||||
writeLine();
|
||||
}
|
||||
else if (closeParenthesizedFunctionType) {
|
||||
write(")");
|
||||
}
|
||||
|
||||
function getReturnTypeVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
let diagnosticMessage: DiagnosticMessage;
|
||||
|
||||
@@ -1820,6 +1820,7 @@ namespace ts {
|
||||
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
|
||||
InElementType = 0x00000040, // Writing an array or union element type
|
||||
UseFullyQualifiedType = 0x00000080, // Write out the fully qualified type name (eg. Module.Type, instead of Type)
|
||||
InFirstTypeArgument = 0x00000100, // Writing first type argument of the instantiated type
|
||||
}
|
||||
|
||||
export const enum SymbolFormatFlags {
|
||||
|
||||
Reference in New Issue
Block a user