Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method alias with TypeScript

I assume this is the easiest way to implement a method alias with TS:

export class Foo {

 bar(){

 }

 aliasOfBar(){
   return this.bar.apply(this, arguments);
 }

}

but I am simply wondering if there is another way we can define an alias with TS (or JS). Perhaps ideally without an extra function call.

If I do this, for example:

let mySharedFn = function () {

};

export class Foo {
  public bar = mySharedFn
  public aliasBar = mySharedFn
}

it transpiles to this:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var mySharedFn = function () {
};
var Foo = (function () {
    function Foo() {
        this.bar = mySharedFn;
        this.aliasBar = mySharedFn;
    }
    return Foo;
}());
exports.Foo = Foo;

I'd like to avoid those extra calls that come with using the constructor to create the methods, etc.

like image 327
Alexander Mills Avatar asked Dec 05 '17 06:12

Alexander Mills


2 Answers

You can add the alias method to the class using an interface and the prototype, like this:

class Person {
    constructor(public name: string) {}
    greet(greeting: string): string { return `${greeting}, ${this.name}`; }
}

interface Person {
    hi: typeof Person.prototype.greet;
}
Person.prototype.hi = Person.prototype.greet;

const p = new Person("Alice");
console.log(p.greet("Hey"));
console.log(p.hi("Hi"));
like image 150
cartant Avatar answered Oct 09 '22 17:10

cartant


Maybe something with bind or with a reference:

export class Foo {
    public bar() {}
    public aliasBar = this.bar.bind(this);
    public aliasGreetSecond;
    constructor() {
        this.aliasGreetSecond = this.bar;
    }
}

the above will transpile to:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Foo = (function () {
    function Foo() {
        this.aliasBar = this.bar.bind(this);
        this.aliasGreetSecond = this.bar;
    }
    Foo.prototype.bar = function () { };
    return Foo;
}());
exports.Foo = Foo;

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Test this in TypeScript playground: https://www.typescriptlang.org/play/

class Greeter {
    greeting: string;
    aliasGreetSecond;

    constructor(message: string) {
        this.greeting = message;
        this.aliasGreetSecond = this.greet;
    }
    greet() {
        return "Hello, " + this.greeting;
    }

    aliasGreet = this.greet.bind(this);
}

let greeter = new Greeter("world");

let button = document.createElement('button');
let button2 = document.createElement('button');
button.textContent = "With bind";
button.onclick = function() {
    alert(greeter.aliasGreet());
}

 button2.textContent = "With reference";
 button2.onclick = function() {
    alert(greeter.aliasGreetSecond());
}

document.body.appendChild(button);
document.body.appendChild(button2);

Which will transpile into:

var Greeter = /** @class */ (function () {
    function Greeter(message) {
        this.aliasGreet = this.greet.bind(this);
        this.greeting = message;
        this.aliasGreetSecond = this.greet;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
}());
var greeter = new Greeter("world");
var button = document.createElement('button');
var button2 = document.createElement('button');
button.textContent = "With bind";
button.onclick = function () {
    alert(greeter.aliasGreet());
};
button2.textContent = "With reference";
button2.onclick = function () {
    alert(greeter.aliasGreetSecond());
};
document.body.appendChild(button);
document.body.appendChild(button2);
like image 37
Stefan Rein Avatar answered Oct 09 '22 15:10

Stefan Rein