3

I have the following class declared:

class MyClass {
 private myValue!: string

 constructor(){
   this.mySettingFunction()
 }

 public mySettingFunction(){
   // do stuff
   this.myValue = 'something'
 }
}

In this class, I'm using the definite assignment assertion(!) on myValue to tell typescript that the value will be initialized despite it not being able to "understand" it.

However, I was guessing, is there a way to tell typescript that mySettingFunction will initialize myValue? (Like an annotation or something similar that allows me to remove the ! from myValue)

7
  • why not initialize it in constructor straight away? Commented Sep 1, 2022 at 12:59
  • 1
    @deaponn Because I don't want to duplicate the code. Otherwise, I would need to keep consistent the constructor and mySettingFunction. Commented Sep 1, 2022 at 13:00
  • Does this answer your question? Typescript: How to initialise a class property outside constructor Commented Sep 1, 2022 at 13:16
  • @Blackhole nope. It gives some alternatives to my solution, but it doesn't give a way to tell typescript "Hey, this function initializes the field" Commented Sep 1, 2022 at 13:36
  • 1
    There is no way to do this, it's considered a design limitation as per ms/TS#21132 that the compiler can't track this sort of thing, and other issues are closed as duplicates of this one without any kind of alternative (except for the definite assignment assertion). So the answer here is just "no". I can write this up as an answer (I think ms/TS#21132 is the closest thing to an authoritative response) but I see there are other answers here already. Still, if you want to see it, let me know (and @jcalz mention me or I won't be alerted) Commented Sep 1, 2022 at 13:40

2 Answers 2

1

What about these two options?

1.

class MyClass {
 private myValue: string | undefined = undefined;

 constructor(){
   this.mySettingFunction();
 }

 public mySettingFunction(){
   // do stuff
   this.myValue = 'something';
 }
}
class MyClass {
 private myValue = '';

 constructor(){
   this.mySettingFunction()
 }

 public mySettingFunction(){
   // do stuff
   this.myValue = 'something'
 }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I didn't want to assign a default value since the assignment would happen twice, and undefined is not true since the value will be defined
1

I think there are only 2 ways of doing it.

One is that you already mentioned with Definite assignment assertion and the second is to change the TS config and set noImplicitAny to false.

But if the assignment is not happening in the constructor explicitly or the property does not have a default value it will always complain.

If the whole point of this question is to avoid duplication of properties in the class body and in the constructor you can try passing access modifiers directly inside constructor parameters

class MyClass {
  constructor(private foo: string, private bar: string){}
}

This is the equivalent of the code below

class MyClass {
  private foo: string;
  private bar: string;

  constructor(foo: string, bar: string){
    this.foo = foo;
    this.bar = bar;
  }
}

1 Comment

Thanks for the info. So we don't have some assertion that we can do on the function. Guess the definite assignment is still the cleanest way

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.