Skip to content

Commit fd059c5

Browse files
Merge pull request #172 from silbinarywolf/fix-typescript-varadic-dependency-injection
fix(dependency-injection): ignore ...rest TypeScript metadata
2 parents eea08a3 + dc756f4 commit fd059c5

File tree

2 files changed

+223
-0
lines changed

2 files changed

+223
-0
lines changed

src/injection.js

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ export function autoinject(potentialTarget?: any): any {
88
let deco = function(target) {
99
if (!target.hasOwnProperty('inject')) {
1010
target.inject = (metadata.getOwn(metadata.paramTypes, target) || _emptyParameters).slice();
11+
// TypeScript 3.0 metadata for "...rest" gives type "Object"
12+
// if last parameter is "Object", assume it's a ...rest and remove that metadata.
13+
if (target.inject.length > 0 &&
14+
target.inject[target.inject.length - 1] === Object) {
15+
target.inject.pop();
16+
}
1117
}
1218
};
1319

test/injection.spec.js

+217
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,223 @@ describe('injection', () => {
276276
expect(app2.logger).toEqual(jasmine.any(Logger));
277277
expect(app2.service).toEqual(jasmine.any(Service));
278278
});
279+
280+
it('test variadic arguments (TypeScript metadata)', function() {
281+
const container = new Container();
282+
const VariadicArg = Object; // TypeScript emits "Object" type for "...rest" param
283+
284+
class Dep$1 {}
285+
class Dep$2 {}
286+
class Dep$3 {}
287+
class Dep$4 {}
288+
class Dep$5 {}
289+
290+
const ParentOneDep = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$1])).on(
291+
class ParentOneDep {
292+
constructor(dep1: Dep$1) {
293+
this.dep1 = dep1;
294+
}
295+
}
296+
)
297+
298+
const ParentTwoDeps = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$1, Dep$2])).on(
299+
class ParentTwoDeps {
300+
constructor(dep1: Dep$1, dep2: Dep$2) {
301+
this.dep1 = dep1;
302+
this.dep2 = dep2;
303+
}
304+
}
305+
)
306+
307+
class ChildZeroDeps$1 extends ParentOneDep {}
308+
class ChildZeroDeps$2 extends ParentTwoDeps {}
309+
310+
const ChildOneDep$1 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$3, VariadicArg])).on(
311+
class ChildOneDep$1 extends ParentOneDep {
312+
constructor(dep3: Dep$3, ...rest) {
313+
super(...rest);
314+
this.dep3 = dep3;
315+
}
316+
}
317+
)
318+
{
319+
const a = container.get(ChildOneDep$1);
320+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
321+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
322+
}
323+
324+
const ChildOneDep$2 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$3, VariadicArg])).on(
325+
class ChildOneDep$2 extends ParentTwoDeps {
326+
constructor(dep3: Dep$3, ...rest) {
327+
super(...rest);
328+
this.dep3 = dep3;
329+
}
330+
}
331+
)
332+
{
333+
const a = container.get(ChildOneDep$2);
334+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
335+
expect(a.dep2).toEqual(jasmine.any(Dep$2));
336+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
337+
}
338+
339+
const ChildTwoDeps$1 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$3, Dep$4, VariadicArg])).on(
340+
class ChildTwoDeps$1 extends ParentOneDep {
341+
constructor(dep3: Dep$3, dep4: Dep$4, ...rest) {
342+
super(...rest);
343+
this.dep3 = dep3;
344+
this.dep4 = dep4;
345+
}
346+
}
347+
)
348+
const ChildTwoDeps$2 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$3, Dep$4, VariadicArg])).on(
349+
class ChildTwoDeps$2 extends ParentTwoDeps {
350+
constructor(dep3: Dep$3, dep4: Dep$4, ...rest) {
351+
super(...rest);
352+
this.dep3 = dep3;
353+
this.dep4 = dep4;
354+
}
355+
}
356+
)
357+
358+
class GrandChildZeroDeps$01 extends ChildZeroDeps$1 {}
359+
{
360+
const a = container.get(GrandChildZeroDeps$01);
361+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
362+
}
363+
364+
class GrandChildZeroDeps$02 extends ChildZeroDeps$2 {}
365+
{
366+
const a = container.get(GrandChildZeroDeps$02);
367+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
368+
expect(a.dep2).toEqual(jasmine.any(Dep$2));
369+
}
370+
371+
class GrandChildZeroDeps$11 extends ChildOneDep$1 {}
372+
{
373+
const a = container.get(GrandChildZeroDeps$11);
374+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
375+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
376+
}
377+
378+
class GrandChildZeroDeps$12 extends ChildOneDep$2 {}
379+
{
380+
const a = container.get(GrandChildZeroDeps$12);
381+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
382+
expect(a.dep2).toEqual(jasmine.any(Dep$2));
383+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
384+
}
385+
386+
class GrandChildZeroDeps$21 extends ChildTwoDeps$1 {}
387+
{
388+
const a = container.get(GrandChildZeroDeps$21);
389+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
390+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
391+
expect(a.dep4).toEqual(jasmine.any(Dep$4));
392+
}
393+
394+
class GrandChildZeroDeps$22 extends ChildTwoDeps$2 {}
395+
{
396+
const a = container.get(GrandChildZeroDeps$22);
397+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
398+
expect(a.dep2).toEqual(jasmine.any(Dep$2));
399+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
400+
expect(a.dep4).toEqual(jasmine.any(Dep$4));
401+
}
402+
403+
const GrandChildOneDep$01 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$5, VariadicArg])).on(
404+
class GrandChildOneDep$01 extends ChildZeroDeps$1 {
405+
constructor(dep5: Dep$5, ...rest) {
406+
super(...rest);
407+
this.dep5 = dep5;
408+
}
409+
}
410+
)
411+
{
412+
const a = container.get(GrandChildOneDep$01);
413+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
414+
expect(a.dep5).toEqual(jasmine.any(Dep$5));
415+
}
416+
417+
const GrandChildOneDep$02 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$5, VariadicArg])).on(
418+
class GrandChildOneDep$02 extends ChildZeroDeps$2 {
419+
constructor(dep5: Dep$5, ...rest) {
420+
super(...rest);
421+
this.dep5 = dep5;
422+
}
423+
}
424+
)
425+
{
426+
const a = container.get(GrandChildOneDep$02);
427+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
428+
expect(a.dep2).toEqual(jasmine.any(Dep$2));
429+
expect(a.dep5).toEqual(jasmine.any(Dep$5));
430+
}
431+
432+
const GrandChildOneDep$11 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$5, VariadicArg])).on(
433+
class GrandChildOneDep$11 extends ChildOneDep$1 {
434+
constructor(dep5: Dep$5, ...rest) {
435+
super(...rest);
436+
this.dep5 = dep5;
437+
}
438+
}
439+
)
440+
{
441+
const a = container.get(GrandChildOneDep$11);
442+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
443+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
444+
expect(a.dep5).toEqual(jasmine.any(Dep$5));
445+
}
446+
447+
const GrandChildOneDep$12 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$5, VariadicArg])).on(
448+
class GrandChildOneDep$12 extends ChildOneDep$2 {
449+
constructor(dep5: Dep$5, ...rest) {
450+
super(...rest);
451+
this.dep5 = dep5;
452+
}
453+
}
454+
)
455+
{
456+
const a = container.get(GrandChildOneDep$12);
457+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
458+
expect(a.dep2).toEqual(jasmine.any(Dep$2));
459+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
460+
expect(a.dep5).toEqual(jasmine.any(Dep$5));
461+
}
462+
463+
const GrandChildOneDep$21 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$5, VariadicArg])).on(
464+
class GrandChildOneDep$21 extends ChildTwoDeps$1 {
465+
constructor(dep5: Dep$5, ...rest) {
466+
super(...rest);
467+
this.dep5 = dep5;
468+
}
469+
}
470+
)
471+
{
472+
const a = container.get(GrandChildOneDep$21);
473+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
474+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
475+
expect(a.dep4).toEqual(jasmine.any(Dep$4));
476+
expect(a.dep5).toEqual(jasmine.any(Dep$5));
477+
}
478+
479+
const GrandChildOneDep$22 = decorators(autoinject(), Reflect.metadata('design:paramtypes', [Dep$5, VariadicArg])).on(
480+
class GrandChildOneDep$22 extends ChildTwoDeps$2 {
481+
constructor(dep5: Dep$5, ...rest) {
482+
super(...rest);
483+
this.dep5 = dep5;
484+
}
485+
}
486+
)
487+
{
488+
const a = container.get(GrandChildOneDep$22);
489+
expect(a.dep1).toEqual(jasmine.any(Dep$1));
490+
expect(a.dep2).toEqual(jasmine.any(Dep$2));
491+
expect(a.dep3).toEqual(jasmine.any(Dep$3));
492+
expect(a.dep4).toEqual(jasmine.any(Dep$4));
493+
expect(a.dep5).toEqual(jasmine.any(Dep$5));
494+
}
495+
});
279496
});
280497
});
281498

0 commit comments

Comments
 (0)