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:
Sheetal Nandi 2016-04-19 10:41:06 -07:00
commit edc3ed37ca
12 changed files with 714 additions and 5 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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 {

View File

@ -0,0 +1,66 @@
//// [declarationEmitFirstTypeArgumentGenericFunctionType.ts]
class X<A> {
}
var prop11: X< <Tany>() => Tany >; // spaces before the first type argument
var prop12: X<(<Tany>() => Tany)>; // spaces before the first type argument
function f1() { // Inferred return type
return prop11;
}
function f2() { // Inferred return type
return prop12;
}
function f3(): X< <Tany>() => Tany> { // written with space before type argument
return prop11;
}
function f4(): X<(<Tany>() => Tany)> { // written type with parenthesis
return prop12;
}
class Y<A, B> {
}
var prop2: Y<string[], <Tany>() => Tany>; // No space after second type argument
var prop2: Y<string[], <Tany>() => Tany>; // space after second type argument
var prop3: Y< <Tany>() => Tany, <Tany>() => Tany>; // space before first type argument
var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>; // parenthesized first type argument
//// [declarationEmitFirstTypeArgumentGenericFunctionType.js]
class X {
}
var prop11; // spaces before the first type argument
var prop12; // spaces before the first type argument
function f1() {
return prop11;
}
function f2() {
return prop12;
}
function f3() {
return prop11;
}
function f4() {
return prop12;
}
class Y {
}
var prop2; // No space after second type argument
var prop2; // space after second type argument
var prop3; // space before first type argument
var prop4; // parenthesized first type argument
//// [declarationEmitFirstTypeArgumentGenericFunctionType.d.ts]
declare class X<A> {
}
declare var prop11: X<(<Tany>() => Tany)>;
declare var prop12: X<(<Tany>() => Tany)>;
declare function f1(): X<(<Tany>() => Tany)>;
declare function f2(): X<(<Tany>() => Tany)>;
declare function f3(): X<(<Tany>() => Tany)>;
declare function f4(): X<(<Tany>() => Tany)>;
declare class Y<A, B> {
}
declare var prop2: Y<string[], <Tany>() => Tany>;
declare var prop2: Y<string[], <Tany>() => Tany>;
declare var prop3: Y<(<Tany>() => Tany), <Tany>() => Tany>;
declare var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>;

View File

@ -0,0 +1,81 @@
=== tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts ===
class X<A> {
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
>A : Symbol(A, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 1, 8))
}
var prop11: X< <Tany>() => Tany >; // spaces before the first type argument
>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3))
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 16))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 16))
var prop12: X<(<Tany>() => Tany)>; // spaces before the first type argument
>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3))
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 16))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 16))
function f1() { // Inferred return type
>f1 : Symbol(f1, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 34))
return prop11;
>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3))
}
function f2() { // Inferred return type
>f2 : Symbol(f2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 7, 1))
return prop12;
>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3))
}
function f3(): X< <Tany>() => Tany> { // written with space before type argument
>f3 : Symbol(f3, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 10, 1))
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 11, 19))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 11, 19))
return prop11;
>prop11 : Symbol(prop11, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 3, 3))
}
function f4(): X<(<Tany>() => Tany)> { // written type with parenthesis
>f4 : Symbol(f4, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 13, 1))
>X : Symbol(X, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 0, 0))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 14, 19))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 14, 19))
return prop12;
>prop12 : Symbol(prop12, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 4, 3))
}
class Y<A, B> {
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
>A : Symbol(A, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 17, 8))
>B : Symbol(B, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 17, 10))
}
var prop2: Y<string[], <Tany>() => Tany>; // No space after second type argument
>prop2 : Symbol(prop2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 3), Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 3))
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 24))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 24))
var prop2: Y<string[], <Tany>() => Tany>; // space after second type argument
>prop2 : Symbol(prop2, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 19, 3), Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 3))
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 24))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 20, 24))
var prop3: Y< <Tany>() => Tany, <Tany>() => Tany>; // space before first type argument
>prop3 : Symbol(prop3, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 3))
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 15))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 15))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 33))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 21, 33))
var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>; // parenthesized first type argument
>prop4 : Symbol(prop4, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 3))
>Y : Symbol(Y, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 16, 1))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 15))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 15))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 34))
>Tany : Symbol(Tany, Decl(declarationEmitFirstTypeArgumentGenericFunctionType.ts, 22, 34))

View File

@ -0,0 +1,81 @@
=== tests/cases/compiler/declarationEmitFirstTypeArgumentGenericFunctionType.ts ===
class X<A> {
>X : X<A>
>A : A
}
var prop11: X< <Tany>() => Tany >; // spaces before the first type argument
>prop11 : X<(<Tany>() => Tany)>
>X : X<A>
>Tany : Tany
>Tany : Tany
var prop12: X<(<Tany>() => Tany)>; // spaces before the first type argument
>prop12 : X<(<Tany>() => Tany)>
>X : X<A>
>Tany : Tany
>Tany : Tany
function f1() { // Inferred return type
>f1 : () => X<(<Tany>() => Tany)>
return prop11;
>prop11 : X<(<Tany>() => Tany)>
}
function f2() { // Inferred return type
>f2 : () => X<(<Tany>() => Tany)>
return prop12;
>prop12 : X<(<Tany>() => Tany)>
}
function f3(): X< <Tany>() => Tany> { // written with space before type argument
>f3 : () => X<(<Tany>() => Tany)>
>X : X<A>
>Tany : Tany
>Tany : Tany
return prop11;
>prop11 : X<(<Tany>() => Tany)>
}
function f4(): X<(<Tany>() => Tany)> { // written type with parenthesis
>f4 : () => X<(<Tany>() => Tany)>
>X : X<A>
>Tany : Tany
>Tany : Tany
return prop12;
>prop12 : X<(<Tany>() => Tany)>
}
class Y<A, B> {
>Y : Y<A, B>
>A : A
>B : B
}
var prop2: Y<string[], <Tany>() => Tany>; // No space after second type argument
>prop2 : Y<string[], <Tany>() => Tany>
>Y : Y<A, B>
>Tany : Tany
>Tany : Tany
var prop2: Y<string[], <Tany>() => Tany>; // space after second type argument
>prop2 : Y<string[], <Tany>() => Tany>
>Y : Y<A, B>
>Tany : Tany
>Tany : Tany
var prop3: Y< <Tany>() => Tany, <Tany>() => Tany>; // space before first type argument
>prop3 : Y<(<Tany>() => Tany), <Tany>() => Tany>
>Y : Y<A, B>
>Tany : Tany
>Tany : Tany
>Tany : Tany
>Tany : Tany
var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>; // parenthesized first type argument
>prop4 : Y<(<Tany>() => Tany), <Tany>() => Tany>
>Y : Y<A, B>
>Tany : Tany
>Tany : Tany
>Tany : Tany
>Tany : Tany

View File

@ -0,0 +1,63 @@
//// [declarationEmitPromise.ts]
export class bluebird<T> {
static all: Array<bluebird<any>>;
}
export async function runSampleWorks<A, B, C, D, E>(
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
f.apply(this, result);
let rfunc: typeof func & {} = func as any; // <- This is the only difference
return rfunc
}
export async function runSampleBreaks<A, B, C, D, E>(
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
f.apply(this, result);
let rfunc: typeof func = func as any; // <- This is the only difference
return rfunc
}
//// [declarationEmitPromise.js]
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator.throw(value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments)).next());
});
};
class bluebird {
}
exports.bluebird = bluebird;
function runSampleWorks(a, b, c, d, e) {
return __awaiter(this, void 0, void 0, function* () {
let result = yield bluebird.all([a, b, c, d, e].filter(el => !!el));
let func = (f) => f.apply(this, result);
let rfunc = func; // <- This is the only difference
return rfunc;
});
}
exports.runSampleWorks = runSampleWorks;
function runSampleBreaks(a, b, c, d, e) {
return __awaiter(this, void 0, void 0, function* () {
let result = yield bluebird.all([a, b, c, d, e].filter(el => !!el));
let func = (f) => f.apply(this, result);
let rfunc = func; // <- This is the only difference
return rfunc;
});
}
exports.runSampleBreaks = runSampleBreaks;
//// [declarationEmitPromise.d.ts]
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)>;

View File

