Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2199,15 +2199,32 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
else if (!(flags & TypeFormatFlags.InTypeAlias) &&
(getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target || type.flags & TypeFlags.UnionOrIntersection) &&
type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
// We emit inferred type as type-alias at the current localtion if all the following is true
// the input type is has alias symbol that is accessible
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
// e.g.: export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
// We emit inferred type as type-alias if type is not in type-alias declaration, existed accessible alias-symbol, type is anonymous or union or intersection.
// However, if the type is an anonymous type with type arguments, we need to perform additional check.
// 1) No type arguments, just emit type-alias as is
// 2) Existed type arguments, check if the type arguments full fill all type parameters of the alias-symbol by
// checking whether the target's aliasTypeArguments has the same size as type's aliasTypeArguments:
// i.e
// type Foo<T> = {
// foo<U>(): Foo<U>
// };
// function foo() {
// return {} as Foo<number>;
// }
// Should be emitted as
// declare type Foo<T> = {
// foo<U>(): Foo<U>;
// };
// declare function foo(): Foo<number>;
// Otherwise type-alias is point to another generic type-alias then don't write it using alias symbol
// export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // this should be emit as "export declare const y: (x: () => [any, string]) => number;"
const typeArguments = (<AnonymousType>type).aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
Expand DownExpand Up@@ -2330,7 +2347,9 @@ namespace ts {
else if (contains(symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// We only want to use type-alias here if the typeAlias is not a generic one. (i.e it doesn't have a target type)
// If it is a generic type-alias just write out "any"
if (typeAlias && !(<AnonymousType>type).target) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters2.ts]

export type Bar<X, Y, Z> = () => [X, Y, Z];
export type Baz<M, N> = Bar<M, string, N>;
export type Baa<Y> = Baz<boolean, Y>;
export const y = (x: Baa<number>) => 1

//// [declarationEmitTypeAliasWithTypeParameters2.js]
"use strict";
exports.y = function (x) { return 1; };


//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
export declare type Baz<M, N> = Bar<M, string, N>;
export declare type Baa<Y> = Baz<boolean, Y>;
export declare const y: (x: () => [boolean, string, number]) => number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))

export type Baz<M, N> = Bar<M, string, N>;
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))

export type Baa<Y> = Baz<boolean, Y>;
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))

export const y = (x: Baa<number>) => 1
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Bar<X, Y, Z>
>X : X
>Y : Y
>Z : Z
>X : X
>Y : Y
>Z : Z

export type Baz<M, N> = Bar<M, string, N>;
>Baz : () => [M, string, N]
>M : M
>N : N
>Bar : Bar<X, Y, Z>
>M : M
>N : N

export type Baa<Y> = Baz<boolean, Y>;
>Baa : () => [boolean, string, Y]
>Y : Y
>Baz : () => [M, string, N]
>Y : Y

export const y = (x: Baa<number>) => 1
>y : (x: () => [boolean, string, number]) => number
>(x: Baa<number>) => 1 : (x: () => [boolean, string, number]) => number
>x : () => [boolean, string, number]
>Baa : () => [boolean, string, Y]
>1 : 1

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
//// [declarationEmitTypeAliasWithTypeParameters3.ts]

type Foo<T> = {
foo<U>(): Foo<U>
};
function bar() {
return {} as Foo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters3.js]
function bar() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
declare type Foo<T> = {
foo<U>(): Foo<U>;
};
declare function bar(): {
foo<U>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))

foo<U>(): Foo<U>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))

};
function bar() {
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))

return {} as Foo<number>;
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Foo<T>
>T : T

foo<U>(): Foo<U>
>foo : <U>() => { foo<U>(): any; }
>U : U
>Foo : Foo<T>
>U : U

};
function bar() {
>bar : () => { foo<U>(): any; }

return {} as Foo<number>;
>{} as Foo<number> : { foo<U>(): any; }
>{} : {}
>Foo : Foo<T>
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters4.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters4.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R> = Foo<string, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))

return {} as SubFoo<number>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Foo<T, Y>
>T : T
>Y : Y

foo<U, J>(): Foo<U, J>
>foo : <U, J>() => { foo<U, J>(): any; }
>U : U
>J : J
>Foo : Foo<T, Y>
>U : U
>J : J

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : { foo<U, J>(): any; }
>R : R
>Foo : Foo<T, Y>
>R : R

function foo() {
>foo : () => { foo<U, J>(): any; }

return {} as SubFoo<number>;
>{} as SubFoo<number> : { foo<U, J>(): any; }
>{} : {}
>SubFoo : { foo<U, J>(): any; }
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.


==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;
~~~
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.

function foo() {
return {} as SubFoo<number>;
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters5.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters5.js]
"use strict";
function foo() {
return {};
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters6.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R, S> = Foo<S, R>;

function foo() {
return {} as SubFoo<number, string>;
}


//// [declarationEmitTypeAliasWithTypeParameters6.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R, S> = Foo<S, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))

};
type SubFoo<R, S> = Foo<S, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))

