Search code examples
typescriptjsweet

Can I write a cast operator in Typescript?


I've used JSWEET to transpile a large Java project. It has converted types like Enumeration<Object> directly to Enumeration<any> in TypeScript.

In the Java world it was possible to assign an array Object[] to an Enumeration<Object>.

In Typescript I get: Type 'any[]' is not assignable to type 'Enumeration<any>'

Is there a way to extend Enumeration<Object> OR any[] in such a way that TypeScript will allow this assignment to occur?


Solution

  • You can cast in two different ways:

    var doSomething = function <T>(a: Enumeration<T>) { };
    var x: Object[] = [];
    
    // cast using "<>""
    doSomething(<Enumeration<Object>>x);
    
    // cast using "as"
    doSomething(x as Enumeration<Object>);
    

    But your Enumeration should probably extend Array:

    interface Enumeration<T> extends Array<T> {
        // ...
    }
    

    Update

    class Enumeration<T> extends Array<T> {
        private _cursor: number;
        public constructor(...elements: T[]) {
            super(...elements);
            this._cursor = 0;
        }
        public nextElement() {
            this._cursor = this._cursor + 1;
            return this.values[this._cursor];
        };
        public hasMoreElements() {
            return this._cursor < this.length - 1;
        }
        public static fromArray<T>(arr: T[]) {
            return new Enumeration<T>(...arr);
        }
    }
    
    interface User {
        name: string;
    }
    
    let a: Array<User> = [{ name: "user1" }, { name: "user2" }];
    let b: Enumeration<User> = new Enumeration({ name: "user1" }, { name: "user2" });
    
    a = b; // OK: Enumeration<User> is assignable to Array<User>
    b = a; // Error: Array<User> is not assignable to Enumeration<User>
    

    Maybe you can add a method fromArray to the enumeration class:

    var doSomething = function <T>(a: Enumeration<T>) { };
    doSomething(Enumeration.fromArray<User>(a));