@ -0,0 +1,155 @@
=== tests/cases/compiler/declarationEmitPromise.ts ===
export class bluebird<T> {
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitPromise.ts, 1, 22))
static all: Array<bluebird<any>>;
>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
}
export async function runSampleWorks<A, B, C, D, E>(
>runSampleWorks : Symbol(runSampleWorks, Decl(declarationEmitPromise.ts, 3, 1))
>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37))
>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39))
>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42))
>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45))
>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48))
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
>a : Symbol(a, Decl(declarationEmitPromise.ts, 5, 52))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37))
>b : Symbol(b, Decl(declarationEmitPromise.ts, 6, 19))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39))
>c : Symbol(c, Decl(declarationEmitPromise.ts, 6, 36))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42))
>d : Symbol(d, Decl(declarationEmitPromise.ts, 6, 53))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45))
>e : Symbol(e, Decl(declarationEmitPromise.ts, 6, 70))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48))
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
>result : Symbol(result, Decl(declarationEmitPromise.ts, 7, 7))
>bluebird.all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
>[a, b, c, d, e].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(declarationEmitPromise.ts, 5, 52))
>b : Symbol(b, Decl(declarationEmitPromise.ts, 6, 19))
>c : Symbol(c, Decl(declarationEmitPromise.ts, 6, 36))
>d : Symbol(d, Decl(declarationEmitPromise.ts, 6, 53))
>e : Symbol(e, Decl(declarationEmitPromise.ts, 6, 70))
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --))
>el : Symbol(el, Decl(declarationEmitPromise.ts, 7, 68))
>el : Symbol(el, Decl(declarationEmitPromise.ts, 7, 68))
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7))
>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16))
>f : Symbol(f, Decl(declarationEmitPromise.ts, 8, 19))
>a : Symbol(a, Decl(declarationEmitPromise.ts, 8, 23))
>A : Symbol(A, Decl(declarationEmitPromise.ts, 5, 37))
>b : Symbol(b, Decl(declarationEmitPromise.ts, 8, 28))
>B : Symbol(B, Decl(declarationEmitPromise.ts, 5, 39))
>c : Symbol(c, Decl(declarationEmitPromise.ts, 8, 35))
>C : Symbol(C, Decl(declarationEmitPromise.ts, 5, 42))
>d : Symbol(d, Decl(declarationEmitPromise.ts, 8, 42))
>D : Symbol(D, Decl(declarationEmitPromise.ts, 5, 45))
>e : Symbol(e, Decl(declarationEmitPromise.ts, 8, 49))
>E : Symbol(E, Decl(declarationEmitPromise.ts, 5, 48))
>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16))
>T : Symbol(T, Decl(declarationEmitPromise.ts, 8, 16))
f.apply(this, result);
>f.apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>f : Symbol(f, Decl(declarationEmitPromise.ts, 8, 19))
>apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>result : Symbol(result, Decl(declarationEmitPromise.ts, 7, 7))
let rfunc: typeof func & {} = func as any; // <- This is the only difference
>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 10, 7))
>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7))
>func : Symbol(func, Decl(declarationEmitPromise.ts, 8, 7))
return rfunc
>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 10, 7))
}
export async function runSampleBreaks<A, B, C, D, E>(
>runSampleBreaks : Symbol(runSampleBreaks, Decl(declarationEmitPromise.ts, 12, 1))
>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38))
>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40))
>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43))
>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46))
>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49))
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
>a : Symbol(a, Decl(declarationEmitPromise.ts, 14, 53))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38))
>b : Symbol(b, Decl(declarationEmitPromise.ts, 15, 19))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40))
>c : Symbol(c, Decl(declarationEmitPromise.ts, 15, 36))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43))
>d : Symbol(d, Decl(declarationEmitPromise.ts, 15, 53))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46))
>e : Symbol(e, Decl(declarationEmitPromise.ts, 15, 70))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49))
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
>result : Symbol(result, Decl(declarationEmitPromise.ts, 16, 7))
>bluebird.all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
>bluebird : Symbol(bluebird, Decl(declarationEmitPromise.ts, 0, 0))
>all : Symbol(bluebird.all, Decl(declarationEmitPromise.ts, 1, 26))
>[a, b, c, d, e].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(declarationEmitPromise.ts, 14, 53))
>b : Symbol(b, Decl(declarationEmitPromise.ts, 15, 19))
>c : Symbol(c, Decl(declarationEmitPromise.ts, 15, 36))
>d : Symbol(d, Decl(declarationEmitPromise.ts, 15, 53))
>e : Symbol(e, Decl(declarationEmitPromise.ts, 15, 70))
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --))
>el : Symbol(el, Decl(declarationEmitPromise.ts, 16, 68))
>el : Symbol(el, Decl(declarationEmitPromise.ts, 16, 68))
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7))
>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16))
>f : Symbol(f, Decl(declarationEmitPromise.ts, 17, 19))
>a : Symbol(a, Decl(declarationEmitPromise.ts, 17, 23))
>A : Symbol(A, Decl(declarationEmitPromise.ts, 14, 38))
>b : Symbol(b, Decl(declarationEmitPromise.ts, 17, 28))
>B : Symbol(B, Decl(declarationEmitPromise.ts, 14, 40))
>c : Symbol(c, Decl(declarationEmitPromise.ts, 17, 35))
>C : Symbol(C, Decl(declarationEmitPromise.ts, 14, 43))
>d : Symbol(d, Decl(declarationEmitPromise.ts, 17, 42))
>D : Symbol(D, Decl(declarationEmitPromise.ts, 14, 46))
>e : Symbol(e, Decl(declarationEmitPromise.ts, 17, 49))
>E : Symbol(E, Decl(declarationEmitPromise.ts, 14, 49))
>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16))
>T : Symbol(T, Decl(declarationEmitPromise.ts, 17, 16))
f.apply(this, result);
>f.apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>f : Symbol(f, Decl(declarationEmitPromise.ts, 17, 19))
>apply : Symbol(Function.apply, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>result : Symbol(result, Decl(declarationEmitPromise.ts, 16, 7))
let rfunc: typeof func = func as any; // <- This is the only difference
>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 19, 7))
>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7))
>func : Symbol(func, Decl(declarationEmitPromise.ts, 17, 7))
return rfunc
>rfunc : Symbol(rfunc, Decl(declarationEmitPromise.ts, 19, 7))
}