return {} as SubFoo<number, string>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
}

Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2199,15 +2199,32 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
else if (!(flags & TypeFormatFlags.InTypeAlias) &&
(getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target || type.flags & TypeFlags.UnionOrIntersection) &&
type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
// We emit inferred type as type-alias at the current localtion if all the following is true
// the input type is has alias symbol that is accessible
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
// e.g.: export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
// We emit inferred type as type-alias if type is not in type-alias declaration, existed accessible alias-symbol, type is anonymous or union or intersection.
// However, if the type is an anonymous type with type arguments, we need to perform additional check.
// 1) No type arguments, just emit type-alias as is
// 2) Existed type arguments, check if the type arguments full fill all type parameters of the alias-symbol by
// checking whether the target's aliasTypeArguments has the same size as type's aliasTypeArguments:
// i.e
// type Foo<T> = {
// foo<U>(): Foo<U>
// };
// function foo() {
// return {} as Foo<number>;
// }
// Should be emitted as
// declare type Foo<T> = {
// foo<U>(): Foo<U>;
// };
// declare function foo(): Foo<number>;
// Otherwise type-alias is point to another generic type-alias then don't write it using alias symbol
// export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // this should be emit as "export declare const y: (x: () => [any, string]) => number;"
const typeArguments = (<AnonymousType>type).aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
Expand DownExpand Up@@ -2330,7 +2347,9 @@ namespace ts {
else if (contains(symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// We only want to use type-alias here if the typeAlias is not a generic one. (i.e it doesn't have a target type)
// If it is a generic type-alias just write out "any"
if (typeAlias && !(<AnonymousType>type).target) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters2.ts]

export type Bar<X, Y, Z> = () => [X, Y, Z];
export type Baz<M, N> = Bar<M, string, N>;
export type Baa<Y> = Baz<boolean, Y>;
export const y = (x: Baa<number>) => 1

//// [declarationEmitTypeAliasWithTypeParameters2.js]
"use strict";
exports.y = function (x) { return 1; };


//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
export declare type Baz<M, N> = Bar<M, string, N>;
export declare type Baa<Y> = Baz<boolean, Y>;
export declare const y: (x: () => [boolean, string, number]) => number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))

export type Baz<M, N> = Bar<M, string, N>;
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))

export type Baa<Y> = Baz<boolean, Y>;
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))

export const y = (x: Baa<number>) => 1
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Bar<X, Y, Z>
>X : X
>Y : Y
>Z : Z
>X : X
>Y : Y
>Z : Z

export type Baz<M, N> = Bar<M, string, N>;
>Baz : () => [M, string, N]
>M : M
>N : N
>Bar : Bar<X, Y, Z>
>M : M
>N : N

export type Baa<Y> = Baz<boolean, Y>;
>Baa : () => [boolean, string, Y]
>Y : Y
>Baz : () => [M, string, N]
>Y : Y

export const y = (x: Baa<number>) => 1
>y : (x: () => [boolean, string, number]) => number
>(x: Baa<number>) => 1 : (x: () => [boolean, string, number]) => number
>x : () => [boolean, string, number]
>Baa : () => [boolean, string, Y]
>1 : 1

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
//// [declarationEmitTypeAliasWithTypeParameters3.ts]

type Foo<T> = {
foo<U>(): Foo<U>
};
function bar() {
return {} as Foo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters3.js]
function bar() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
declare type Foo<T> = {
foo<U>(): Foo<U>;
};
declare function bar(): {
foo<U>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))

foo<U>(): Foo<U>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))

};
function bar() {
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))

return {} as Foo<number>;
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Foo<T>
>T : T

foo<U>(): Foo<U>
>foo : <U>() => { foo<U>(): any; }
>U : U
>Foo : Foo<T>
>U : U

};
function bar() {
>bar : () => { foo<U>(): any; }

return {} as Foo<number>;
>{} as Foo<number> : { foo<U>(): any; }
>{} : {}
>Foo : Foo<T>
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters4.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters4.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R> = Foo<string, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))

return {} as SubFoo<number>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Foo<T, Y>
>T : T
>Y : Y

foo<U, J>(): Foo<U, J>
>foo : <U, J>() => { foo<U, J>(): any; }
>U : U
>J : J
>Foo : Foo<T, Y>
>U : U
>J : J

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : { foo<U, J>(): any; }
>R : R
>Foo : Foo<T, Y>
>R : R

function foo() {
>foo : () => { foo<U, J>(): any; }

return {} as SubFoo<number>;
>{} as SubFoo<number> : { foo<U, J>(): any; }
>{} : {}
>SubFoo : { foo<U, J>(): any; }
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.


==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;
~~~
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.

function foo() {
return {} as SubFoo<number>;
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters5.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters5.js]
"use strict";
function foo() {
return {};
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters6.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R, S> = Foo<S, R>;

function foo() {
return {} as SubFoo<number, string>;
}


//// [declarationEmitTypeAliasWithTypeParameters6.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R, S> = Foo<S, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))

};
type SubFoo<R, S> = Foo<S, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))

