62

Is there a way in typescript to create anonymous class?

my code:

export abstract class Runnable {
    public abstract run();
}

and I'm trying to do something like this:

new Runnable {
    runner() {
        //implement
    }
}

How can I do it?

3
  • @JaredSmith atrocities XD Commented Mar 13, 2017 at 15:14
  • 6
    Not so atrocity. If you want a callback with many different functions, what do you prefer? A) Send as many parameters to the function as the callback methods, or B) Encapsulate all the callbacks methods in a single software unit that gives it cohesion? Commented Oct 5, 2018 at 0:17
  • If you want a short way you can do: const myRunnable = <Runnable>{ run:() => { console.log("I ran"); } } But I think this is more like typecasting, not inheritance Commented Mar 27, 2023 at 11:40

4 Answers 4

102

Yes, here is the way.

The abstract class:

export abstract class Runnable {
  public abstract run();
}

An anonymous implementation:

const runnable = new class extends Runnable {
  run() {
    // implement here
  }
}();
Sign up to request clarification or add additional context in comments.

2 Comments

I had voted for this answer because this is the most compact form and truly assigns an anonymous class (without defining another named class).
This is the most to the point, correct answer.
26

Not quite, but you can do this:

abstract class Runnable {
    public abstract run();
}

let runnable = new (class MyRunnable extends Runnable {
    run() {
        console.log("running...");
    }
})();

runnable.run(); // running...

(code in playground)

The problem with this approach however is that the interpreter will evaluate the class every time it uses it, unlike with a compiled language (such as java) in which the compiler only evaluates it once.

1 Comment

Actually, just new class extends Runnable { /* bla bla bla */ } seems to work.
9

How to create Anonymous Class?

Let's say you have a interface Runnable and an abstract class Task.when you declare a class Foo in typescript you actual create an class instance of Foo & a constructor function for the class Foo.you could want to see depth in typescript.Anonymous class that ref as a constructor function like {new(...args):type} that can be created using new keyword.

interface Runnable {
    run(): void;
}

abstract class Task {
    constructor(readonly name: string) {
    }

    abstract run(): void;
}

Create anonymous class extends superclass via class extends ?

test('anonymous class extends superclass by `class extends ?`', () => {
    let stub = jest.fn();
    let AntTask: {new(name: string): Task} = class extends Task {
        //anonymous class auto inherit its superclass constructor if you don't declare a constructor here.
        run() {
            stub();
        }
    };

    let antTask: Task = new AntTask("ant");
    antTask.run();

    expect(stub).toHaveBeenCalled();
    expect(antTask instanceof Task).toBe(true);
    expect(antTask.name).toBe("ant");
});

create anonymous class implements interface/type via class ?.

test('anonymous class implements interface by `class ?`', () => {
    let stub = jest.fn();
    let TestRunner: {new(): Runnable} = class {
        run = stub
    };

    let runner: Runnable = new TestRunner();
    runner.run();

    expect(stub).toHaveBeenCalled();
});

1 Comment

Thanks for this detailed answer. I think you don't need : {new(name: string): Task} in your second example.
1

You just need to create an inline local class and immediately extend it.

interface Runnable {
    run();
}

// ...

const runnable = new (class ___Runnable implements Runnable {
    run() { /*...*/ }
});

/* parentheses are optional */

return new class ___Runnable implements Runnable {
    run() { /*...*/ }
}

/* do not worry, ___Runnable does not leak in to scope.
its scope is the hidden (extra) parentheses. */

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.