From 59403796c70ec51d1f40c398befa50768ca7b289 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 29 Nov 2016 12:42:17 -0800 Subject: [PATCH 1/3] Add serialization of typenode for null/undefined/never as part of metadata type Fixes #12684 and #11933 --- src/compiler/transformers/ts.ts | 41 ++++++---- src/compiler/utilities.ts | 4 + .../reference/metadataOfUnionWithNull.js | 78 +++++++++++++++++++ .../reference/metadataOfUnionWithNull.symbols | 56 +++++++++++++ .../reference/metadataOfUnionWithNull.types | 60 ++++++++++++++ .../cases/compiler/metadataOfUnionWithNull.ts | 29 +++++++ 6 files changed, 253 insertions(+), 15 deletions(-) create mode 100644 tests/baselines/reference/metadataOfUnionWithNull.js create mode 100644 tests/baselines/reference/metadataOfUnionWithNull.symbols create mode 100644 tests/baselines/reference/metadataOfUnionWithNull.types create mode 100644 tests/cases/compiler/metadataOfUnionWithNull.ts diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 877131b369c87..366c94aa629c6 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1662,6 +1662,8 @@ namespace ts { switch (node.kind) { case SyntaxKind.VoidKeyword: + case SyntaxKind.UndefinedKeyword: + case SyntaxKind.NullKeyword: return createVoidZero(); case SyntaxKind.ParenthesizedType: @@ -1715,27 +1717,35 @@ namespace ts { case SyntaxKind.UnionType: { const unionOrIntersection = node; - let serializedUnion: Identifier; + let serializedUnion: Identifier | VoidExpression; for (const typeNode of unionOrIntersection.types) { - const serializedIndividual = serializeTypeNode(typeNode) as Identifier; - // Non identifier - if (serializedIndividual.kind !== SyntaxKind.Identifier) { - serializedUnion = undefined; - break; - } + const serializedIndividual = serializeTypeNode(typeNode); - // One of the individual is global object, return immediately - if (serializedIndividual.text === "Object") { - return serializedIndividual; - } + if (isIdentifier(serializedIndividual)) { + // One of the individual is global object, return immediately + if (serializedIndividual.text === "Object") { + return serializedIndividual; + } + + // Different types + if (serializedUnion && isIdentifier(serializedUnion) && serializedUnion.text !== serializedIndividual.text) { + serializedUnion = undefined; + break; + } - // Different types - if (serializedUnion && serializedUnion.text !== serializedIndividual.text) { + serializedUnion = serializedIndividual; + } + else if (isVoidExpression(serializedIndividual)) { + // If we dont have any other type already set, set the initial type + if (!serializedUnion) { + serializedUnion = serializedIndividual; + } + } + else { + // Non identifier and undefined/null serializedUnion = undefined; break; } - - serializedUnion = serializedIndividual; } // If we were able to find common type @@ -1751,6 +1761,7 @@ namespace ts { case SyntaxKind.TypeLiteral: case SyntaxKind.AnyKeyword: case SyntaxKind.ThisType: + case SyntaxKind.NeverKeyword: break; default: diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6f491f6708fee..0914b0d0c246c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3581,6 +3581,10 @@ namespace ts { return node.kind === SyntaxKind.Identifier; } + export function isVoidExpression(node: Node): node is VoidExpression { + return node.kind === SyntaxKind.VoidExpression; + } + export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier { // Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`. return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None; diff --git a/tests/baselines/reference/metadataOfUnionWithNull.js b/tests/baselines/reference/metadataOfUnionWithNull.js new file mode 100644 index 0000000000000..7b4b734b83417 --- /dev/null +++ b/tests/baselines/reference/metadataOfUnionWithNull.js @@ -0,0 +1,78 @@ +//// [metadataOfUnionWithNull.ts] +function PropDeco(target: Object, propKey: string | symbol) { } + +class A { +} + +class B { + @PropDeco + x: "foo" | null; + + @PropDeco + y: true | never; + + @PropDeco + z: "foo" | undefined; + + @PropDeco + a: null; + + @PropDeco + b: never; + + @PropDeco + c: undefined; + + @PropDeco + d: undefined | null; +} + +//// [metadataOfUnionWithNull.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +function PropDeco(target, propKey) { } +var A = (function () { + function A() { + } + return A; +}()); +var B = (function () { + function B() { + } + return B; +}()); +__decorate([ + PropDeco, + __metadata("design:type", String) +], B.prototype, "x"); +__decorate([ + PropDeco, + __metadata("design:type", Object) +], B.prototype, "y"); +__decorate([ + PropDeco, + __metadata("design:type", String) +], B.prototype, "z"); +__decorate([ + PropDeco, + __metadata("design:type", void 0) +], B.prototype, "a"); +__decorate([ + PropDeco, + __metadata("design:type", Object) +], B.prototype, "b"); +__decorate([ + PropDeco, + __metadata("design:type", void 0) +], B.prototype, "c"); +__decorate([ + PropDeco, + __metadata("design:type", void 0) +], B.prototype, "d"); diff --git a/tests/baselines/reference/metadataOfUnionWithNull.symbols b/tests/baselines/reference/metadataOfUnionWithNull.symbols new file mode 100644 index 0000000000000..13533a26699a2 --- /dev/null +++ b/tests/baselines/reference/metadataOfUnionWithNull.symbols @@ -0,0 +1,56 @@ +=== tests/cases/compiler/metadataOfUnionWithNull.ts === +function PropDeco(target: Object, propKey: string | symbol) { } +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) +>target : Symbol(target, Decl(metadataOfUnionWithNull.ts, 0, 18)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>propKey : Symbol(propKey, Decl(metadataOfUnionWithNull.ts, 0, 33)) + +class A { +>A : Symbol(A, Decl(metadataOfUnionWithNull.ts, 0, 63)) +} + +class B { +>B : Symbol(B, Decl(metadataOfUnionWithNull.ts, 3, 1)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + x: "foo" | null; +>x : Symbol(B.x, Decl(metadataOfUnionWithNull.ts, 5, 9)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + y: true | never; +>y : Symbol(B.y, Decl(metadataOfUnionWithNull.ts, 7, 20)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + z: "foo" | undefined; +>z : Symbol(B.z, Decl(metadataOfUnionWithNull.ts, 10, 20)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + a: null; +>a : Symbol(B.a, Decl(metadataOfUnionWithNull.ts, 13, 25)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + b: never; +>b : Symbol(B.b, Decl(metadataOfUnionWithNull.ts, 16, 12)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + c: undefined; +>c : Symbol(B.c, Decl(metadataOfUnionWithNull.ts, 19, 13)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + d: undefined | null; +>d : Symbol(B.d, Decl(metadataOfUnionWithNull.ts, 22, 17)) +} diff --git a/tests/baselines/reference/metadataOfUnionWithNull.types b/tests/baselines/reference/metadataOfUnionWithNull.types new file mode 100644 index 0000000000000..e6037e16cb3b0 --- /dev/null +++ b/tests/baselines/reference/metadataOfUnionWithNull.types @@ -0,0 +1,60 @@ +=== tests/cases/compiler/metadataOfUnionWithNull.ts === +function PropDeco(target: Object, propKey: string | symbol) { } +>PropDeco : (target: Object, propKey: string | symbol) => void +>target : Object +>Object : Object +>propKey : string | symbol + +class A { +>A : A +} + +class B { +>B : B + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + x: "foo" | null; +>x : "foo" +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + y: true | never; +>y : true +>true : true + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + z: "foo" | undefined; +>z : "foo" + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + a: null; +>a : null +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + b: never; +>b : never + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + c: undefined; +>c : undefined + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + d: undefined | null; +>d : null +>null : null +} diff --git a/tests/cases/compiler/metadataOfUnionWithNull.ts b/tests/cases/compiler/metadataOfUnionWithNull.ts new file mode 100644 index 0000000000000..475024229fced --- /dev/null +++ b/tests/cases/compiler/metadataOfUnionWithNull.ts @@ -0,0 +1,29 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +function PropDeco(target: Object, propKey: string | symbol) { } + +class A { +} + +class B { + @PropDeco + x: "foo" | null; + + @PropDeco + y: true | never; + + @PropDeco + z: "foo" | undefined; + + @PropDeco + a: null; + + @PropDeco + b: never; + + @PropDeco + c: undefined; + + @PropDeco + d: undefined | null; +} \ No newline at end of file From 73a829279ab9534802763bbda02aaf6816e08eaa Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 29 Nov 2016 12:42:17 -0800 Subject: [PATCH 2/3] Support union of non identifier serialized type node with null/undefined/never --- src/compiler/transformers/ts.ts | 91 ++++++++++--------- .../reference/metadataOfUnionWithNull.js | 39 +++++++- .../reference/metadataOfUnionWithNull.symbols | 33 +++++++ .../reference/metadataOfUnionWithNull.types | 37 ++++++++ .../cases/compiler/metadataOfUnionWithNull.ts | 15 +++ 5 files changed, 168 insertions(+), 47 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 366c94aa629c6..ecd2e2dfcfd9d 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1637,6 +1637,8 @@ namespace ts { return createVoidZero(); } + type SerializedTypeNode = SerializedEntityNameAsExpression | VoidExpression | ConditionalExpression; + /** * Serializes a type node for use with decorator type metadata. * @@ -1655,7 +1657,7 @@ namespace ts { * * @param node The type node to serialize. */ - function serializeTypeNode(node: TypeNode): Expression { + function serializeTypeNode(node: TypeNode): SerializedTypeNode { if (node === undefined) { return createIdentifier("Object"); } @@ -1664,6 +1666,7 @@ namespace ts { case SyntaxKind.VoidKeyword: case SyntaxKind.UndefinedKeyword: case SyntaxKind.NullKeyword: + case SyntaxKind.NeverKeyword: return createVoidZero(); case SyntaxKind.ParenthesizedType: @@ -1715,45 +1718,8 @@ namespace ts { case SyntaxKind.IntersectionType: case SyntaxKind.UnionType: - { - const unionOrIntersection = node; - let serializedUnion: Identifier | VoidExpression; - for (const typeNode of unionOrIntersection.types) { - const serializedIndividual = serializeTypeNode(typeNode); - - if (isIdentifier(serializedIndividual)) { - // One of the individual is global object, return immediately - if (serializedIndividual.text === "Object") { - return serializedIndividual; - } - - // Different types - if (serializedUnion && isIdentifier(serializedUnion) && serializedUnion.text !== serializedIndividual.text) { - serializedUnion = undefined; - break; - } - - serializedUnion = serializedIndividual; - } - else if (isVoidExpression(serializedIndividual)) { - // If we dont have any other type already set, set the initial type - if (!serializedUnion) { - serializedUnion = serializedIndividual; - } - } - else { - // Non identifier and undefined/null - serializedUnion = undefined; - break; - } - } + return serializeUnionOrIntersectionType(node); - // If we were able to find common type - if (serializedUnion) { - return serializedUnion; - } - } - // Fallthrough case SyntaxKind.TypeQuery: case SyntaxKind.TypeOperator: case SyntaxKind.IndexedAccessType: @@ -1761,7 +1727,6 @@ namespace ts { case SyntaxKind.TypeLiteral: case SyntaxKind.AnyKeyword: case SyntaxKind.ThisType: - case SyntaxKind.NeverKeyword: break; default: @@ -1772,13 +1737,48 @@ namespace ts { return createIdentifier("Object"); } + function serializeUnionOrIntersectionType(node: UnionOrIntersectionTypeNode): SerializedTypeNode { + let serializedUnion: SerializedTypeNode; + for (const typeNode of node.types) { + const serializedIndividual = serializeTypeNode(typeNode); + + if (isVoidExpression(serializedIndividual)) { + // If we dont have any other type already set, set the initial type + if (!serializedUnion) { + serializedUnion = serializedIndividual; + } + } + else if (isIdentifier(serializedIndividual) && serializedIndividual.text === "Object") { + // One of the individual is global object, return immediately + return serializedIndividual; + } + // If there exists union that is not void 0 expression, check if the the common type is identifier. + // anything more complex and we will just default to Object + else if (serializedUnion && !isVoidExpression(serializedUnion)) { + // Different types + if (!isIdentifier(serializedUnion) || + !isIdentifier(serializedIndividual) || + serializedUnion.text !== serializedIndividual.text) { + return createIdentifier("Object"); + } + } + else { + // Initialize the union type + serializedUnion = serializedIndividual; + } + } + + // If we were able to find common type, use it + return serializedUnion; + } + /** * Serializes a TypeReferenceNode to an appropriate JS constructor value for use with * decorator type metadata. * * @param node The type reference node. */ - function serializeTypeReferenceNode(node: TypeReferenceNode) { + function serializeTypeReferenceNode(node: TypeReferenceNode): SerializedTypeNode { switch (resolver.getTypeReferenceSerializationKind(node.typeName, currentScope)) { case TypeReferenceSerializationKind.Unknown: const serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true); @@ -1826,6 +1826,7 @@ namespace ts { } } + type SerializedEntityNameAsExpression = Identifier | BinaryExpression | PropertyAccessExpression; /** * Serializes an entity name as an expression for decorator type metadata. * @@ -1833,7 +1834,7 @@ namespace ts { * @param useFallback A value indicating whether to use logical operators to test for the * entity name at runtime. */ - function serializeEntityNameAsExpression(node: EntityName, useFallback: boolean): Expression { + function serializeEntityNameAsExpression(node: EntityName, useFallback: boolean): SerializedEntityNameAsExpression { switch (node.kind) { case SyntaxKind.Identifier: // Create a clone of the name with a new parent, and treat it as if it were @@ -1866,8 +1867,8 @@ namespace ts { * @param useFallback A value indicating whether to use logical operators to test for the * qualified name at runtime. */ - function serializeQualifiedNameAsExpression(node: QualifiedName, useFallback: boolean): Expression { - let left: Expression; + function serializeQualifiedNameAsExpression(node: QualifiedName, useFallback: boolean): PropertyAccessExpression { + let left: SerializedEntityNameAsExpression; if (node.left.kind === SyntaxKind.Identifier) { left = serializeEntityNameAsExpression(node.left, useFallback); } @@ -1892,7 +1893,7 @@ namespace ts { * Gets an expression that points to the global "Symbol" constructor at runtime if it is * available. */ - function getGlobalSymbolNameWithFallback(): Expression { + function getGlobalSymbolNameWithFallback(): ConditionalExpression { return createConditional( createTypeCheck(createIdentifier("Symbol"), "function"), createIdentifier("Symbol"), diff --git a/tests/baselines/reference/metadataOfUnionWithNull.js b/tests/baselines/reference/metadataOfUnionWithNull.js index 7b4b734b83417..cc594ae326dc3 100644 --- a/tests/baselines/reference/metadataOfUnionWithNull.js +++ b/tests/baselines/reference/metadataOfUnionWithNull.js @@ -25,6 +25,21 @@ class B { @PropDeco d: undefined | null; + + @PropDeco + e: symbol | null; + + @PropDeco + f: symbol | A; + + @PropDeco + g: A | null; + + @PropDeco + h: null | B; + + @PropDeco + j: null | symbol; } //// [metadataOfUnionWithNull.js] @@ -54,7 +69,7 @@ __decorate([ ], B.prototype, "x"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", Boolean) ], B.prototype, "y"); __decorate([ PropDeco, @@ -66,7 +81,7 @@ __decorate([ ], B.prototype, "a"); __decorate([ PropDeco, - __metadata("design:type", Object) + __metadata("design:type", void 0) ], B.prototype, "b"); __decorate([ PropDeco, @@ -76,3 +91,23 @@ __decorate([ PropDeco, __metadata("design:type", void 0) ], B.prototype, "d"); +__decorate([ + PropDeco, + __metadata("design:type", typeof Symbol === "function" ? Symbol : Object) +], B.prototype, "e"); +__decorate([ + PropDeco, + __metadata("design:type", Object) +], B.prototype, "f"); +__decorate([ + PropDeco, + __metadata("design:type", A) +], B.prototype, "g"); +__decorate([ + PropDeco, + __metadata("design:type", B) +], B.prototype, "h"); +__decorate([ + PropDeco, + __metadata("design:type", typeof Symbol === "function" ? Symbol : Object) +], B.prototype, "j"); diff --git a/tests/baselines/reference/metadataOfUnionWithNull.symbols b/tests/baselines/reference/metadataOfUnionWithNull.symbols index 13533a26699a2..13316bc7cf19e 100644 --- a/tests/baselines/reference/metadataOfUnionWithNull.symbols +++ b/tests/baselines/reference/metadataOfUnionWithNull.symbols @@ -53,4 +53,37 @@ class B { d: undefined | null; >d : Symbol(B.d, Decl(metadataOfUnionWithNull.ts, 22, 17)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + e: symbol | null; +>e : Symbol(B.e, Decl(metadataOfUnionWithNull.ts, 25, 24)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + f: symbol | A; +>f : Symbol(B.f, Decl(metadataOfUnionWithNull.ts, 28, 21)) +>A : Symbol(A, Decl(metadataOfUnionWithNull.ts, 0, 63)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + g: A | null; +>g : Symbol(B.g, Decl(metadataOfUnionWithNull.ts, 31, 18)) +>A : Symbol(A, Decl(metadataOfUnionWithNull.ts, 0, 63)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + h: null | B; +>h : Symbol(B.h, Decl(metadataOfUnionWithNull.ts, 34, 16)) +>B : Symbol(B, Decl(metadataOfUnionWithNull.ts, 3, 1)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + j: null | symbol; +>j : Symbol(B.j, Decl(metadataOfUnionWithNull.ts, 37, 16)) } diff --git a/tests/baselines/reference/metadataOfUnionWithNull.types b/tests/baselines/reference/metadataOfUnionWithNull.types index e6037e16cb3b0..04a5b162d4c52 100644 --- a/tests/baselines/reference/metadataOfUnionWithNull.types +++ b/tests/baselines/reference/metadataOfUnionWithNull.types @@ -56,5 +56,42 @@ class B { d: undefined | null; >d : null +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + e: symbol | null; +>e : symbol +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + f: symbol | A; +>f : symbol | A +>A : A + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + g: A | null; +>g : A +>A : A +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + h: null | B; +>h : B +>null : null +>B : B + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + j: null | symbol; +>j : symbol >null : null } diff --git a/tests/cases/compiler/metadataOfUnionWithNull.ts b/tests/cases/compiler/metadataOfUnionWithNull.ts index 475024229fced..bb4d93189fc66 100644 --- a/tests/cases/compiler/metadataOfUnionWithNull.ts +++ b/tests/cases/compiler/metadataOfUnionWithNull.ts @@ -26,4 +26,19 @@ class B { @PropDeco d: undefined | null; + + @PropDeco + e: symbol | null; + + @PropDeco + f: symbol | A; + + @PropDeco + g: A | null; + + @PropDeco + h: null | B; + + @PropDeco + j: null | symbol; } \ No newline at end of file From 62426de220f7404508f7a0fd9f22f677d7cfcab2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 21 Dec 2016 12:11:47 -0800 Subject: [PATCH 3/3] Nit: Moving type aliases for serialized type nodes as per feedback --- src/compiler/transformers/ts.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index ecd2e2dfcfd9d..f791025807a25 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1555,12 +1555,15 @@ namespace ts { return false; } + type SerializedEntityNameAsExpression = Identifier | BinaryExpression | PropertyAccessExpression; + type SerializedTypeNode = SerializedEntityNameAsExpression | VoidExpression | ConditionalExpression; + /** * Serializes the type of a node for use with decorator type metadata. * * @param node The node that should have its type serialized. */ - function serializeTypeOfNode(node: Node): Expression { + function serializeTypeOfNode(node: Node): SerializedTypeNode { switch (node.kind) { case SyntaxKind.PropertyDeclaration: case SyntaxKind.Parameter: @@ -1582,7 +1585,7 @@ namespace ts { * * @param node The node that should have its parameter types serialized. */ - function serializeParameterTypesOfNode(node: Node, container: ClassLikeDeclaration): Expression { + function serializeParameterTypesOfNode(node: Node, container: ClassLikeDeclaration): ArrayLiteralExpression { const valueDeclaration = isClassLike(node) ? getFirstConstructorWithBody(node) @@ -1590,7 +1593,7 @@ namespace ts { ? node : undefined; - const expressions: Expression[] = []; + const expressions: SerializedTypeNode[] = []; if (valueDeclaration) { const parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container); const numParameters = parameters.length; @@ -1626,7 +1629,7 @@ namespace ts { * * @param node The node that should have its return type serialized. */ - function serializeReturnTypeOfNode(node: Node): Expression { + function serializeReturnTypeOfNode(node: Node): SerializedTypeNode { if (isFunctionLike(node) && node.type) { return serializeTypeNode(node.type); } @@ -1637,8 +1640,6 @@ namespace ts { return createVoidZero(); } - type SerializedTypeNode = SerializedEntityNameAsExpression | VoidExpression | ConditionalExpression; - /** * Serializes a type node for use with decorator type metadata. * @@ -1826,7 +1827,6 @@ namespace ts { } } - type SerializedEntityNameAsExpression = Identifier | BinaryExpression | PropertyAccessExpression; /** * Serializes an entity name as an expression for decorator type metadata. *