Skip to content

weird behavior of TypeScript on assignment operators #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hanwenguo opened this issue Nov 13, 2024 · 4 comments
Closed

weird behavior of TypeScript on assignment operators #9

hanwenguo opened this issue Nov 13, 2024 · 4 comments

Comments

@hanwenguo
Copy link
Contributor

Look at the following code:

function works(param: string | number): string {
  param = param + "a";
  return param; // accepted by type checker, because 'param' is narrowed to 'string'
}

function shouldAlsoWorkButDoesNot(param: string | number): string {
  param += "a";
  return param; // type error because 'param' is _not_ narrowed to 'string'
}

function worksToo(x: unknown): string {
  if (typeof x === "string") {
    x += "str";
    return x; // accepted by type checker, because 'x' is narrowed to 'string'
  } else {
    return "";
  }
}

function shouldAlsoWorkButDoesNotEither(x: unknown): string {
  if (typeof x === "string") {
    x = x + "hello"; // 'x' in rhs is 'string', 'x' in lhs is 'unknown'
    return x; // type error because 'x' is _reset_ to 'unknown'
  } else {
    return "";
  }
}

Summary:

  • assignment operators like += behaves differently from their expanded equivalent like x = x + ... on type narrowing, though they should be equivalent (at least for the given examples)
  • the behavior of each of these two kinds of assignments, even if we forget that they should be equivalent, are inconsistent by themselves, i.e. same kind of assignment behaves differently in different contexts.

Part of the code is taken from this issue.

Maybe we should open an issue at TypeScript's repo.

@bennn
Copy link
Member

bennn commented Nov 13, 2024

Sure, check for duplicate issues and then open one.

I wonder if + can be overridden. Or maybe it has more complicated semantics (with implicit coercions) than +=.

@hanwenguo
Copy link
Contributor Author

I wonder if + can be overridden.

Seems not possible for TypeScript.

maybe it has more complicated semantics

According to ECMA, at least for the example code above, their semantics should be equivalent. The difference is mostly about pattern matching (e.g. [a, b] = [1, 2] or when rhs is an anonymous function (not relevant to this issue).

@hanwenguo
Copy link
Contributor Author

Issue opened: microsoft/TypeScript#60520 and microsoft/TypeScript#60521. Actually, I realized that they are two separate issues, because the last two function in the code example is not about operators performing narrowing, rather x = x + ... resets the already narrowed type.

@hanwenguo
Copy link
Contributor Author

hanwenguo commented Nov 16, 2024

Good news: maintainer quickly noticed they are duplicate-ish issues
Bad news: the original issues proposed is either closed without response or left open without further explanation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants