MichaelAttard
MichaelAttard

Reputation: 2158

Typescript classes that are functions but also have properties

Is it possible to implement the following interface:

export interface Foo {
    (): void;

    bar: number;
}

Using classes?

This is the closest thing I could figure out:

var foo = function () { } as Foo;

foo.bar = 5;

Upvotes: 2

Views: 87

Answers (3)

Alex
Alex

Reputation: 14503

You can not have a class do this, but you can use type aliases and intersection types to do something like this:

// Define the type of your objects
type Foo = { (): void } & { bar: number };

// You could have a factory method to create instances
var fooFactoryMethod = (func: () => void, bar: number) => {
  var foo = func as Foo;
  foo.bar = bar;
  return foo;
}   

var myObject = fooFactoryMethod(() => { console.log("Hello world") }, 23)

// Or just creating them manually
var myObject2 = (() => { console.log("Hello world") }) as Foo;
myObject2.bar = 45;

// Now you can use it like this
var func = (arg: Foo) => {
  arg();
  arg.bar = 34;
}
func(myObject)

Playground

Upvotes: 1

Brian Herbert
Brian Herbert

Reputation: 1191

All classes are functions when they get compiled into js.

export class FooClass implements Foo {
    bar: number;

    constructor() {
        this.bar = 1;
    }

}

Upvotes: 0

Zoltán Tamási
Zoltán Tamási

Reputation: 12754

Although I'm not completely sure, I think this is not possible using classes without some serious hacks. I think this interface syntax is actually for supporting external library typings, where in many cases such constructions exist.

What you actually refer to in your sample code, is static members of a class. I mean a class with a public constructor and some static members is exactly this construction. But static members cannot be declared in interfaces (obviously).

Upvotes: 1

Related Questions