View File

@ -0,0 +1,181 @@
=== tests/cases/compiler/declarationEmitPromise.ts ===
export class bluebird<T> {
>bluebird : bluebird<T>
>T : T
static all: Array<bluebird<any>>;
>all : bluebird<any>[]
>Array : T[]
>bluebird : bluebird<T>
}
export async function runSampleWorks<A, B, C, D, E>(
>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) & {}>
>A : A
>B : B
>C : C
>D : D
>E : E
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
>a : bluebird<A>
>bluebird : bluebird<T>
>A : A
>b : bluebird<B>
>bluebird : bluebird<T>
>B : B
>c : bluebird<C>
>bluebird : bluebird<T>
>C : C
>d : bluebird<D>
>bluebird : bluebird<T>
>D : D
>e : bluebird<E>
>bluebird : bluebird<T>
>E : E
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
>result : any
>await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any
>(bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any
>(bluebird.all as any) : any
>bluebird.all as any : any
>bluebird.all : bluebird<any>[]
>bluebird : typeof bluebird
>all : bluebird<any>[]
>[a, b, c, d, e].filter(el => !!el) : bluebird<A>[]
>[a, b, c, d, e].filter : (callbackfn: (value: bluebird<A>, index: number, array: bluebird<A>[]) => any, thisArg?: any) => bluebird<A>[]
>[a, b, c, d, e] : bluebird<A>[]
>a : bluebird<A>
>b : bluebird<B>
>c : bluebird<C>
>d : bluebird<D>
>e : bluebird<E>
>filter : (callbackfn: (value: bluebird<A>, index: number, array: bluebird<A>[]) => any, thisArg?: any) => bluebird<A>[]
>el => !!el : (el: bluebird<A>) => boolean
>el : bluebird<A>
>!!el : boolean
>!el : boolean
>el : bluebird<A>
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
><T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => f.apply(this, result) : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
>T : T
>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T
>a : A
>A : A
>b : B
>B : B
>c : C
>C : C
>d : D
>D : D
>e : E
>E : E
>T : T
>T : T
f.apply(this, result);
>f.apply(this, result) : T
>f.apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T
>apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
>this : any
>result : any
let rfunc: typeof func & {} = func as any; // <- This is the only difference
>rfunc : (<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
>func as any : any
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
return rfunc
>rfunc : (<T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T) & {}
}
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)>
>A : A
>B : B
>C : C
>D : D
>E : E
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
>a : bluebird<A>
>bluebird : bluebird<T>
>A : A
>b : bluebird<B>
>bluebird : bluebird<T>
>B : B
>c : bluebird<C>
>bluebird : bluebird<T>
>C : C
>d : bluebird<D>
>bluebird : bluebird<T>
>D : D
>e : bluebird<E>
>bluebird : bluebird<T>
>E : E
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
>result : any
>await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any
>(bluebird.all as any)([a, b, c, d, e].filter(el => !!el)) : any
>(bluebird.all as any) : any
>bluebird.all as any : any
>bluebird.all : bluebird<any>[]
>bluebird : typeof bluebird
>all : bluebird<any>[]
>[a, b, c, d, e].filter(el => !!el) : bluebird<A>[]
>[a, b, c, d, e].filter : (callbackfn: (value: bluebird<A>, index: number, array: bluebird<A>[]) => any, thisArg?: any) => bluebird<A>[]
>[a, b, c, d, e] : bluebird<A>[]
>a : bluebird<A>
>b : bluebird<B>
>c : bluebird<C>
>d : bluebird<D>
>e : bluebird<E>
>filter : (callbackfn: (value: bluebird<A>, index: number, array: bluebird<A>[]) => any, thisArg?: any) => bluebird<A>[]
>el => !!el : (el: bluebird<A>) => boolean
>el : bluebird<A>
>!!el : boolean
>!el : boolean
>el : bluebird<A>
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
><T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T => f.apply(this, result) : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
>T : T
>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T
>a : A
>A : A
>b : B
>B : B
>c : C
>C : C
>d : D
>D : D
>e : E
>E : E
>T : T
>T : T
f.apply(this, result);
>f.apply(this, result) : T
>f.apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
>f : (a: A, b?: B, c?: C, d?: D, e?: E) => T
>apply : { <T, U>(this: (this: T, ...argArray: any[]) => U, thisArg: T, argArray?: any): U; (this: Function, thisArg: any, argArray?: any): any; }
>this : any
>result : any
let rfunc: typeof func = func as any; // <- This is the only difference
>rfunc : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
>func as any : any
>func : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
return rfunc
>rfunc : <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T) => T
}