return {} as SubFoo<number, string>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
}

Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2199,15 +2199,32 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
else if (!(flags & TypeFormatFlags.InTypeAlias) &&
(getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target || type.flags & TypeFlags.UnionOrIntersection) &&
type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
// We emit inferred type as type-alias at the current localtion if all the following is true
// the input type is has alias symbol that is accessible
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
// e.g.: export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
// We emit inferred type as type-alias if type is not in type-alias declaration, existed accessible alias-symbol, type is anonymous or union or intersection.
// However, if the type is an anonymous type with type arguments, we need to perform additional check.
// 1) No type arguments, just emit type-alias as is
// 2) Existed type arguments, check if the type arguments full fill all type parameters of the alias-symbol by
// checking whether the target's aliasTypeArguments has the same size as type's aliasTypeArguments:
// i.e
// type Foo<T> = {
// foo<U>(): Foo<U>
// };
// function foo() {
// return {} as Foo<number>;
// }
// Should be emitted as
// declare type Foo<T> = {
// foo<U>(): Foo<U>;
// };
// declare function foo(): Foo<number>;
// Otherwise type-alias is point to another generic type-alias then don't write it using alias symbol
// export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // this should be emit as "export declare const y: (x: () => [any, string]) => number;"
const typeArguments = (<AnonymousType>type).aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
Expand DownExpand Up@@ -2330,7 +2347,9 @@ namespace ts {
else if (contains(symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// We only want to use type-alias here if the typeAlias is not a generic one. (i.e it doesn't have a target type)
// If it is a generic type-alias just write out "any"
if (typeAlias && !(<AnonymousType>type).target) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters2.ts]

export type Bar<X, Y, Z> = () => [X, Y, Z];
export type Baz<M, N> = Bar<M, string, N>;
export type Baa<Y> = Baz<boolean, Y>;
export const y = (x: Baa<number>) => 1

//// [declarationEmitTypeAliasWithTypeParameters2.js]
"use strict";
exports.y = function (x) { return 1; };


//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
export declare type Baz<M, N> = Bar<M, string, N>;
export declare type Baa<Y> = Baz<boolean, Y>;
export declare const y: (x: () => [boolean, string, number]) => number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))

export type Baz<M, N> = Bar<M, string, N>;
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))

export type Baa<Y> = Baz<boolean, Y>;
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))

export const y = (x: Baa<number>) => 1
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Bar<X, Y, Z>
>X : X
>Y : Y
>Z : Z
>X : X
>Y : Y
>Z : Z

export type Baz<M, N> = Bar<M, string, N>;
>Baz : () => [M, string, N]
>M : M
>N : N
>Bar : Bar<X, Y, Z>
>M : M
>N : N

export type Baa<Y> = Baz<boolean, Y>;
>Baa : () => [boolean, string, Y]
>Y : Y
>Baz : () => [M, string, N]
>Y : Y

export const y = (x: Baa<number>) => 1
>y : (x: () => [boolean, string, number]) => number
>(x: Baa<number>) => 1 : (x: () => [boolean, string, number]) => number
>x : () => [boolean, string, number]
>Baa : () => [boolean, string, Y]
>1 : 1

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
//// [declarationEmitTypeAliasWithTypeParameters3.ts]

type Foo<T> = {
foo<U>(): Foo<U>
};
function bar() {
return {} as Foo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters3.js]
function bar() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
declare type Foo<T> = {
foo<U>(): Foo<U>;
};
declare function bar(): {
foo<U>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))

foo<U>(): Foo<U>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))

};
function bar() {
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))

return {} as Foo<number>;
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Foo<T>
>T : T

foo<U>(): Foo<U>
>foo : <U>() => { foo<U>(): any; }
>U : U
>Foo : Foo<T>
>U : U

};
function bar() {
>bar : () => { foo<U>(): any; }

return {} as Foo<number>;
>{} as Foo<number> : { foo<U>(): any; }
>{} : {}
>Foo : Foo<T>
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters4.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters4.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R> = Foo<string, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))

return {} as SubFoo<number>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Foo<T, Y>
>T : T
>Y : Y

foo<U, J>(): Foo<U, J>
>foo : <U, J>() => { foo<U, J>(): any; }
>U : U
>J : J
>Foo : Foo<T, Y>
>U : U
>J : J

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : { foo<U, J>(): any; }
>R : R
>Foo : Foo<T, Y>
>R : R

function foo() {
>foo : () => { foo<U, J>(): any; }

return {} as SubFoo<number>;
>{} as SubFoo<number> : { foo<U, J>(): any; }
>{} : {}
>SubFoo : { foo<U, J>(): any; }
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.


==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;
~~~
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.

function foo() {
return {} as SubFoo<number>;
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters5.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters5.js]
"use strict";
function foo() {
return {};
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters6.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R, S> = Foo<S, R>;

function foo() {
return {} as SubFoo<number, string>;
}


//// [declarationEmitTypeAliasWithTypeParameters6.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R, S> = Foo<S, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))

};
type SubFoo<R, S> = Foo<S, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))

return {} as SubFoo<number, string>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
}

Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2199,15 +2199,32 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
else if (!(flags & TypeFormatFlags.InTypeAlias) &&
(getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target || type.flags & TypeFlags.UnionOrIntersection) &&
type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
// We emit inferred type as type-alias at the current localtion if all the following is true
// the input type is has alias symbol that is accessible
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
// e.g.: export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
// We emit inferred type as type-alias if type is not in type-alias declaration, existed accessible alias-symbol, type is anonymous or union or intersection.
// However, if the type is an anonymous type with type arguments, we need to perform additional check.
// 1) No type arguments, just emit type-alias as is
// 2) Existed type arguments, check if the type arguments full fill all type parameters of the alias-symbol by
// checking whether the target's aliasTypeArguments has the same size as type's aliasTypeArguments:
// i.e
// type Foo<T> = {
// foo<U>(): Foo<U>
// };
// function foo() {
// return {} as Foo<number>;
// }
// Should be emitted as
// declare type Foo<T> = {
// foo<U>(): Foo<U>;
// };
// declare function foo(): Foo<number>;
// Otherwise type-alias is point to another generic type-alias then don't write it using alias symbol
// export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // this should be emit as "export declare const y: (x: () => [any, string]) => number;"
const typeArguments = (<AnonymousType>type).aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
Expand DownExpand Up@@ -2330,7 +2347,9 @@ namespace ts {
else if (contains(symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// We only want to use type-alias here if the typeAlias is not a generic one. (i.e it doesn't have a target type)
// If it is a generic type-alias just write out "any"
if (typeAlias && !(<AnonymousType>type).target) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters2.ts]

export type Bar<X, Y, Z> = () => [X, Y, Z];
export type Baz<M, N> = Bar<M, string, N>;
export type Baa<Y> = Baz<boolean, Y>;
export const y = (x: Baa<number>) => 1

//// [declarationEmitTypeAliasWithTypeParameters2.js]
"use strict";
exports.y = function (x) { return 1; };


//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
export declare type Baz<M, N> = Bar<M, string, N>;
export declare type Baa<Y> = Baz<boolean, Y>;
export declare const y: (x: () => [boolean, string, number]) => number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))

export type Baz<M, N> = Bar<M, string, N>;
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))

export type Baa<Y> = Baz<boolean, Y>;
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))

export const y = (x: Baa<number>) => 1
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Bar<X, Y, Z>
>X : X
>Y : Y
>Z : Z
>X : X
>Y : Y
>Z : Z

export type Baz<M, N> = Bar<M, string, N>;
>Baz : () => [M, string, N]
>M : M
>N : N
>Bar : Bar<X, Y, Z>
>M : M
>N : N

export type Baa<Y> = Baz<boolean, Y>;
>Baa : () => [boolean, string, Y]
>Y : Y
>Baz : () => [M, string, N]
>Y : Y

export const y = (x: Baa<number>) => 1
>y : (x: () => [boolean, string, number]) => number
>(x: Baa<number>) => 1 : (x: () => [boolean, string, number]) => number
>x : () => [boolean, string, number]
>Baa : () => [boolean, string, Y]
>1 : 1

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
//// [declarationEmitTypeAliasWithTypeParameters3.ts]

type Foo<T> = {
foo<U>(): Foo<U>
};
function bar() {
return {} as Foo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters3.js]
function bar() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
declare type Foo<T> = {
foo<U>(): Foo<U>;
};
declare function bar(): {
foo<U>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))

foo<U>(): Foo<U>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))

};
function bar() {
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))

return {} as Foo<number>;
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Foo<T>
>T : T

foo<U>(): Foo<U>
>foo : <U>() => { foo<U>(): any; }
>U : U
>Foo : Foo<T>
>U : U

};
function bar() {
>bar : () => { foo<U>(): any; }

return {} as Foo<number>;
>{} as Foo<number> : { foo<U>(): any; }
>{} : {}
>Foo : Foo<T>
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters4.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters4.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R> = Foo<string, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))

return {} as SubFoo<number>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Foo<T, Y>
>T : T
>Y : Y

foo<U, J>(): Foo<U, J>
>foo : <U, J>() => { foo<U, J>(): any; }
>U : U
>J : J
>Foo : Foo<T, Y>
>U : U
>J : J

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : { foo<U, J>(): any; }
>R : R
>Foo : Foo<T, Y>
>R : R

function foo() {
>foo : () => { foo<U, J>(): any; }

return {} as SubFoo<number>;
>{} as SubFoo<number> : { foo<U, J>(): any; }
>{} : {}
>SubFoo : { foo<U, J>(): any; }
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.


==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;
~~~
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.

function foo() {
return {} as SubFoo<number>;
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters5.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters5.js]
"use strict";
function foo() {
return {};
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters6.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R, S> = Foo<S, R>;

function foo() {
return {} as SubFoo<number, string>;
}


//// [declarationEmitTypeAliasWithTypeParameters6.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R, S> = Foo<S, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))

};
type SubFoo<R, S> = Foo<S, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))

return {} as SubFoo<number, string>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
}

Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2199,15 +2199,32 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
else if (!(flags & TypeFormatFlags.InTypeAlias) &&
(getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target || type.flags & TypeFlags.UnionOrIntersection) &&
type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
// We emit inferred type as type-alias at the current localtion if all the following is true
// the input type is has alias symbol that is accessible
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
// e.g.: export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
// We emit inferred type as type-alias if type is not in type-alias declaration, existed accessible alias-symbol, type is anonymous or union or intersection.
// However, if the type is an anonymous type with type arguments, we need to perform additional check.
// 1) No type arguments, just emit type-alias as is
// 2) Existed type arguments, check if the type arguments full fill all type parameters of the alias-symbol by
// checking whether the target's aliasTypeArguments has the same size as type's aliasTypeArguments:
// i.e
// type Foo<T> = {
// foo<U>(): Foo<U>
// };
// function foo() {
// return {} as Foo<number>;
// }
// Should be emitted as
// declare type Foo<T> = {
// foo<U>(): Foo<U>;
// };
// declare function foo(): Foo<number>;
// Otherwise type-alias is point to another generic type-alias then don't write it using alias symbol
// export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // this should be emit as "export declare const y: (x: () => [any, string]) => number;"
const typeArguments = (<AnonymousType>type).aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
Expand DownExpand Up@@ -2330,7 +2347,9 @@ namespace ts {
else if (contains(symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// We only want to use type-alias here if the typeAlias is not a generic one. (i.e it doesn't have a target type)
// If it is a generic type-alias just write out "any"
if (typeAlias && !(<AnonymousType>type).target) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters2.ts]

export type Bar<X, Y, Z> = () => [X, Y, Z];
export type Baz<M, N> = Bar<M, string, N>;
export type Baa<Y> = Baz<boolean, Y>;
export const y = (x: Baa<number>) => 1

//// [declarationEmitTypeAliasWithTypeParameters2.js]
"use strict";
exports.y = function (x) { return 1; };


//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
export declare type Baz<M, N> = Bar<M, string, N>;
export declare type Baa<Y> = Baz<boolean, Y>;
export declare const y: (x: () => [boolean, string, number]) => number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))

export type Baz<M, N> = Bar<M, string, N>;
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))

export type Baa<Y> = Baz<boolean, Y>;
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))

export const y = (x: Baa<number>) => 1
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Bar<X, Y, Z>
>X : X
>Y : Y
>Z : Z
>X : X
>Y : Y
>Z : Z

export type Baz<M, N> = Bar<M, string, N>;
>Baz : () => [M, string, N]
>M : M
>N : N
>Bar : Bar<X, Y, Z>
>M : M
>N : N

export type Baa<Y> = Baz<boolean, Y>;
>Baa : () => [boolean, string, Y]
>Y : Y
>Baz : () => [M, string, N]
>Y : Y

export const y = (x: Baa<number>) => 1
>y : (x: () => [boolean, string, number]) => number
>(x: Baa<number>) => 1 : (x: () => [boolean, string, number]) => number
>x : () => [boolean, string, number]
>Baa : () => [boolean, string, Y]
>1 : 1

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
//// [declarationEmitTypeAliasWithTypeParameters3.ts]

type Foo<T> = {
foo<U>(): Foo<U>
};
function bar() {
return {} as Foo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters3.js]
function bar() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
declare type Foo<T> = {
foo<U>(): Foo<U>;
};
declare function bar(): {
foo<U>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))

foo<U>(): Foo<U>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))

};
function bar() {
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))

return {} as Foo<number>;
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Foo<T>
>T : T

foo<U>(): Foo<U>
>foo : <U>() => { foo<U>(): any; }
>U : U
>Foo : Foo<T>
>U : U

};
function bar() {
>bar : () => { foo<U>(): any; }

return {} as Foo<number>;
>{} as Foo<number> : { foo<U>(): any; }
>{} : {}
>Foo : Foo<T>
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters4.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters4.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R> = Foo<string, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))

return {} as SubFoo<number>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Foo<T, Y>
>T : T
>Y : Y

foo<U, J>(): Foo<U, J>
>foo : <U, J>() => { foo<U, J>(): any; }
>U : U
>J : J
>Foo : Foo<T, Y>
>U : U
>J : J

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : { foo<U, J>(): any; }
>R : R
>Foo : Foo<T, Y>
>R : R

function foo() {
>foo : () => { foo<U, J>(): any; }

return {} as SubFoo<number>;
>{} as SubFoo<number> : { foo<U, J>(): any; }
>{} : {}
>SubFoo : { foo<U, J>(): any; }
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.


==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;
~~~
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.

function foo() {
return {} as SubFoo<number>;
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters5.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters5.js]
"use strict";
function foo() {
return {};
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters6.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R, S> = Foo<S, R>;

function foo() {
return {} as SubFoo<number, string>;
}


//// [declarationEmitTypeAliasWithTypeParameters6.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R, S> = Foo<S, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))

};
type SubFoo<R, S> = Foo<S, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))

return {} as SubFoo<number, string>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
}

Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2199,15 +2199,32 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
else if (!(flags & TypeFormatFlags.InTypeAlias) &&
(getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target || type.flags & TypeFlags.UnionOrIntersection) &&
type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
// We emit inferred type as type-alias at the current localtion if all the following is true
// the input type is has alias symbol that is accessible
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
// e.g.: export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
// We emit inferred type as type-alias if type is not in type-alias declaration, existed accessible alias-symbol, type is anonymous or union or intersection.
// However, if the type is an anonymous type with type arguments, we need to perform additional check.
// 1) No type arguments, just emit type-alias as is
// 2) Existed type arguments, check if the type arguments full fill all type parameters of the alias-symbol by
// checking whether the target's aliasTypeArguments has the same size as type's aliasTypeArguments:
// i.e
// type Foo<T> = {
// foo<U>(): Foo<U>
// };
// function foo() {
// return {} as Foo<number>;
// }
// Should be emitted as
// declare type Foo<T> = {
// foo<U>(): Foo<U>;
// };
// declare function foo(): Foo<number>;
// Otherwise type-alias is point to another generic type-alias then don't write it using alias symbol
// export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // this should be emit as "export declare const y: (x: () => [any, string]) => number;"
const typeArguments = (<AnonymousType>type).aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
Expand DownExpand Up@@ -2330,7 +2347,9 @@ namespace ts {
else if (contains(symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// We only want to use type-alias here if the typeAlias is not a generic one. (i.e it doesn't have a target type)
// If it is a generic type-alias just write out "any"
if (typeAlias && !(<AnonymousType>type).target) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters2.ts]

export type Bar<X, Y, Z> = () => [X, Y, Z];
export type Baz<M, N> = Bar<M, string, N>;
export type Baa<Y> = Baz<boolean, Y>;
export const y = (x: Baa<number>) => 1

//// [declarationEmitTypeAliasWithTypeParameters2.js]
"use strict";
exports.y = function (x) { return 1; };


//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
export declare type Baz<M, N> = Bar<M, string, N>;
export declare type Baa<Y> = Baz<boolean, Y>;
export declare const y: (x: () => [boolean, string, number]) => number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))

export type Baz<M, N> = Bar<M, string, N>;
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))

