Skip to content

Commit 7555f60

Browse files
authored
Merge pull request #11391 from Microsoft/metaDataWithStringLiteral
Emit of union type metadata for decorator to use constituent serialized type if its identifier and same across all constituent types
2 parents 3008520 + 506afe5 commit 7555f60

File tree

9 files changed

+409
-2
lines changed

9 files changed

+409
-2
lines changed

src/compiler/transformers/ts.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,10 +1801,41 @@ namespace ts {
18011801
case SyntaxKind.TypeReference:
18021802
return serializeTypeReferenceNode(<TypeReferenceNode>node);
18031803

1804+
case SyntaxKind.IntersectionType:
1805+
case SyntaxKind.UnionType:
1806+
{
1807+
const unionOrIntersection = <UnionOrIntersectionTypeNode>node;
1808+
let serializedUnion: Identifier;
1809+
for (const typeNode of unionOrIntersection.types) {
1810+
const serializedIndividual = serializeTypeNode(typeNode) as Identifier;
1811+
// Non identifier
1812+
if (serializedIndividual.kind !== SyntaxKind.Identifier) {
1813+
serializedUnion = undefined;
1814+
break;
1815+
}
1816+
1817+
// One of the individual is global object, return immediately
1818+
if (serializedIndividual.text === "Object") {
1819+
return serializedIndividual;
1820+
}
1821+
1822+
// Different types
1823+
if (serializedUnion && serializedUnion.text !== serializedIndividual.text) {
1824+
serializedUnion = undefined;
1825+
break;
1826+
}
1827+
1828+
serializedUnion = serializedIndividual;
1829+
}
1830+
1831+
// If we were able to find common type
1832+
if (serializedUnion) {
1833+
return serializedUnion;
1834+
}
1835+
}
1836+
// Fallthrough
18041837
case SyntaxKind.TypeQuery:
18051838
case SyntaxKind.TypeLiteral:
1806-
case SyntaxKind.UnionType:
1807-
case SyntaxKind.IntersectionType:
18081839
case SyntaxKind.AnyKeyword:
18091840
case SyntaxKind.ThisType:
18101841
break;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [metadataOfStringLiteral.ts]
2+
function PropDeco(target: Object, propKey: string | symbol) { }
3+
4+
class Foo {
5+
@PropDeco
6+
public foo: "foo" | "bar";
7+
}
8+
9+
//// [metadataOfStringLiteral.js]
10+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
11+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
12+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
13+
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;
14+
return c > 3 && r && Object.defineProperty(target, key, r), r;
15+
};
16+
var __metadata = (this && this.__metadata) || function (k, v) {
17+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
18+
};
19+
function PropDeco(target, propKey) { }
20+
var Foo = (function () {
21+
function Foo() {
22+
}
23+
return Foo;
24+
}());
25+
__decorate([
26+
PropDeco,
27+
__metadata("design:type", String)
28+
], Foo.prototype, "foo");
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/metadataOfStringLiteral.ts ===
2+
function PropDeco(target: Object, propKey: string | symbol) { }
3+
>PropDeco : Symbol(PropDeco, Decl(metadataOfStringLiteral.ts, 0, 0))
4+
>target : Symbol(target, Decl(metadataOfStringLiteral.ts, 0, 18))
5+
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
6+
>propKey : Symbol(propKey, Decl(metadataOfStringLiteral.ts, 0, 33))
7+
8+
class Foo {
9+
>Foo : Symbol(Foo, Decl(metadataOfStringLiteral.ts, 0, 63))
10+
11+
@PropDeco
12+
>PropDeco : Symbol(PropDeco, Decl(metadataOfStringLiteral.ts, 0, 0))
13+
14+
public foo: "foo" | "bar";
15+
>foo : Symbol(Foo.foo, Decl(metadataOfStringLiteral.ts, 2, 11))
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/metadataOfStringLiteral.ts ===
2+
function PropDeco(target: Object, propKey: string | symbol) { }
3+
>PropDeco : (target: Object, propKey: string | symbol) => void
4+
>target : Object
5+
>Object : Object
6+
>propKey : string | symbol
7+
8+
class Foo {
9+
>Foo : Foo
10+
11+
@PropDeco
12+
>PropDeco : (target: Object, propKey: string | symbol) => void
13+
14+
public foo: "foo" | "bar";
15+
>foo : "foo" | "bar"
16+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
//// [metadataOfUnion.ts]
2+
function PropDeco(target: Object, propKey: string | symbol) { }
3+
4+
class A {
5+
}
6+
7+
class B {
8+
@PropDeco
9+
x: "foo" | A;
10+
11+
@PropDeco
12+
y: true | boolean;
13+
14+
@PropDeco
15+
z: "foo" | boolean;
16+
}
17+
18+
enum E {
19+
A,
20+
B,
21+
C,
22+
D
23+
}
24+
25+
class D {
26+
@PropDeco
27+
a: E.A;
28+
29+
@PropDeco
30+
b: E.B | E.C;
31+
32+
@PropDeco
33+
c: E;
34+
35+
@PropDeco
36+
d: E | number;
37+
}
38+
39+
//// [metadataOfUnion.js]
40+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
41+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
42+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
43+
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;
44+
return c > 3 && r && Object.defineProperty(target, key, r), r;
45+
};
46+
var __metadata = (this && this.__metadata) || function (k, v) {
47+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
48+
};
49+
function PropDeco(target, propKey) { }
50+
var A = (function () {
51+
function A() {
52+
}
53+
return A;
54+
}());
55+
var B = (function () {
56+
function B() {
57+
}
58+
return B;
59+
}());
60+
__decorate([
61+
PropDeco,
62+
__metadata("design:type", Object)
63+
], B.prototype, "x");
64+
__decorate([
65+
PropDeco,
66+
__metadata("design:type", Boolean)
67+
], B.prototype, "y");
68+
__decorate([
69+
PropDeco,
70+
__metadata("design:type", Object)
71+
], B.prototype, "z");
72+
var E;
73+
(function (E) {
74+
E[E["A"] = 0] = "A";
75+
E[E["B"] = 1] = "B";
76+
E[E["C"] = 2] = "C";
77+
E[E["D"] = 3] = "D";
78+
})(E || (E = {}));
79+
var D = (function () {
80+
function D() {
81+
}
82+
return D;
83+
}());
84+
__decorate([
85+
PropDeco,
86+
__metadata("design:type", Number)
87+
], D.prototype, "a");
88+
__decorate([
89+
PropDeco,
90+
__metadata("design:type", Number)
91+
], D.prototype, "b");
92+
__decorate([
93+
PropDeco,
94+
__metadata("design:type", Number)
95+
], D.prototype, "c");
96+
__decorate([
97+
PropDeco,
98+
__metadata("design:type", Number)
99+
], D.prototype, "d");
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
=== tests/cases/compiler/metadataOfUnion.ts ===
2+
function PropDeco(target: Object, propKey: string | symbol) { }
3+
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
4+
>target : Symbol(target, Decl(metadataOfUnion.ts, 0, 18))
5+
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
6+
>propKey : Symbol(propKey, Decl(metadataOfUnion.ts, 0, 33))
7+
8+
class A {
9+
>A : Symbol(A, Decl(metadataOfUnion.ts, 0, 63))
10+
}
11+
12+
class B {
13+
>B : Symbol(B, Decl(metadataOfUnion.ts, 3, 1))
14+
15+
@PropDeco
16+
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
17+
18+
x: "foo" | A;
19+
>x : Symbol(B.x, Decl(metadataOfUnion.ts, 5, 9))
20+
>A : Symbol(A, Decl(metadataOfUnion.ts, 0, 63))
21+
22+
@PropDeco
23+
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
24+
25+
y: true | boolean;
26+
>y : Symbol(B.y, Decl(metadataOfUnion.ts, 7, 17))
27+
28+
@PropDeco
29+
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
30+
31+
z: "foo" | boolean;
32+
>z : Symbol(B.z, Decl(metadataOfUnion.ts, 10, 22))
33+
}
34+
35+
enum E {
36+
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
37+
38+
A,
39+
>A : Symbol(E.A, Decl(metadataOfUnion.ts, 16, 8))
40+
41+
B,
42+
>B : Symbol(E.B, Decl(metadataOfUnion.ts, 17, 6))
43+
44+
C,
45+
>C : Symbol(E.C, Decl(metadataOfUnion.ts, 18, 6))
46+
47+
D
48+
>D : Symbol(E.D, Decl(metadataOfUnion.ts, 19, 6))
49+
}
50+
51+
class D {
52+
>D : Symbol(D, Decl(metadataOfUnion.ts, 21, 1))
53+
54+
@PropDeco
55+
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
56+
57+
a: E.A;
58+
>a : Symbol(D.a, Decl(metadataOfUnion.ts, 23, 9))
59+
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
60+
>A : Symbol(E.A, Decl(metadataOfUnion.ts, 16, 8))
61+
62+
@PropDeco
63+
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
64+
65+
b: E.B | E.C;
66+
>b : Symbol(D.b, Decl(metadataOfUnion.ts, 25, 11))
67+
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
68+
>B : Symbol(E.B, Decl(metadataOfUnion.ts, 17, 6))
69+
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
70+
>C : Symbol(E.C, Decl(metadataOfUnion.ts, 18, 6))
71+
72+
@PropDeco
73+
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
74+
75+
c: E;
76+
>c : Symbol(D.c, Decl(metadataOfUnion.ts, 28, 17))
77+
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
78+
79+
@PropDeco
80+
>PropDeco : Symbol(PropDeco, Decl(metadataOfUnion.ts, 0, 0))
81+
82+
d: E | number;
83+
>d : Symbol(D.d, Decl(metadataOfUnion.ts, 31, 9))
84+
>E : Symbol(E, Decl(metadataOfUnion.ts, 14, 1))
85+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
=== tests/cases/compiler/metadataOfUnion.ts ===
2+
function PropDeco(target: Object, propKey: string | symbol) { }
3+
>PropDeco : (target: Object, propKey: string | symbol) => void
4+
>target : Object
5+
>Object : Object
6+
>propKey : string | symbol
7+
8+
class A {
9+
>A : A
10+
}
11+
12+
class B {
13+
>B : B
14+
15+
@PropDeco
16+
>PropDeco : (target: Object, propKey: string | symbol) => void
17+
18+
x: "foo" | A;
19+
>x : A | "foo"
20+
>A : A
21+
22+
@PropDeco
23+
>PropDeco : (target: Object, propKey: string | symbol) => void
24+
25+
y: true | boolean;
26+
>y : boolean
27+
>true : true
28+
29+
@PropDeco
30+
>PropDeco : (target: Object, propKey: string | symbol) => void
31+
32+
z: "foo" | boolean;
33+
>z : boolean | "foo"
34+
}
35+
36+
enum E {
37+
>E : E
38+
39+
A,
40+
>A : E.A
41+
42+
B,
43+
>B : E.B
44+
45+
C,
46+
>C : E.C
47+
48+
D
49+
>D : E.D
50+
}
51+
52+
class D {
53+
>D : D
54+
55+
@PropDeco
56+
>PropDeco : (target: Object, propKey: string | symbol) => void
57+
58+
a: E.A;
59+
>a : E.A
60+
>E : any
61+
>A : E.A
62+
63+
@PropDeco
64+
>PropDeco : (target: Object, propKey: string | symbol) => void
65+
66+
b: E.B | E.C;
67+
>b : E.B | E.C
68+
>E : any
69+
>B : E.B
70+
>E : any
71+
>C : E.C
72+
73+
@PropDeco
74+
>PropDeco : (target: Object, propKey: string | symbol) => void
75+
76+
c: E;
77+
>c : E
78+
>E : E
79+
80+
@PropDeco
81+
>PropDeco : (target: Object, propKey: string | symbol) => void
82+
83+
d: E | number;
84+
>d : number | E
85+
>E : E
86+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// @experimentalDecorators: true
2+
// @emitDecoratorMetadata: true
3+
function PropDeco(target: Object, propKey: string | symbol) { }
4+
5+
class Foo {
6+
@PropDeco
7+
public foo: "foo" | "bar";
8+
}

0 commit comments

Comments
 (0)