Discussion on `--strictOptionalProperties`
See original GitHub issueWe’ve pulled in a new feature called --strictOptionalProperties
which sits under the --strict
family of flags. If we were to start TypeScript over again, we believe the behavior of strictOptionalProperties
would be on by default; however, this strictness option comes at a time when the community is much more mature with lots of existing code.
I’ve opened up this issue to discuss some broader concerns so that we can ensure that --strictOptionalProperties
ships smoothly and so we can hear some feedback from users.
Off the bat, here’s a few of my own concerns:
Discoverability of the Break
A user who upgrades TypeScript with --strict
on currently has no idea why their code has broken. At best, they will get an error like
Type 'T | U | V | undefined' is not assignable to type 'T | U | V'.
Type 'undefined' is not assignable to type 'T | U | V'.
We can do better here, which is why I’ve opened up https://github.com/microsoft/TypeScript/issues/44403.
Manual Upgrade Woes
The most permissive thing to do to fix breaks from --strictOptionalProperties
is to tack on an | undefined
onto every single ?
-marked optional property; however, this is incredibly tedious for an existing project.
We’d like to provide some automated tooling to help alleviate this, which is why I’ve opened up https://github.com/microsoft/TypeScript/issues/44419.
Surrounding Community Upgrade Woes
There are really 3 places that are outside most users’ control that need to be upgraded to work correctly with strictOptionalProperties
:
lib.d.ts
- DefinitelyTyped (
@types
packages) - Libraries shipping their own types
The last one is the hardest to solve; however, the first two are way more automatable, and we can have the core team help with it, but it’s definitely time taken away from other work, and that’s a delicate tradeoff.
I haven’t created an issue to manage this one, but I think it might be worth distributing segments of lib.d.ts
and some number of top packages to add | undefined
to the definitions and see if that helps. Ideally, automation from https://github.com/microsoft/TypeScript/issues/44419 could help. We’d also have to update the lib.dom.d.ts
generator to emit | undefined
on most optional properties.
I’d like to get @RyanCavanaugh’s thoughts on this one.
Other Feedback
I’m curious to hear feedback from users on this one - is it a useful option? Do you feel good about it and its purpose? Did it catch any interesting bugs? Let us know!
Issue Analytics
- State:
- Created 2 years ago
- Reactions:13
- Comments:31 (12 by maintainers)
We spoke about this at our last design meeting (#44524). We’ve decided:
--strict
. We believe the flag is too invasive, even for--strict
.noUncheckedIndexedAccess
). We believe that the flag still has utility.strict
would be misleading.lib.d.ts
, Definitely Typed).--init
once the ecosystem is ready.For context, if we’re looking at type system features, this was easily in the top 10 in terms of upvotes (it’s behind only typed exception clauses, parametric types, nominal types, exact types, spread types, type guard inference, and
internal
).I definitely hear the feedback, though – some codebases consistently disavow any difference between
{ }
and{ k: undefined }
. If that’s true in your codebase, turning this flag on is all pain and no gain.There are many APIs in JS that don’t work like this, though (including the spread operator
...
), and faithful typing of real JS API is our north star. I think it was truly a “missing” (ha) feature and the question is just how to get it out there in a way that isn’t too painful, even if “too painful” means “too much to toggle a flag in your tsconfig”.