export type Baa<Y> = Baz<boolean, Y>;
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))

export const y = (x: Baa<number>) => 1
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Bar<X, Y, Z>
>X : X
>Y : Y
>Z : Z
>X : X
>Y : Y
>Z : Z

export type Baz<M, N> = Bar<M, string, N>;
>Baz : () => [M, string, N]
>M : M
>N : N
>Bar : Bar<X, Y, Z>
>M : M
>N : N

export type Baa<Y> = Baz<boolean, Y>;
>Baa : () => [boolean, string, Y]
>Y : Y
>Baz : () => [M, string, N]
>Y : Y

export const y = (x: Baa<number>) => 1
>y : (x: () => [boolean, string, number]) => number
>(x: Baa<number>) => 1 : (x: () => [boolean, string, number]) => number
>x : () => [boolean, string, number]
>Baa : () => [boolean, string, Y]
>1 : 1

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
//// [declarationEmitTypeAliasWithTypeParameters3.ts]

type Foo<T> = {
foo<U>(): Foo<U>
};
function bar() {
return {} as Foo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters3.js]
function bar() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
declare type Foo<T> = {
foo<U>(): Foo<U>;
};
declare function bar(): {
foo<U>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))

foo<U>(): Foo<U>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))

};
function bar() {
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))

return {} as Foo<number>;
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Foo<T>
>T : T

foo<U>(): Foo<U>
>foo : <U>() => { foo<U>(): any; }
>U : U
>Foo : Foo<T>
>U : U

};
function bar() {
>bar : () => { foo<U>(): any; }

return {} as Foo<number>;
>{} as Foo<number> : { foo<U>(): any; }
>{} : {}
>Foo : Foo<T>
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters4.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters4.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R> = Foo<string, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))

return {} as SubFoo<number>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Foo<T, Y>
>T : T
>Y : Y

foo<U, J>(): Foo<U, J>
>foo : <U, J>() => { foo<U, J>(): any; }
>U : U
>J : J
>Foo : Foo<T, Y>
>U : U
>J : J

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : { foo<U, J>(): any; }
>R : R
>Foo : Foo<T, Y>
>R : R

function foo() {
>foo : () => { foo<U, J>(): any; }

return {} as SubFoo<number>;
>{} as SubFoo<number> : { foo<U, J>(): any; }
>{} : {}
>SubFoo : { foo<U, J>(): any; }
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.


==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;
~~~
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.

function foo() {
return {} as SubFoo<number>;
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters5.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters5.js]
"use strict";
function foo() {
return {};
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters6.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R, S> = Foo<S, R>;

function foo() {
return {} as SubFoo<number, string>;
}


//// [declarationEmitTypeAliasWithTypeParameters6.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R, S> = Foo<S, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))

};
type SubFoo<R, S> = Foo<S, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))

return {} as SubFoo<number, string>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
}

Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2199,15 +2199,32 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
else if (!(flags & TypeFormatFlags.InTypeAlias) &&
(getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target || type.flags & TypeFlags.UnionOrIntersection) &&
type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
// We emit inferred type as type-alias at the current localtion if all the following is true
// the input type is has alias symbol that is accessible
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
// e.g.: export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
// We emit inferred type as type-alias if type is not in type-alias declaration, existed accessible alias-symbol, type is anonymous or union or intersection.
// However, if the type is an anonymous type with type arguments, we need to perform additional check.
// 1) No type arguments, just emit type-alias as is
// 2) Existed type arguments, check if the type arguments full fill all type parameters of the alias-symbol by
// checking whether the target's aliasTypeArguments has the same size as type's aliasTypeArguments:
// i.e
// type Foo<T> = {
// foo<U>(): Foo<U>
// };
// function foo() {
// return {} as Foo<number>;
// }
// Should be emitted as
// declare type Foo<T> = {
// foo<U>(): Foo<U>;
// };
// declare function foo(): Foo<number>;
// Otherwise type-alias is point to another generic type-alias then don't write it using alias symbol
// export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // this should be emit as "export declare const y: (x: () => [any, string]) => number;"
const typeArguments = (<AnonymousType>type).aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
Expand DownExpand Up@@ -2330,7 +2347,9 @@ namespace ts {
else if (contains(symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// We only want to use type-alias here if the typeAlias is not a generic one. (i.e it doesn't have a target type)
// If it is a generic type-alias just write out "any"
if (typeAlias && !(<AnonymousType>type).target) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters2.ts]

export type Bar<X, Y, Z> = () => [X, Y, Z];
export type Baz<M, N> = Bar<M, string, N>;
export type Baa<Y> = Baz<boolean, Y>;
export const y = (x: Baa<number>) => 1

//// [declarationEmitTypeAliasWithTypeParameters2.js]
"use strict";
exports.y = function (x) { return 1; };


//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
export declare type Baz<M, N> = Bar<M, string, N>;
export declare type Baa<Y> = Baz<boolean, Y>;
export declare const y: (x: () => [boolean, string, number]) => number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))

export type Baz<M, N> = Bar<M, string, N>;
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))

export type Baa<Y> = Baz<boolean, Y>;
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))

export const y = (x: Baa<number>) => 1
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Bar<X, Y, Z>
>X : X
>Y : Y
>Z : Z
>X : X
>Y : Y
>Z : Z

export type Baz<M, N> = Bar<M, string, N>;
>Baz : () => [M, string, N]
>M : M
>N : N
>Bar : Bar<X, Y, Z>
>M : M
>N : N

