0

Let's say we have an enum, "Profession":

enum Profession {
  Teacher = "Teacher",
  Scientist = "Scientist",
  Rapper = "Rapper",
}

And we have a Person interface, which accepts a generic drawn from Profession's values:

interface Person<P extends Profession> {
  profession: P;
}

And finally, we want to implement Person:

class AmericanCitizen implements Person<Profession.Teacher> {
  // ... problem continued below
}

... within the class implementation, I'd like to assign the generic-specified profession like so:

class AmericanCitizen implements Person<Profession.Teacher> {
  profession = Profession.Teacher;
}

This results in the following TS error:

Property 'profession' in type 'AmericanCitizen' is not assignable to the same property in base type 'Person<Profession.Teacher>'.
  Type 'Profession' is not assignable to type 'Profession.Teacher'.

Playground Link

The compiler forces me to do the long-hand equivalent:

class AmericanCitizen implements Person<Profession.Teacher> {
  profession: Profession.Teacher;

  constructor() {
    this.profession = Profession.Teacher;
  }
}

Playground Link

Why is it that the former is invalid?

1
  • Doing profession = Profession.Teacher as Profession.Teacher works for some reason as well (playground). Commented Mar 15, 2020 at 3:14

1 Answer 1

1
class AmericanCitizen implements Person<Profession.Teacher> {
  profession = Profession.Teacher;
}

Since you haven't told typescript what type you want profession to be, typescript will try to infer it from how you're using it. It sees you're assigning Profession.Teacher to it, which is part of an enum so it assumes you want profession to be that enum. Not a specific value of the enum though; the whole thing. Similarly if you tried to define name = "bob" it would assume you wanted string as the type, not specifically "bob", and age = 100 would be number, not specifically 100.

You can tell typescript that you want something more specific in several ways:

profession: Profession.Teacher = Profession.Teacher;
profession = Profession.Teacher as Profession.Teacher;
profession = Profession.Teacher as const;

Your version with a constructor works too and is equivalent to my first example.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the fast & high quality response!

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.