View File

@ -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

View File

@ -0,0 +1,26 @@
// @declaration: true
// @module: commonjs
// @target: es6
class X<A> {
}
var prop11: X< <Tany>() => Tany >; // spaces before the first type argument
var prop12: X<(<Tany>() => Tany)>; // spaces before the first type argument
function f1() { // Inferred return type
return prop11;
}
function f2() { // Inferred return type
return prop12;
}
function f3(): X< <Tany>() => Tany> { // written with space before type argument
return prop11;
}
function f4(): X<(<Tany>() => Tany)> { // written type with parenthesis
return prop12;
}
class Y<A, B> {
}
var prop2: Y<string[], <Tany>() => Tany>; // No space after second type argument
var prop2: Y<string[], <Tany>() => Tany>; // space after second type argument
var prop3: Y< <Tany>() => Tany, <Tany>() => Tany>; // space before first type argument
var prop4: Y<(<Tany>() => Tany), <Tany>() => Tany>; // parenthesized first type argument

View File

@ -0,0 +1,25 @@
// @declaration: true
// @module: commonjs
// @target: es6
export class bluebird<T> {
static all: Array<bluebird<any>>;
}
export async function runSampleWorks<A, B, C, D, E>(
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
f.apply(this, result);
let rfunc: typeof func & {} = func as any; // <- This is the only difference
return rfunc
}
export async function runSampleBreaks<A, B, C, D, E>(
a: bluebird<A>, b?: bluebird<B>, c?: bluebird<C>, d?: bluebird<D>, e?: bluebird<E>) {
let result = await (bluebird.all as any)([a, b, c, d, e].filter(el => !!el));
let func = <T>(f: (a: A, b?: B, c?: C, d?: D, e?: E) => T): T =>
f.apply(this, result);
let rfunc: typeof func = func as any; // <- This is the only difference
return rfunc
}