export type Baa<Y> = Baz<boolean, Y>;
>Baa : () => [boolean, string, Y]
>Y : Y
>Baz : () => [M, string, N]
>Y : Y

export const y = (x: Baa<number>) => 1
>y : (x: () => [boolean, string, number]) => number
>(x: Baa<number>) => 1 : (x: () => [boolean, string, number]) => number
>x : () => [boolean, string, number]
>Baa : () => [boolean, string, Y]
>1 : 1

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
//// [declarationEmitTypeAliasWithTypeParameters3.ts]

type Foo<T> = {
foo<U>(): Foo<U>
};
function bar() {
return {} as Foo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters3.js]
function bar() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
declare type Foo<T> = {
foo<U>(): Foo<U>;
};
declare function bar(): {
foo<U>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))

foo<U>(): Foo<U>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))

};
function bar() {
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))

return {} as Foo<number>;
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Foo<T>
>T : T

foo<U>(): Foo<U>
>foo : <U>() => { foo<U>(): any; }
>U : U
>Foo : Foo<T>
>U : U

};
function bar() {
>bar : () => { foo<U>(): any; }

return {} as Foo<number>;
>{} as Foo<number> : { foo<U>(): any; }
>{} : {}
>Foo : Foo<T>
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters4.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters4.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R> = Foo<string, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))

return {} as SubFoo<number>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Foo<T, Y>
>T : T
>Y : Y

foo<U, J>(): Foo<U, J>
>foo : <U, J>() => { foo<U, J>(): any; }
>U : U
>J : J
>Foo : Foo<T, Y>
>U : U
>J : J

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : { foo<U, J>(): any; }
>R : R
>Foo : Foo<T, Y>
>R : R

function foo() {
>foo : () => { foo<U, J>(): any; }

return {} as SubFoo<number>;
>{} as SubFoo<number> : { foo<U, J>(): any; }
>{} : {}
>SubFoo : { foo<U, J>(): any; }
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.


==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;
~~~
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.

function foo() {
return {} as SubFoo<number>;
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters5.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters5.js]
"use strict";
function foo() {
return {};
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters6.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R, S> = Foo<S, R>;

function foo() {
return {} as SubFoo<number, string>;
}


//// [declarationEmitTypeAliasWithTypeParameters6.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R, S> = Foo<S, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))

};
type SubFoo<R, S> = Foo<S, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))

return {} as SubFoo<number, string>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
}

Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/compiler/checker.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2199,15 +2199,32 @@ namespace ts {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags);
}
else if (!(flags & TypeFormatFlags.InTypeAlias) && ((getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target) || type.flags & TypeFlags.UnionOrIntersection) && type.aliasSymbol &&
else if (!(flags & TypeFormatFlags.InTypeAlias) &&
(getObjectFlags(type) & ObjectFlags.Anonymous && !(<AnonymousType>type).target || type.flags & TypeFlags.UnionOrIntersection) &&
type.aliasSymbol &&
isSymbolAccessible(type.aliasSymbol, enclosingDeclaration, SymbolFlags.Type, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
// We emit inferred type as type-alias at the current localtion if all the following is true
// the input type is has alias symbol that is accessible
// the input type is a union, intersection or anonymous type that is fully instantiated (if not we want to keep dive into)
// e.g.: export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // we want to emit as ...x: () => [any, string])
const typeArguments = type.aliasTypeArguments;
// We emit inferred type as type-alias if type is not in type-alias declaration, existed accessible alias-symbol, type is anonymous or union or intersection.
// However, if the type is an anonymous type with type arguments, we need to perform additional check.
// 1) No type arguments, just emit type-alias as is
// 2) Existed type arguments, check if the type arguments full fill all type parameters of the alias-symbol by
// checking whether the target's aliasTypeArguments has the same size as type's aliasTypeArguments:
// i.e
// type Foo<T> = {
// foo<U>(): Foo<U>
// };
// function foo() {
// return {} as Foo<number>;
// }
// Should be emitted as
// declare type Foo<T> = {
// foo<U>(): Foo<U>;
// };
// declare function foo(): Foo<number>;
// Otherwise type-alias is point to another generic type-alias then don't write it using alias symbol
// export type Bar<X, Y> = () => [X, Y];
// export type Foo<Y> = Bar<any, Y>;
// export const y = (x: Foo<string>) => 1 // this should be emit as "export declare const y: (x: () => [any, string]) => number;"
const typeArguments = (<AnonymousType>type).aliasTypeArguments;
writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, typeArguments ? typeArguments.length : 0, nextFlags);
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
Expand DownExpand Up@@ -2330,7 +2347,9 @@ namespace ts {
else if (contains(symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
const typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
// We only want to use type-alias here if the typeAlias is not a generic one. (i.e it doesn't have a target type)
// If it is a generic type-alias just write out "any"
if (typeAlias && !(<AnonymousType>type).target) {
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters2.ts]

export type Bar<X, Y, Z> = () => [X, Y, Z];
export type Baz<M, N> = Bar<M, string, N>;
export type Baa<Y> = Baz<boolean, Y>;
export const y = (x: Baa<number>) => 1

//// [declarationEmitTypeAliasWithTypeParameters2.js]
"use strict";
exports.y = function (x) { return 1; };


//// [declarationEmitTypeAliasWithTypeParameters2.d.ts]
export declare type Bar<X, Y, Z> = () => [X, Y, Z];
export declare type Baz<M, N> = Bar<M, string, N>;
export declare type Baa<Y> = Baz<boolean, Y>;
export declare const y: (x: () => [boolean, string, number]) => number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))
>X : Symbol(X, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 16))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 18))
>Z : Symbol(Z, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 21))

