Nullish coalescing should always include the type of the right operand
See original GitHub issue$ ./node_modules/.bin/tsc --version
Version 3.7.2
Search Terms:
Code
A toy example would be something like this.
let foo: string = "";
foo = "bar" ?? 123;
This one is obviously fine since "bar"
is always truthy.
However, this becomes a little bit problematic when you consider the idiom of having Record
objects and checking their truthiness before using them.
const elts = ["foo", "bar", "spam", "spam", "foo", "eggs"];
const counts: Record<string, number>;
for (const elt of elts) {
// This really **should** raise an error.
counts[elt] = counts[elt] ?? "zero";
counts[elt] += 1;
}
Expected behavior: An error should be raised.
Actual behavior: Curiously, an error is not raised in strict mode but is raised in un-strict mode.
$ ./node_modules/.bin/tsc ./foo.ts
foo.ts:5:3 - error TS2322: Type 'number | "zero"' is not assignable to type 'number'.
Type '"zero"' is not assignable to type 'number'.
5 counts[elt] = counts[elt] ?? "zero";
~~~~~~~~~~~
Found 1 error.
$ ./node_modules/.bin/tsc --strict ./foo.ts
# No error, exits 0 and emits JS.
Playground Link: Playground Link
Toggling the strictNullChecks
config option will show the issue.
Related Issues:
Issue Analytics
- State:
- Created 4 years ago
- Reactions:3
- Comments:5 (2 by maintainers)
Top Results From Across the Web
Nullish coalescing operator '??' - The Modern JavaScript Tutorial
The nullish coalescing operator ?? provides a short way to choose the first “defined” value from a list. It's used to assign default...
Read more >Nullish coalescing operator (??) - JavaScript - MDN Web Docs
The nullish coalescing (??) operator is a logical operator that returns its right-hand side operand when its left-hand side operand is null ...
Read more >Nullish Coalescing Operator (??) In JavaScript - What Is It And ...
According to MDN, the nullish coalescing is "a logical operator that returns its right-hand side operand when its left-hand side operand is ...
Read more >The Ultimate Guide to the ES2020 Nullish Coalescing Operator
If the left-hand operand of the && operator evaluates to false , the JavaScript interpreter is smart enough to know that the result...
Read more >Optional chaining and nullish coalescing in TypeScript
TypeScript's type system defines two very special types, null and undefined , to represent the values null and undefined , respectively. However ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
This is probably related to or a duplicate of #13778.
With
--strictNullChecks
on, the compiler assumes thatcounts[elt]
must be of typenumber
, which is nevernull
orundefined
. If you want the compiler to notice thatcounts[elt]
may beundefined
, then you (currently) need to includeundefined
in the property type manually:Playground
With
--strictNullChecks
off, the compiler never assumes nullish coalescing will short-circuit because it can never eliminatenull
andundefined
. See this comment from the PRI respectfully disagree (obviously - I created the issue 😉). Using too-loose
Record
types is a common idiom in TypeScript, and I think changing this behavior makes that idiom easier to work with.