mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 20:37:00 -05:00
Merge pull request #15932 from Microsoft/decl-emit-class-expr-as-type-literal
Declaration-emit class expressions as type literals
This commit is contained in:
@@ -3161,7 +3161,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
const globalFlagsToPass = globalFlags & TypeFormatFlags.WriteOwnNameForAnyLike;
|
||||
const globalFlagsToPass = globalFlags & (TypeFormatFlags.WriteOwnNameForAnyLike | TypeFormatFlags.WriteClassExpressionAsTypeLiteral);
|
||||
let inObjectTypeLiteral = false;
|
||||
return writeType(type, globalFlags);
|
||||
|
||||
@@ -3278,6 +3278,11 @@ namespace ts {
|
||||
writeTypeList(type.typeArguments.slice(0, getTypeReferenceArity(type)), SyntaxKind.CommaToken);
|
||||
writePunctuation(writer, SyntaxKind.CloseBracketToken);
|
||||
}
|
||||
else if (flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral &&
|
||||
type.symbol.valueDeclaration &&
|
||||
type.symbol.valueDeclaration.kind === SyntaxKind.ClassExpression) {
|
||||
writeAnonymousType(getDeclaredTypeOfClassOrInterface(type.symbol), flags);
|
||||
}
|
||||
else {
|
||||
// Write the type reference in the format f<A>.g<B>.C<X, Y> where A and B are type arguments
|
||||
// for outer type parameters, and f and g are the respective declaring containers of those
|
||||
@@ -3325,7 +3330,9 @@ namespace ts {
|
||||
const symbol = type.symbol;
|
||||
if (symbol) {
|
||||
// Always use 'typeof T' for type of class, enum, and module objects
|
||||
if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) ||
|
||||
if (symbol.flags & SymbolFlags.Class &&
|
||||
!getBaseTypeVariableOfClass(symbol) &&
|
||||
!(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && flags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) ||
|
||||
symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule)) {
|
||||
writeTypeOfSymbol(type, flags);
|
||||
}
|
||||
@@ -3347,12 +3354,23 @@ namespace ts {
|
||||
else {
|
||||
// Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
|
||||
// of types allows us to catch circular references to instantiations of the same anonymous type
|
||||
// However, in case of class expressions, we want to write both the static side and the instance side.
|
||||
// We skip adding the static side so that the instance side has a chance to be written
|
||||
// before checking for circular references.
|
||||
if (!symbolStack) {
|
||||
symbolStack = [];
|
||||
}
|
||||
symbolStack.push(symbol);
|
||||
writeLiteralType(type, flags);
|
||||
symbolStack.pop();
|
||||
const isConstructorObject = type.flags & TypeFlags.Object &&
|
||||
getObjectFlags(type) & ObjectFlags.Anonymous &&
|
||||
type.symbol && type.symbol.flags & SymbolFlags.Class;
|
||||
if (isConstructorObject) {
|
||||
writeLiteralType(type, flags);
|
||||
}
|
||||
else {
|
||||
symbolStack.push(symbol);
|
||||
writeLiteralType(type, flags);
|
||||
symbolStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -3471,6 +3489,14 @@ namespace ts {
|
||||
buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack);
|
||||
buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack);
|
||||
for (const p of resolved.properties) {
|
||||
if (globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) {
|
||||
if (p.flags & SymbolFlags.Prototype) {
|
||||
continue;
|
||||
}
|
||||
if (getDeclarationModifierFlagsFromSymbol(p) & (ModifierFlags.Private | ModifierFlags.Protected)) {
|
||||
writer.reportPrivateInBaseOfClassExpression(p.name);
|
||||
}
|
||||
}
|
||||
const t = getTypeOfSymbol(p);
|
||||
if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) {
|
||||
const signatures = getSignaturesOfType(t, SignatureKind.Call);
|
||||
@@ -3485,7 +3511,7 @@ namespace ts {
|
||||
writePropertyWithModifiers(p);
|
||||
writePunctuation(writer, SyntaxKind.ColonToken);
|
||||
writeSpace(writer);
|
||||
writeType(t, TypeFormatFlags.None);
|
||||
writeType(t, globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral);
|
||||
writePunctuation(writer, SyntaxKind.SemicolonToken);
|
||||
writer.writeLine();
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace ts {
|
||||
const writer = <EmitTextWriterWithSymbolWriter>createTextWriter(newLine);
|
||||
writer.trackSymbol = trackSymbol;
|
||||
writer.reportInaccessibleThisError = reportInaccessibleThisError;
|
||||
writer.reportIllegalExtends = reportIllegalExtends;
|
||||
writer.reportPrivateInBaseOfClassExpression = reportPrivateInBaseOfClassExpression;
|
||||
writer.writeKeyword = writer.write;
|
||||
writer.writeOperator = writer.write;
|
||||
writer.writePunctuation = writer.write;
|
||||
@@ -314,11 +314,11 @@ namespace ts {
|
||||
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
|
||||
}
|
||||
|
||||
function reportIllegalExtends() {
|
||||
function reportPrivateInBaseOfClassExpression(propertyName: string) {
|
||||
if (errorNameNode) {
|
||||
reportedDeclarationError = true;
|
||||
emitterDiagnostics.add(createDiagnosticForNode(errorNameNode, Diagnostics.extends_clause_of_exported_class_0_refers_to_a_type_whose_name_cannot_be_referenced,
|
||||
declarationNameToString(errorNameNode)));
|
||||
emitterDiagnostics.add(
|
||||
createDiagnosticForNode(errorNameNode, Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +344,9 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
errorNameNode = declaration.name;
|
||||
const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue |
|
||||
const format = TypeFormatFlags.UseTypeOfFunction |
|
||||
TypeFormatFlags.WriteClassExpressionAsTypeLiteral |
|
||||
TypeFormatFlags.UseTypeAliasValue |
|
||||
(shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0);
|
||||
resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer);
|
||||
errorNameNode = undefined;
|
||||
@@ -360,7 +362,11 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
errorNameNode = signature.name;
|
||||
resolver.writeReturnTypeOfSignatureDeclaration(signature, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
resolver.writeReturnTypeOfSignatureDeclaration(
|
||||
signature,
|
||||
enclosingDeclaration,
|
||||
TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue | TypeFormatFlags.WriteClassExpressionAsTypeLiteral,
|
||||
writer);
|
||||
errorNameNode = undefined;
|
||||
}
|
||||
}
|
||||
@@ -621,7 +627,11 @@ namespace ts {
|
||||
write(tempVarName);
|
||||
write(": ");
|
||||
writer.getSymbolAccessibilityDiagnostic = () => diagnostic;
|
||||
resolver.writeTypeOfExpression(expr, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
resolver.writeTypeOfExpression(
|
||||
expr,
|
||||
enclosingDeclaration,
|
||||
TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue | TypeFormatFlags.WriteClassExpressionAsTypeLiteral,
|
||||
writer);
|
||||
write(";");
|
||||
writeLine();
|
||||
return tempVarName;
|
||||
|
||||
@@ -2456,9 +2456,9 @@
|
||||
"category": "Error",
|
||||
"code": 4092
|
||||
},
|
||||
"'extends' clause of exported class '{0}' refers to a type whose name cannot be referenced.": {
|
||||
"Property '{0}' of exported class expression may not be private or protected.": {
|
||||
"category": "Error",
|
||||
"code": 4093
|
||||
"code": 4094
|
||||
},
|
||||
|
||||
"The current host does not support the '{0}' option.": {
|
||||
|
||||
@@ -2651,24 +2651,25 @@ namespace ts {
|
||||
// with import statements it previously saw (but chose not to emit).
|
||||
trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void;
|
||||
reportInaccessibleThisError(): void;
|
||||
reportIllegalExtends(): void;
|
||||
reportPrivateInBaseOfClassExpression(propertyName: string): void;
|
||||
}
|
||||
|
||||
export const enum TypeFormatFlags {
|
||||
None = 0x00000000,
|
||||
WriteArrayAsGenericType = 0x00000001, // Write Array<T> instead T[]
|
||||
UseTypeOfFunction = 0x00000002, // Write typeof instead of function type literal
|
||||
NoTruncation = 0x00000004, // Don't truncate typeToString result
|
||||
WriteArrowStyleSignature = 0x00000008, // Write arrow style signature
|
||||
WriteOwnNameForAnyLike = 0x00000010, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc)
|
||||
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
|
||||
InElementType = 0x00000040, // Writing an array or union element type
|
||||
UseFullyQualifiedType = 0x00000080, // Write out the fully qualified type name (eg. Module.Type, instead of Type)
|
||||
InFirstTypeArgument = 0x00000100, // Writing first type argument of the instantiated type
|
||||
InTypeAlias = 0x00000200, // Writing type in type alias declaration
|
||||
UseTypeAliasValue = 0x00000400, // Serialize the type instead of using type-alias. This is needed when we emit declaration file.
|
||||
SuppressAnyReturnType = 0x00000800, // If the return type is any-like, don't offer a return type.
|
||||
AddUndefined = 0x00001000, // Add undefined to types of initialized, non-optional parameters
|
||||
None = 0,
|
||||
WriteArrayAsGenericType = 1 << 0, // Write Array<T> instead T[]
|
||||
UseTypeOfFunction = 1 << 2, // Write typeof instead of function type literal
|
||||
NoTruncation = 1 << 3, // Don't truncate typeToString result
|
||||
WriteArrowStyleSignature = 1 << 4, // Write arrow style signature
|
||||
WriteOwnNameForAnyLike = 1 << 5, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc)
|
||||
WriteTypeArgumentsOfSignature = 1 << 6, // Write the type arguments instead of type parameters of the signature
|
||||
InElementType = 1 << 7, // Writing an array or union element type
|
||||
UseFullyQualifiedType = 1 << 8, // Write out the fully qualified type name (eg. Module.Type, instead of Type)
|
||||
InFirstTypeArgument = 1 << 9, // Writing first type argument of the instantiated type
|
||||
InTypeAlias = 1 << 10, // Writing type in type alias declaration
|
||||
UseTypeAliasValue = 1 << 11, // Serialize the type instead of using type-alias. This is needed when we emit declaration file.
|
||||
SuppressAnyReturnType = 1 << 12, // If the return type is any-like, don't offer a return type.
|
||||
AddUndefined = 1 << 13, // Add undefined to types of initialized, non-optional parameters
|
||||
WriteClassExpressionAsTypeLiteral = 1 << 14, // Write a type literal instead of (Anonymous class)
|
||||
}
|
||||
|
||||
export const enum SymbolFormatFlags {
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace ts {
|
||||
clear: () => str = "",
|
||||
trackSymbol: noop,
|
||||
reportInaccessibleThisError: noop,
|
||||
reportIllegalExtends: noop
|
||||
reportPrivateInBaseOfClassExpression: noop,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1136,7 +1136,7 @@ namespace ts {
|
||||
clear: resetWriter,
|
||||
trackSymbol: noop,
|
||||
reportInaccessibleThisError: noop,
|
||||
reportIllegalExtends: noop
|
||||
reportPrivateInBaseOfClassExpression: noop,
|
||||
};
|
||||
|
||||
function writeIndent() {
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
tests/cases/compiler/declarationEmitExpressionInExtends4.ts(1,10): error TS4060: Return type of exported function has or is using private name 'D'.
|
||||
tests/cases/compiler/declarationEmitExpressionInExtends4.ts(5,17): error TS2315: Type 'D' is not generic.
|
||||
tests/cases/compiler/declarationEmitExpressionInExtends4.ts(5,17): error TS4020: 'extends' clause of exported class 'C' has or is using private name 'D'.
|
||||
tests/cases/compiler/declarationEmitExpressionInExtends4.ts(9,18): error TS2304: Cannot find name 'SomeUndefinedFunction'.
|
||||
tests/cases/compiler/declarationEmitExpressionInExtends4.ts(14,18): error TS2304: Cannot find name 'SomeUndefinedFunction'.
|
||||
tests/cases/compiler/declarationEmitExpressionInExtends4.ts(14,18): error TS4020: 'extends' clause of exported class 'C3' has or is using private name 'SomeUndefinedFunction'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/declarationEmitExpressionInExtends4.ts (6 errors) ====
|
||||
==== tests/cases/compiler/declarationEmitExpressionInExtends4.ts (4 errors) ====
|
||||
function getSomething() {
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS4060: Return type of exported function has or is using private name 'D'.
|
||||
return class D { }
|
||||
}
|
||||
|
||||
class C extends getSomething()<number, string> {
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2315: Type 'D' is not generic.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS4020: 'extends' clause of exported class 'C' has or is using private name 'D'.
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
//// [emitClassExpressionInDeclarationFile.ts]
|
||||
export var simpleExample = class {
|
||||
static getTags() { }
|
||||
tags() { }
|
||||
}
|
||||
export var circularReference = class C {
|
||||
static getTags(c: C): C { return c }
|
||||
tags(c: C): C { return c }
|
||||
}
|
||||
|
||||
// repro from #15066
|
||||
export class FooItem {
|
||||
foo(): void { }
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export type Constructor<T> = new(...args: any[]) => T;
|
||||
export function WithTags<T extends Constructor<FooItem>>(Base: T) {
|
||||
return class extends Base {
|
||||
static getTags(): void { }
|
||||
tags(): void { }
|
||||
}
|
||||
}
|
||||
|
||||
export class Test extends WithTags(FooItem) {}
|
||||
|
||||
const test = new Test();
|
||||
|
||||
Test.getTags()
|
||||
test.tags();
|
||||
|
||||
|
||||
//// [emitClassExpressionInDeclarationFile.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
exports.simpleExample = (function () {
|
||||
function class_1() {
|
||||
}
|
||||
class_1.getTags = function () { };
|
||||
class_1.prototype.tags = function () { };
|
||||
return class_1;
|
||||
}());
|
||||
exports.circularReference = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.getTags = function (c) { return c; };
|
||||
C.prototype.tags = function (c) { return c; };
|
||||
return C;
|
||||
}());
|
||||
// repro from #15066
|
||||
var FooItem = (function () {
|
||||
function FooItem() {
|
||||
}
|
||||
FooItem.prototype.foo = function () { };
|
||||
return FooItem;
|
||||
}());
|
||||
exports.FooItem = FooItem;
|
||||
function WithTags(Base) {
|
||||
return (function (_super) {
|
||||
__extends(class_2, _super);
|
||||
function class_2() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
class_2.getTags = function () { };
|
||||
class_2.prototype.tags = function () { };
|
||||
return class_2;
|
||||
}(Base));
|
||||
}
|
||||
exports.WithTags = WithTags;
|
||||
var Test = (function (_super) {
|
||||
__extends(Test, _super);
|
||||
function Test() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return Test;
|
||||
}(WithTags(FooItem)));
|
||||
exports.Test = Test;
|
||||
var test = new Test();
|
||||
Test.getTags();
|
||||
test.tags();
|
||||
|
||||
|
||||
//// [emitClassExpressionInDeclarationFile.d.ts]
|
||||
export declare var simpleExample: {
|
||||
new (): {
|
||||
tags(): void;
|
||||
};
|
||||
getTags(): void;
|
||||
};
|
||||
export declare var circularReference: {
|
||||
new (): {
|
||||
tags(c: any): any;
|
||||
};
|
||||
getTags(c: {
|
||||
tags(c: any): any;
|
||||
}): {
|
||||
tags(c: any): any;
|
||||
};
|
||||
};
|
||||
export declare class FooItem {
|
||||
foo(): void;
|
||||
name?: string;
|
||||
}
|
||||
export declare type Constructor<T> = new (...args: any[]) => T;
|
||||
export declare function WithTags<T extends Constructor<FooItem>>(Base: T): {
|
||||
new (...args: any[]): {
|
||||
tags(): void;
|
||||
foo(): void;
|
||||
name?: string;
|
||||
};
|
||||
getTags(): void;
|
||||
} & T;
|
||||
declare const Test_base: {
|
||||
new (...args: any[]): {
|
||||
tags(): void;
|
||||
foo(): void;
|
||||
name?: string;
|
||||
};
|
||||
getTags(): void;
|
||||
} & typeof FooItem;
|
||||
export declare class Test extends Test_base {
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
=== tests/cases/compiler/emitClassExpressionInDeclarationFile.ts ===
|
||||
export var simpleExample = class {
|
||||
>simpleExample : Symbol(simpleExample, Decl(emitClassExpressionInDeclarationFile.ts, 0, 10))
|
||||
|
||||
static getTags() { }
|
||||
>getTags : Symbol(simpleExample.getTags, Decl(emitClassExpressionInDeclarationFile.ts, 0, 34))
|
||||
|
||||
tags() { }
|
||||
>tags : Symbol(simpleExample.tags, Decl(emitClassExpressionInDeclarationFile.ts, 1, 24))
|
||||
}
|
||||
export var circularReference = class C {
|
||||
>circularReference : Symbol(circularReference, Decl(emitClassExpressionInDeclarationFile.ts, 4, 10))
|
||||
>C : Symbol(C, Decl(emitClassExpressionInDeclarationFile.ts, 4, 30))
|
||||
|
||||
static getTags(c: C): C { return c }
|
||||
>getTags : Symbol(C.getTags, Decl(emitClassExpressionInDeclarationFile.ts, 4, 40))
|
||||
>c : Symbol(c, Decl(emitClassExpressionInDeclarationFile.ts, 5, 19))
|
||||
>C : Symbol(C, Decl(emitClassExpressionInDeclarationFile.ts, 4, 30))
|
||||
>C : Symbol(C, Decl(emitClassExpressionInDeclarationFile.ts, 4, 30))
|
||||
>c : Symbol(c, Decl(emitClassExpressionInDeclarationFile.ts, 5, 19))
|
||||
|
||||
tags(c: C): C { return c }
|
||||
>tags : Symbol(C.tags, Decl(emitClassExpressionInDeclarationFile.ts, 5, 40))
|
||||
>c : Symbol(c, Decl(emitClassExpressionInDeclarationFile.ts, 6, 9))
|
||||
>C : Symbol(C, Decl(emitClassExpressionInDeclarationFile.ts, 4, 30))
|
||||
>C : Symbol(C, Decl(emitClassExpressionInDeclarationFile.ts, 4, 30))
|
||||
>c : Symbol(c, Decl(emitClassExpressionInDeclarationFile.ts, 6, 9))
|
||||
}
|
||||
|
||||
// repro from #15066
|
||||
export class FooItem {
|
||||
>FooItem : Symbol(FooItem, Decl(emitClassExpressionInDeclarationFile.ts, 7, 1))
|
||||
|
||||
foo(): void { }
|
||||
>foo : Symbol(FooItem.foo, Decl(emitClassExpressionInDeclarationFile.ts, 10, 22))
|
||||
|
||||
name?: string;
|
||||
>name : Symbol(FooItem.name, Decl(emitClassExpressionInDeclarationFile.ts, 11, 19))
|
||||
}
|
||||
|
||||
export type Constructor<T> = new(...args: any[]) => T;
|
||||
>Constructor : Symbol(Constructor, Decl(emitClassExpressionInDeclarationFile.ts, 13, 1))
|
||||
>T : Symbol(T, Decl(emitClassExpressionInDeclarationFile.ts, 15, 24))
|
||||
>args : Symbol(args, Decl(emitClassExpressionInDeclarationFile.ts, 15, 33))
|
||||
>T : Symbol(T, Decl(emitClassExpressionInDeclarationFile.ts, 15, 24))
|
||||
|
||||
export function WithTags<T extends Constructor<FooItem>>(Base: T) {
|
||||
>WithTags : Symbol(WithTags, Decl(emitClassExpressionInDeclarationFile.ts, 15, 54))
|
||||
>T : Symbol(T, Decl(emitClassExpressionInDeclarationFile.ts, 16, 25))
|
||||
>Constructor : Symbol(Constructor, Decl(emitClassExpressionInDeclarationFile.ts, 13, 1))
|
||||
>FooItem : Symbol(FooItem, Decl(emitClassExpressionInDeclarationFile.ts, 7, 1))
|
||||
>Base : Symbol(Base, Decl(emitClassExpressionInDeclarationFile.ts, 16, 57))
|
||||
>T : Symbol(T, Decl(emitClassExpressionInDeclarationFile.ts, 16, 25))
|
||||
|
||||
return class extends Base {
|
||||
>Base : Symbol(Base, Decl(emitClassExpressionInDeclarationFile.ts, 16, 57))
|
||||
|
||||
static getTags(): void { }
|
||||
>getTags : Symbol((Anonymous class).getTags, Decl(emitClassExpressionInDeclarationFile.ts, 17, 31))
|
||||
|
||||
tags(): void { }
|
||||
>tags : Symbol((Anonymous class).tags, Decl(emitClassExpressionInDeclarationFile.ts, 18, 34))
|
||||
}
|
||||
}
|
||||
|
||||
export class Test extends WithTags(FooItem) {}
|
||||
>Test : Symbol(Test, Decl(emitClassExpressionInDeclarationFile.ts, 21, 1))
|
||||
>WithTags : Symbol(WithTags, Decl(emitClassExpressionInDeclarationFile.ts, 15, 54))
|
||||
>FooItem : Symbol(FooItem, Decl(emitClassExpressionInDeclarationFile.ts, 7, 1))
|
||||
|
||||
const test = new Test();
|
||||
>test : Symbol(test, Decl(emitClassExpressionInDeclarationFile.ts, 25, 5))
|
||||
>Test : Symbol(Test, Decl(emitClassExpressionInDeclarationFile.ts, 21, 1))
|
||||
|
||||
Test.getTags()
|
||||
>Test.getTags : Symbol((Anonymous class).getTags, Decl(emitClassExpressionInDeclarationFile.ts, 17, 31))
|
||||
>Test : Symbol(Test, Decl(emitClassExpressionInDeclarationFile.ts, 21, 1))
|
||||
>getTags : Symbol((Anonymous class).getTags, Decl(emitClassExpressionInDeclarationFile.ts, 17, 31))
|
||||
|
||||
test.tags();
|
||||
>test.tags : Symbol((Anonymous class).tags, Decl(emitClassExpressionInDeclarationFile.ts, 18, 34))
|
||||
>test : Symbol(test, Decl(emitClassExpressionInDeclarationFile.ts, 25, 5))
|
||||
>tags : Symbol((Anonymous class).tags, Decl(emitClassExpressionInDeclarationFile.ts, 18, 34))
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
=== tests/cases/compiler/emitClassExpressionInDeclarationFile.ts ===
|
||||
export var simpleExample = class {
|
||||
>simpleExample : typeof simpleExample
|
||||
>class { static getTags() { } tags() { }} : typeof simpleExample
|
||||
|
||||
static getTags() { }
|
||||
>getTags : () => void
|
||||
|
||||
tags() { }
|
||||
>tags : () => void
|
||||
}
|
||||
export var circularReference = class C {
|
||||
>circularReference : typeof C
|
||||
>class C { static getTags(c: C): C { return c } tags(c: C): C { return c }} : typeof C
|
||||
>C : typeof C
|
||||
|
||||
static getTags(c: C): C { return c }
|
||||
>getTags : (c: C) => C
|
||||
>c : C
|
||||
>C : C
|
||||
>C : C
|
||||
>c : C
|
||||
|
||||
tags(c: C): C { return c }
|
||||
>tags : (c: C) => C
|
||||
>c : C
|
||||
>C : C
|
||||
>C : C
|
||||
>c : C
|
||||
}
|
||||
|
||||
// repro from #15066
|
||||
export class FooItem {
|
||||
>FooItem : FooItem
|
||||
|
||||
foo(): void { }
|
||||
>foo : () => void
|
||||
|
||||
name?: string;
|
||||
>name : string
|
||||
}
|
||||
|
||||
export type Constructor<T> = new(...args: any[]) => T;
|
||||
>Constructor : Constructor<T>
|
||||
>T : T
|
||||
>args : any[]
|
||||
>T : T
|
||||
|
||||
export function WithTags<T extends Constructor<FooItem>>(Base: T) {
|
||||
>WithTags : <T extends Constructor<FooItem>>(Base: T) => { new (...args: any[]): (Anonymous class); prototype: WithTags<any>.(Anonymous class); getTags(): void; } & T
|
||||
>T : T
|
||||
>Constructor : Constructor<T>
|
||||
>FooItem : FooItem
|
||||
>Base : T
|
||||
>T : T
|
||||
|
||||
return class extends Base {
|
||||
>class extends Base { static getTags(): void { } tags(): void { } } : { new (...args: any[]): (Anonymous class); prototype: WithTags<any>.(Anonymous class); getTags(): void; } & T
|
||||
>Base : FooItem
|
||||
|
||||
static getTags(): void { }
|
||||
>getTags : () => void
|
||||
|
||||
tags(): void { }
|
||||
>tags : () => void
|
||||
}
|
||||
}
|
||||
|
||||
export class Test extends WithTags(FooItem) {}
|
||||
>Test : Test
|
||||
>WithTags(FooItem) : WithTags<typeof FooItem>.(Anonymous class) & FooItem
|
||||
>WithTags : <T extends Constructor<FooItem>>(Base: T) => { new (...args: any[]): (Anonymous class); prototype: WithTags<any>.(Anonymous class); getTags(): void; } & T
|
||||
>FooItem : typeof FooItem
|
||||
|
||||
const test = new Test();
|
||||
>test : Test
|
||||
>new Test() : Test
|
||||
>Test : typeof Test
|
||||
|
||||
Test.getTags()
|
||||
>Test.getTags() : void
|
||||
>Test.getTags : () => void
|
||||
>Test : typeof Test
|
||||
>getTags : () => void
|
||||
|
||||
test.tags();
|
||||
>test.tags() : void
|
||||
>test.tags : () => void
|
||||
>test : Test
|
||||
>tags : () => void
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
tests/cases/compiler/emitClassExpressionInDeclarationFile2.ts(1,12): error TS4094: Property 'p' of exported class expression may not be private or protected.
|
||||
tests/cases/compiler/emitClassExpressionInDeclarationFile2.ts(1,12): error TS4094: Property 'ps' of exported class expression may not be private or protected.
|
||||
tests/cases/compiler/emitClassExpressionInDeclarationFile2.ts(16,17): error TS4094: Property 'property' of exported class expression may not be private or protected.
|
||||
|
||||
|
||||
==== tests/cases/compiler/emitClassExpressionInDeclarationFile2.ts (3 errors) ====
|
||||
export var noPrivates = class {
|
||||
~~~~~~~~~~
|
||||
!!! error TS4094: Property 'p' of exported class expression may not be private or protected.
|
||||
~~~~~~~~~~
|
||||
!!! error TS4094: Property 'ps' of exported class expression may not be private or protected.
|
||||
static getTags() { }
|
||||
tags() { }
|
||||
private static ps = -1
|
||||
private p = 12
|
||||
}
|
||||
|
||||
// altered repro from #15066 to add private property
|
||||
export class FooItem {
|
||||
foo(): void { }
|
||||
name?: string;
|
||||
private property = "capitalism"
|
||||
}
|
||||
|
||||
export type Constructor<T> = new(...args: any[]) => T;
|
||||
export function WithTags<T extends Constructor<FooItem>>(Base: T) {
|
||||
~~~~~~~~
|
||||
!!! error TS4094: Property 'property' of exported class expression may not be private or protected.
|
||||
return class extends Base {
|
||||
static getTags(): void { }
|
||||
tags(): void { }
|
||||
}
|
||||
}
|
||||
|
||||
export class Test extends WithTags(FooItem) {}
|
||||
|
||||
const test = new Test();
|
||||
|
||||
Test.getTags()
|
||||
test.tags();
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
//// [emitClassExpressionInDeclarationFile2.ts]
|
||||
export var noPrivates = class {
|
||||
static getTags() { }
|
||||
tags() { }
|
||||
private static ps = -1
|
||||
private p = 12
|
||||
}
|
||||
|
||||
// altered repro from #15066 to add private property
|
||||
export class FooItem {
|
||||
foo(): void { }
|
||||
name?: string;
|
||||
private property = "capitalism"
|
||||
}
|
||||
|
||||
export type Constructor<T> = new(...args: any[]) => T;
|
||||
export function WithTags<T extends Constructor<FooItem>>(Base: T) {
|
||||
return class extends Base {
|
||||
static getTags(): void { }
|
||||
tags(): void { }
|
||||
}
|
||||
}
|
||||
|
||||
export class Test extends WithTags(FooItem) {}
|
||||
|
||||
const test = new Test();
|
||||
|
||||
Test.getTags()
|
||||
test.tags();
|
||||
|
||||
|
||||
//// [emitClassExpressionInDeclarationFile2.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
exports.noPrivates = (_a = (function () {
|
||||
function class_1() {
|
||||
this.p = 12;
|
||||
}
|
||||
class_1.getTags = function () { };
|
||||
class_1.prototype.tags = function () { };
|
||||
return class_1;
|
||||
}()),
|
||||
_a.ps = -1,
|
||||
_a);
|
||||
// altered repro from #15066 to add private property
|
||||
var FooItem = (function () {
|
||||
function FooItem() {
|
||||
this.property = "capitalism";
|
||||
}
|
||||
FooItem.prototype.foo = function () { };
|
||||
return FooItem;
|
||||
}());
|
||||
exports.FooItem = FooItem;
|
||||
function WithTags(Base) {
|
||||
return (function (_super) {
|
||||
__extends(class_2, _super);
|
||||
function class_2() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
class_2.getTags = function () { };
|
||||
class_2.prototype.tags = function () { };
|
||||
return class_2;
|
||||
}(Base));
|
||||
}
|
||||
exports.WithTags = WithTags;
|
||||
var Test = (function (_super) {
|
||||
__extends(Test, _super);
|
||||
function Test() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
return Test;
|
||||
}(WithTags(FooItem)));
|
||||
exports.Test = Test;
|
||||
var test = new Test();
|
||||
Test.getTags();
|
||||
test.tags();
|
||||
var _a;
|
||||
30
tests/cases/compiler/emitClassExpressionInDeclarationFile.ts
Normal file
30
tests/cases/compiler/emitClassExpressionInDeclarationFile.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
// @declaration: true
|
||||
export var simpleExample = class {
|
||||
static getTags() { }
|
||||
tags() { }
|
||||
}
|
||||
export var circularReference = class C {
|
||||
static getTags(c: C): C { return c }
|
||||
tags(c: C): C { return c }
|
||||
}
|
||||
|
||||
// repro from #15066
|
||||
export class FooItem {
|
||||
foo(): void { }
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export type Constructor<T> = new(...args: any[]) => T;
|
||||
export function WithTags<T extends Constructor<FooItem>>(Base: T) {
|
||||
return class extends Base {
|
||||
static getTags(): void { }
|
||||
tags(): void { }
|
||||
}
|
||||
}
|
||||
|
||||
export class Test extends WithTags(FooItem) {}
|
||||
|
||||
const test = new Test();
|
||||
|
||||
Test.getTags()
|
||||
test.tags();
|
||||
@@ -0,0 +1,29 @@
|
||||
// @declaration: true
|
||||
export var noPrivates = class {
|
||||
static getTags() { }
|
||||
tags() { }
|
||||
private static ps = -1
|
||||
private p = 12
|
||||
}
|
||||
|
||||
// altered repro from #15066 to add private property
|
||||
export class FooItem {
|
||||
foo(): void { }
|
||||
name?: string;
|
||||
private property = "capitalism"
|
||||
}
|
||||
|
||||
export type Constructor<T> = new(...args: any[]) => T;
|
||||
export function WithTags<T extends Constructor<FooItem>>(Base: T) {
|
||||
return class extends Base {
|
||||
static getTags(): void { }
|
||||
tags(): void { }
|
||||
}
|
||||
}
|
||||
|
||||
export class Test extends WithTags(FooItem) {}
|
||||
|
||||
const test = new Test();
|
||||
|
||||
Test.getTags()
|
||||
test.tags();
|
||||
Reference in New Issue
Block a user