mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
Parenthesize the fn or constructor type with type parameter when writing it in type argument
Fixes #8105
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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -60,63 +60,4 @@ export declare class bluebird<T> {
|
||||
static all: Array<bluebird<any>>;
|
||||
}
|
||||
export declare function runSampleWorks<A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>): Promise<(<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}>;
|
||||
export declare function runSampleBreaks<A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>): Promise<<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T>;
|
||||
|
||||
|
||||
//// [DtsFileErrors]
|
||||
|
||||
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,141): error TS2314: Generic type 'Promise<T>' requires 1 type argument(s).
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,148): error TS1144: '{' or ';' expected.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,150): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,153): error TS2304: Cannot find name 'f'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,154): error TS1005: ')' expected.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,160): error TS2304: Cannot find name 'A'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,167): error TS2304: Cannot find name 'B'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,174): error TS2304: Cannot find name 'C'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,181): error TS2304: Cannot find name 'D'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,188): error TS2304: Cannot find name 'E'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,194): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,195): error TS1005: ';' expected.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,197): error TS1128: Declaration or statement expected.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,200): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/compiler/declarationEmitPromise.d.ts(5,202): error TS1109: Expression expected.
|
||||
|
||||
|
||||
==== tests/cases/compiler/declarationEmitPromise.d.ts (15 errors) ====
|
||||
export declare class bluebird<T> {
|
||||
static all: Array<bluebird<any>>;
|
||||
}
|
||||
export declare function runSampleWorks<A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>): Promise<(<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}>;
|
||||
export declare function runSampleBreaks<A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>): Promise<<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T>;
|
||||
~~~~~~~
|
||||
!!! error TS2314: Generic type 'Promise<T>' requires 1 type argument(s).
|
||||
~~
|
||||
!!! error TS1144: '{' or ';' expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'f'.
|
||||
~
|
||||
!!! error TS1005: ')' expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'A'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'B'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'C'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'D'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'E'.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
~
|
||||
!!! error TS1005: ';' expected.
|
||||
~~
|
||||
!!! error TS1128: Declaration or statement expected.
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
|
||||
export declare function runSampleBreaks<A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>): Promise<(<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)>;
|
||||
|
||||
@@ -96,7 +96,7 @@ export async function runSampleWorks<A, B, C, D, E>(
|
||||
}
|
||||
|
||||
export async function runSampleBreaks<A, B, C, D, E>(
|
||||
>runSampleBreaks : <A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) => Promise<<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T>
|
||||
>runSampleBreaks : <A, B, C, D, E>(a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) => Promise<(<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T)>
|
||||
>A : A
|
||||
>B : B
|
||||
>C : C
|
||||
|
||||
@@ -4,7 +4,7 @@ class X<A> {
|
||||
>A : A
|
||||
|
||||
prop: X< <Tany>() => Tany >;
|
||||
>prop : X<<Tany>() => Tany>
|
||||
>prop : X<(<Tany>() => Tany)>
|
||||
>X : X<A>
|
||||
>Tany : Tany
|
||||
>Tany : Tany
|
||||
|
||||
Reference in New Issue
Block a user