Skip to content

+= on string | undefined should narrow its operand to string #20203

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

Open
mhchem opened this issue Nov 21, 2017 · 5 comments
Open

+= on string | undefined should narrow its operand to string #20203

mhchem opened this issue Nov 21, 2017 · 5 comments
Labels
Bug A bug in TypeScript
Milestone

Comments

@mhchem
Copy link

mhchem commented Nov 21, 2017

TypeScript Version: 2.6.1

Code

let a: string | undefined;
a = a + "a";
a; // string

let b: string | undefined;
b += "a";
b;  // should be string, but is still string | undefined

Expected behavior:
Both notations should be equivalend

@mhegazy
Copy link
Contributor

mhegazy commented Nov 22, 2017

we do not consider += / -= /today as narrowing operations.. moreover we explicitly allow + string on possibly undefined values to allow for debugging scenarios.. e.g. console.log("" + value). not sure why we allow +=..

@mhegazy mhegazy added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Nov 22, 2017
@mhchem
Copy link
Author

mhchem commented Nov 23, 2017

I don't mind how you treat this.
I have to admit that, undefined + "a" might be an common source for error (expecting "a", but getting "undefineda"). So not allowing this, might be a sensible solution.
But a = a + "a" and a += "a" must be treated 100% identical.

@RyanCavanaugh
Copy link
Member

We tried to talk about this but argued about implicit coercion for half an hour instead...

@kujon
Copy link
Contributor

kujon commented Apr 26, 2018

@RyanCavanaugh what was the outcome of this argument? I feel like, at least in strict mode, typescript should disallow type coercion altogether. As it stands right now, it's quite inconsistent with what it lets through, e.g.

const foo = 42 + {}; // Operator '+' cannot be applied to types '42' and '{}'.
const foo = '42' + {}; // fine
const foo = {} + []; // Operator '+' cannot be applied to types '{}' and 'never[]'.
const foo = `${{}}${[]}`; // fine

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript and removed In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels Jun 24, 2021
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Jun 24, 2021
@RyanCavanaugh RyanCavanaugh changed the title += (plus equal) operator not treated correctly += on string | undefined should narrow its operand to string Jun 24, 2021
@Rudxain
Copy link

Rudxain commented Mar 18, 2024

IMO, template literals are "explicit enough" to not be considered coercion. But + must only allow homogenous operands.

Recently, I noticed noUncheckedIndexedAccess wasn't causing this code to be an error:

const NAME = 'foobar'
let chars = ''
chars += NAME[Math.random() * 0x10 | 0]

because, string + undefined is "valid"

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

No branches or pull requests

5 participants