Jiří Lechner
Jiří Lechner

Reputation: 820

How to declare literal object with interface?

I would like to define a literal object that implements an interface. So I wrote something like this

interface MyInterface {
  update: () => void;
}

class MyClass {
  a: MyInterface = {
    update: function(){},
    func2: function(){}
  }
}

But this gives me an error that type of a is not assignable to MyInterface. Is there a way how to say a only implements the interface?

Upvotes: 2

Views: 674

Answers (3)

ccarton
ccarton

Reputation: 3666

There isn't a syntax to declare that an object literal extends an interface. It is generally not needed. If a implements the update() function properly then Typescript will recognise that it extends MyInterface and you can use it as such, even though it isn't tagged.

If you just want this for code documentation purposes the best solution is to explicitly define a new type for a which extends MyInterface and define the additional properties. However, if you really want Typescript to enforce that an object literal extends MyInterface at the point of definition, then there is a workaround. You can use a generic function to assert the interface constraint. Something like this:

interface MyInterface {
  update: () => void;
}

const inferAs = <U,>() => <T extends U>(v:T) => v

class MyClass {
  a = inferAs<MyInterface>()({
    update: function(){},
    func2: function(){}
  })
}

That is the closest you can get to what you are asking for.

Upvotes: 4

Christian
Christian

Reputation: 7852

No. You need to comply to the interface in the implementation of it.

You may combine interfaces in your declaration of the variable a like so:

interface OtherInterfaceDeclaringFunc2 {
  func2: () => void;
}

...

  a: MyInterface & OtherInterfaceDeclaringFunc2 = {
    update: function(){},
    func2: function(){}
  }

Upvotes: 0

Martin
Martin

Reputation: 2273

Of course a is not assignable to MyInterface because MyInterface states that is has a update function, and not an update and a func2 fuction.

You either have to remove func2 from the a declaration, or add func2 to MyInterface

So both of the following will work:

interface MyInterface {
  update: () => void;
}

class MyClass {
  a: MyInterface = {
    update: function(){},
  }
}
interface MyInterface {
  update: () => void;
  func2: () => void;
}

class MyClass {
  a: MyInterface = {
    update: function(){},
    func2: function(){}
  }
}

Upvotes: 0

Related Questions