Repository navigation
Non-null type assertions shouldn't affect optional chaining #34875
Description
Activity
falsandtru commented
on Nov 2, 2019 ContributorAuthorMore actionsAnother case.
// b must be `ChildNode | 0` but actualy `ChildNode` const b = document.querySelector('_')?.firstChild! ?? 0;
Btw,
A new ! post-fix expression operator may be used to assert that its operand is non-null and non-undefined in contexts where the type checker is unable to conclude that fact. Specifically, the operation x! produces a value of the type of x with null and undefined excluded.
Reacted by Bruce Pascoe, Martin Johns, Jordi Oliveras Rovira, Ryan Cavanaugh and Daniel RosenwasserMemes aside, if the goal here is simply to remove the null possibility for
textContentonly, that's probably going to be difficult in general because!applies to the entire expression and the compiler can't distinguish betweenT | undefined | undefinedandT | undefined. By the time the compiler sees the!, the two levels of null possibility have already collapsed down to one.- addedWorking as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug
on Nov 4, 2019 RyanCavanaugh commented
on Nov 4, 2019 MemberMore actionsThis is the same as if you had written
const _a = document.querySelector('_')?.textContent; const a = _a!;
IOW
!applies to the entire operand expression, not just the property accessfalsandtru commented
on Nov 4, 2019 ContributorAuthorMore actionsCan't you notice the problem that there is no way to infer the actual type
string | nullfromdocument.querySelector('_')?.textContenteven when using!?!became useless with many cases using optional chaining.Optional chaining covers common use cases with terse expressions. If you really need to go deep detail about each part of your expression; if it's important for your use case to distinguish when
querySelectorreturnsundefinedvs whentextContentreturnsnull; then just break it out into separate statements and test each one.RyanCavanaugh commented
on Nov 5, 2019 MemberMore actionsfalsandtru (@falsandtru) you'll have to get a time machine and take it up with TC39 in 2017, I guess.
?.won't propagate anullvalue and TS represents thatReacted by AnyhowStepfalsandtru commented
on Nov 5, 2019 ContributorAuthorMore actionsRyan Cavanaugh (@RyanCavanaugh) Then I just replace
nullwithundefined. Anyway the essential problem is the same. When developers introduce optional chaining, currently TypeScript forces developers to explicitly write the expected type in some cases likedocument.querySelector('_')?.textContent as string | undefined.The question is TypeScript won't resolve the new problem that optional chaining sometimes makes type inference to be impossible to infer the actual type?
- locked as resolved and limited conversation to collaborators
on Oct 21, 2025

cc Anders Hejlsberg (@ahejlsberg)
TypeScript Version: 3.7.x-dev.20191101
Search Terms:
Code
Expected behavior:
Type of a is string | undefined.
Actual behavior:
Type of a is string.
This means
document.querySelector('_').textContent!is valid and these are the equivalent todocument.querySelector('_')!.textContent!.Playground Link: http://www.typescriptlang.org/play/?ts=3.8.0-dev.20191101&ssl=1&ssc=53&pln=2&pc=23#code/MYewdgzgLgBAhjAvDAJiYBXAtgUzFAOgEcMcAnATwGUcAbHYKEMgCgHIB9NgSgH4CoOAB5QAwuEH4AhAG4gA
Related Issues: