Description
π Search Terms
"just ! does not work as search", "I am not sure how ! is named in here"
β Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
β Suggestion
Apologies I flagged last two points because related links are all about TS ... well, this is about JS instead, or better, JSDoc TS flavor, and I don't know better to flag this issue but please allow me to explain:
const map = new Map<string,{count:number}>;
const key = 'any key';
if (!map.has(key))
map.set(key, {count: 0});
map.get(key).count++;
// ^^^^^^^^^
Error: Object is possibly 'undefined'.
Now, if I am a TS developer I could easily fix that, whenever I am sure the Map prototype is not poisoned in my env and everything is awesome, as such:
map.get(key)!.count++;
But as JS developer I really don't have many options ... because:
- the example is simple for this issue sake, using a
map.get(key)
instead of usingmap.has(key)
can't survive any falsy values, I want my map to be robust against all the odds - re-setting each time what I maybe got from
map.get
might break insertion order and it will definitely do more operations than needed, when the key was already known - even if I don't understand 100% reasons that is happening, I'd ove to tell JSDoc TS that such operation is fine and expected to return whatever that
map
reference returns
Proposal
I know I can force-cast stuff in JSDoc TS by using:
/** @type {{count:number}} */(map.get(key)).count++;
but you can see that wouldn't play well repeatedly and it's quite just a copy & paste boring exercise from a DX point of view, so how about a comment able to explicitly tell TS that such operation is the equivalent of a !
suffix?
/** @safe */(map.get(key))
could work/** @! */(map.get(key))
could work too, but I feel like it's a stretch over the@
notation/** @infer */(map.get(key))
could work too
As summary, is there any way make people in the JS world satisfy the !
equivalent expectation in TS? 'cause like I've recently posted, it easily brings JS developers to just use ?
instead, which is a slippery slope because while it works under TS parsing goals, it fully changes the semantic of the code where a !
does not change semantics, while ?
does and everything after that might be, or not, defined.
Thanks in advance for either pointing me at the already opened discussion or to consider such improvement for raw JS users, as that warning is more a curse than a help π
π Motivating Example
if JS folks using JSDoc TS are forced to simplify their troubles via ?
instead of the unavailable !
in ECMAScript syntax, more things can fail because a ?
passes TS checks but can fail at JS checks after or lazily out of the different runtime return value a ?
can provide once executed.
π» Use Cases
- What do you want to use this for? every time I am sure my map, WeakMap, arrary.at(...), or any similar case should never be ignored by me adding just an
?
as that's the meaning of that syntax: ignore - What shortcomings exist with current approaches? no idea
- What workarounds are you using in the meantime? many and this is super annoying from a JS developer perspective