jeudi 15 octobre 2020

Is it possible to automatically add tracing to private functions in a TypeScript namespace?

Is it somehow possible to loop over all functions (including private) of a TypeScript namespace (without exporting the private functions!), particularly while in the namespace ?

Example: Given

namespace Abraka.Dabra
{
    // 'use strict';
    function somethingPrivate()
    {
        return "42";
    }

    export function somethingPublic()
    {
        return somethingPrivate()*2;
    }


}

Now this transpiles to

var Abraka;
(function (Abraka_1) {
    var Dabra;
    (function (Dabra) {
        // 'use strict';

        function somethingPrivate()
        {
            return "42";
        }

        function somethingPublic() {
            return somethingPrivate()*2;
        }
        Dabra.somethingPublic = somethingPublic;



    })(Dabra = Abraka_1.Dabra || (Abraka_1.Dabra = {}));
})(Abraka || (Abraka = {}));

Now I have a function "autoTrace", which is defined as

private autoTrace(self: any): any

Example implementation in this answer here (works for classes).

What I want now, is to loop over all function in Abraka.Dabra, and say

object[functionName] = autoTrace(object[functionName])

I can do this with the exported functions, but I can't do this with the non-exported functions.

Is there any way to do this, without having to either export all private functions, too, and without having to manually add the logging ?

I was thinking along the lines of hooking into arguments.callee at the end of the namespace like

var Abraka;
(function (Abraka_1) {
    var Dabra;
    (function (Dabra) {
        // 'use strict';

        function somethingPrivate()
        {
            return "42";
        }

        function somethingPublic() {
            return somethingPrivate()*2;
        }
        Dabra.somethingPublic = somethingPublic;


        function addLogging(fn)
        {
             for (var functionName in fn) 
             {
                 console.log("functionName", functionName);
             }
        }

        addLogging(arguments.callee);

    })(Dabra = Abraka_1.Dabra || (Abraka_1.Dabra = {}));
})(Abraka || (Abraka = {}));

Abraka.Dabra.somethingPublic()

but that doesn't even work in non-strict mode...

Note:
I cannot alter the transpiler output, so the construction

var Abraka;
(function (Abraka_1) {
    var Dabra;
    (function (Dabra) {
        // 'use strict';
        [...]
    })(Dabra = Abraka_1.Dabra || (Abraka_1.Dabra = {}));
})(Abraka || (Abraka = {}));

is fixed, and you can't make the anonymous function a named function.

Edit:
Apparently, one way is this:

namespace Abraka.Dabra
{
    'use strict';

    class cSelf
    {
        // add constructor and add autotrace there 

        private somethingPrivate()
        {
            return "42";
        }

        public somethingPublic() {
            return somethingPrivate()*2;
        }
    }

    (<any>Dabra) = new cSelf();
}

But this is not exactly good, as this overrides the namespace, instead of extending a possibly existing object.





Aucun commentaire:

Enregistrer un commentaire