1

I want to use certain static methods from another class in my code, but getting a weird error.

class Mouth {
  static greet() {
    console.log('Mouth.greet')
  }
}

class DogMouth extends Mouth {
  static greet() {
    console.log('DogMouth.woof')
  }
}

class Animal {
  mouth: Mouth
  constructor() {
    this.mouth = Mouth
  }

  greet() {
    this.mouth.greet()  // fails with Property 'greet' is a static member of type 'Mouth'
    Mouth.greet() // this works but should be the same thing?
    console.log('Animal.greet')
  }

}

class Dog extends Animal {

  constructor() {
    super()
    this.mouth = DogMouth
  }
}

function main() {
  const pup = new Dog()
  pup.greet()
}

main()

I created a typescript playground example here

So these are the problem lines, where this.mouth is defined to be the class Mouth collapsing the constructor etc code its the same as this:

    this.mouth = Mouth
    this.mouth.greet()  // fails with Property 'greet' is a static member of type 'Mouth'
    Mouth.greet() // this works but should be the same thing?

If this is confusing I'm wondering what better patterns I could use where I need certain methods to do different things based on the subclass. But ideally those methods are also available as static methods outside the subclass.

1
  • 1
    Mouth is the type of the instances. The class itself is typeof Mouth. i.e. you need to say: mouth: typeof Mouth Commented Oct 8, 2020 at 15:04

1 Answer 1

2

You declared your property to be an instance of Mouth

mouth: Mouth

... but static methods are not available on instances

Static methods aren't called on instances of the class. Instead, they're called on the class itself

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static

So the soultion is, to set the correct type or let TS do it for you:

class Animal {
  // TS will detect type from assignment
  mouth = Mouth;

  // Set type manually and assign
  // mouth: typeof Mouth = Mouth;

  // Set type only (and assign later)
  // mouth: typeof Mouth;

  // NOT WHAT YOU WANT (instance, static methods not available)
  // mouth: Mouth = new Mouth();

  greet() {
    this.mouth.greet()
    Mouth.greet()
    console.log('Animal.greet')
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

got it thanks! mouth: Mouth is a setup for an instance of Mouth, not the Mouth class itself. mouth = Mouth does the assignment and lets TS handle the types.
I've added some more comments to make it more obvious in code.

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.