Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I create a class [] operator in Typescript

Is there a way to override the [] operation in typescript? We use 1.4 so we're fine with a solution that requires 1.4.

Update: I was horribly unclear in my initial question. What I meant was can I add that as an operator to a class. In my class I presently have a method:

public get(index : number) : LinkedListNode<t> {

    if (this._first === null || (index >= this._count)) {
        return null;
    }
    var node = this._first;
    while (index-- > 0) {
        node = node._next;
    }
    return node;
}

I would prefer to be able to call data[5] instead of data.get(5).

Is there a way to do this?

thanks & sorry for the incredibly inaccurate initial question.

like image 466
David Thielen Avatar asked Apr 14 '15 15:04

David Thielen


People also ask

What is ?: In TypeScript?

What does ?: mean in TypeScript? Using a question mark followed by a colon ( ?: ) means a property is optional. That said, a property can either have a value based on the type defined or its value can be undefined .

How do I create an instance of a class in TypeScript?

You can do this by using the new keyword, followed by a syntax similar to that of an arrow function, where the parameter list contains the parameters expected by the constructor and the return type is the class instance this constructor returns. The TypeScript compiler now will correctly compile your code.

Should you use classes in TypeScript?

When should we use classes and interfaces? If you want to create and pass a type-checked class object, you should use TypeScript classes. If you need to work without creating an object, an interface is best for you.


1 Answers

Update

In response to your update to your question, no it's not possible to overload the index operator for a class—you can't do data[5] instead of data.get(5).

In my opinion, the reason this has not been implemented is because JavaScript allows accessing an object's properties using brackets and that creates some ambiguity. For example, if data.myProperty is a property that exists and data['myProperty'] is called, then it would be difficult to decide if it should return the myProperty property or if the string 'myProperty' should be passed to the index overload.

Original Answer

It's not possible to change the result of:

var a = [];

Imagine the problems that could occur if people were allowed to change that behaviour? Library A could define it one way and then Library B could overwrite that with its own behaviour... meaning Library B now uses Library A's [] behaviour.

What you can do is add methods to Array's prototype:

interface Array {
    log: () => void;
}

Array.prototype.log = function() {
    console.log(JSON.stringify(this));
};

Then use:

var a = [];
a.log();

However, doing this is extremely not recommended! You shouldn't be modifying objects you don't own because it can lead to unforeseen problems. The reason not to do this is similar to why changing []'s behaviour would lead to problems:

  1. Library A defines a log method.
  2. Library B defines a log method that works differently.
  3. Now the log method for Library A won't work as expected because it's using Library B's method.

Recommendation

I would suggest creating your own implementation of array:

class MyArray<T> implements Array<T> {
    private _underlyingArray : Array<T> = [];

    // implement methods for Array here

    log() {
        console.log(JSON.stringify(this._underlyingArray));
    }
}

Or create a helper class:

class ArrayHelper {
    static log<T>(a: Array<T>) {
        console.log(JSON.stringify(a));
    }
}
like image 63
David Sherret Avatar answered Oct 20 '22 17:10

David Sherret