export type Baz<M, N> = Bar<M, string, N>;
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))
>Bar : Symbol(Bar, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 0, 0))
>M : Symbol(M, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 16))
>N : Symbol(N, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 18))

export type Baa<Y> = Baz<boolean, Y>;
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))
>Baz : Symbol(Baz, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 1, 43))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 3, 16))

export const y = (x: Baa<number>) => 1
>y : Symbol(y, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 12))
>x : Symbol(x, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 4, 18))
>Baa : Symbol(Baa, Decl(declarationEmitTypeAliasWithTypeParameters2.ts, 2, 42))

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters2.ts ===

export type Bar<X, Y, Z> = () => [X, Y, Z];
>Bar : Bar<X, Y, Z>
>X : X
>Y : Y
>Z : Z
>X : X
>Y : Y
>Z : Z

export type Baz<M, N> = Bar<M, string, N>;
>Baz : () => [M, string, N]
>M : M
>N : N
>Bar : Bar<X, Y, Z>
>M : M
>N : N

export type Baa<Y> = Baz<boolean, Y>;
>Baa : () => [boolean, string, Y]
>Y : Y
>Baz : () => [M, string, N]
>Y : Y

export const y = (x: Baa<number>) => 1
>y : (x: () => [boolean, string, number]) => number
>(x: Baa<number>) => 1 : (x: () => [boolean, string, number]) => number
>x : () => [boolean, string, number]
>Baa : () => [boolean, string, Y]
>1 : 1

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
//// [declarationEmitTypeAliasWithTypeParameters3.ts]

type Foo<T> = {
foo<U>(): Foo<U>
};
function bar() {
return {} as Foo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters3.js]
function bar() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters3.d.ts]
declare type Foo<T> = {
foo<U>(): Foo<U>;
};
declare function bar(): {
foo<U>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 9))

foo<U>(): Foo<U>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 1, 15))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 2, 8))

};
function bar() {
>bar : Symbol(bar, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 3, 2))

return {} as Foo<number>;
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters3.ts, 0, 0))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters3.ts ===

type Foo<T> = {
>Foo : Foo<T>
>T : T

foo<U>(): Foo<U>
>foo : <U>() => { foo<U>(): any; }
>U : U
>Foo : Foo<T>
>U : U

};
function bar() {
>bar : () => { foo<U>(): any; }

return {} as Foo<number>;
>{} as Foo<number> : { foo<U>(): any; }
>{} : {}
>Foo : Foo<T>
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters4.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters4.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters4.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R> = Foo<string, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 2, 10))

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 0, 0))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 4, 32))

return {} as SubFoo<number>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters4.ts, 3, 2))
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters4.ts ===

type Foo<T, Y> = {
>Foo : Foo<T, Y>
>T : T
>Y : Y

foo<U, J>(): Foo<U, J>
>foo : <U, J>() => { foo<U, J>(): any; }
>U : U
>J : J
>Foo : Foo<T, Y>
>U : U
>J : J

};
type SubFoo<R> = Foo<string, R>;
>SubFoo : { foo<U, J>(): any; }
>R : R
>Foo : Foo<T, Y>
>R : R

function foo() {
>foo : () => { foo<U, J>(): any; }

return {} as SubFoo<number>;
>{} as SubFoo<number> : { foo<U, J>(): any; }
>{} : {}
>SubFoo : { foo<U, J>(): any; }
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts(5,25): error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.


==== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters5.ts (1 errors) ====

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;
~~~
!!! error TS4081: Exported type alias 'SubFoo' has or is using private name 'Foo'.

function foo() {
return {} as SubFoo<number>;
}

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
//// [declarationEmitTypeAliasWithTypeParameters5.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
export type SubFoo<R> = Foo<string, R>;

function foo() {
return {} as SubFoo<number>;
}


//// [declarationEmitTypeAliasWithTypeParameters5.js]
"use strict";
function foo() {
return {};
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
//// [declarationEmitTypeAliasWithTypeParameters6.ts]

type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>
};
type SubFoo<R, S> = Foo<S, R>;

function foo() {
return {} as SubFoo<number, string>;
}


//// [declarationEmitTypeAliasWithTypeParameters6.js]
function foo() {
return {};
}


//// [declarationEmitTypeAliasWithTypeParameters6.d.ts]
declare type Foo<T, Y> = {
foo<U, J>(): Foo<U, J>;
};
declare type SubFoo<R, S> = Foo<S, R>;
declare function foo(): {
foo<U, J>(): any;
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
=== tests/cases/compiler/declarationEmitTypeAliasWithTypeParameters6.ts ===

type Foo<T, Y> = {
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>T : Symbol(T, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 9))
>Y : Symbol(Y, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 11))

foo<U, J>(): Foo<U, J>
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 1, 18))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>U : Symbol(U, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 8))
>J : Symbol(J, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 2, 10))

};
type SubFoo<R, S> = Foo<S, R>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>Foo : Symbol(Foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 0, 0))
>S : Symbol(S, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 14))
>R : Symbol(R, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 12))

function foo() {
>foo : Symbol(foo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 4, 30))

return {} as SubFoo<number, string>;
>SubFoo : Symbol(SubFoo, Decl(declarationEmitTypeAliasWithTypeParameters6.ts, 3, 2))
}

Loading