3

So I have the following code:

class A {
  constructor(private num: number = 1) {

  }

  private changeNum() {
    this.num = Math.random();
  }

  private fn() {
    if(this.num == 1) {
      this.changeNum();
      if(this.num == 0.5) {
        // do stuff
      }
    }
  }
}

It is a class, which has a property num and a function changeNum that changes that number.

Then, it also has another function fn which firstly checks whether num is equal to 1 and if so, changes num through changeNum and checks it again.

The problem is that Typescript does not detect that num was changed through changeNum and throws the following error:

This condition will always return 'false' since the types '1' and '0.5' have no overlap.

Is there a way to get Typescript to recognize that num was changed through changeNum?

EDIT: One thing that I found is that changing if(this.num == 0.5) to if(this.num == Number(0.5)) makes the program compile correctly but that certainly doesn't seem like a good solution!

1 Answer 1

5

This is a know issue with the control flow analysis.

The primary question is: When a function is invoked, what should we assume its side effects are?

One option is to be pessimistic and reset all narrowings, assuming that any function might mutate any object it could possibly get its hands on. Another option is to be optimistic and assume the function doesn't modify any state. Both of these seem to be bad. (Emphasis added)

https://github.com/Microsoft/TypeScript/issues/9998

TypeScript is taking the optimistic approach and assuming that the function only modifies its own state. That suggests a workaround: do not mutate external state in a function or method. For instance, you could rewrite your demo like this:

class A {
  constructor(private num: number = 1) { }

  private getNewNum() {
    return Math.random();
  }

  private fn() {
    if (this.num === 1) {
      this.num = this.getNewNum();
      if (this.num === 0.5) {
        // do stuff
      }
    }
  }
}

The upshot of this is that your program will take a more functional approach.

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

2 Comments

GetNewNum() is not a pure function. It will return different results when called with the same parameters. There was a question about random functions being not pure in stackoverflow.
This approach is good but it is not working with "Array.length" as you cannot modify it like that.

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.