MCPcopy Create free account
hub / github.com/microsoft/typescript-go / checkTestingKnownTruthyType

Method checkTestingKnownTruthyType

internal/checker/checker.go:3816–3874  ·  view source on GitHub ↗
(condExpr *ast.Node, condType *Type, body *ast.Node)

Source from the content-addressed store, hash-verified

3814}
3815
3816func (c *Checker) checkTestingKnownTruthyType(condExpr *ast.Node, condType *Type, body *ast.Node) {
3817 location := condExpr
3818 if ast.IsLogicalOrCoalescingBinaryExpression(condExpr) {
3819 location = ast.SkipParentheses(condExpr.AsBinaryExpression().Right)
3820 }
3821 if ast.IsModuleExportsAccessExpression(location) {
3822 return
3823 }
3824 if ast.IsLogicalOrCoalescingBinaryExpression(location) {
3825 c.checkTestingKnownTruthyTypes(location, condType, body)
3826 return
3827 }
3828 t := condType
3829 if location != condExpr {
3830 t = c.checkExpression(location)
3831 }
3832 if t.flags&TypeFlagsEnumLiteral != 0 && ast.IsPropertyAccessExpression(location) && core.OrElse(c.getResolvedSymbolOrNil(location.Expression()), c.unknownSymbol).Flags&ast.SymbolFlagsEnum != 0 {
3833 // EnumLiteral type at condition with known value is always truthy or always falsy, likely an error
3834 c.error(location, diagnostics.This_condition_will_always_return_0, core.IfElse(evaluator.IsTruthy(t.AsLiteralType().value), "true", "false"))
3835 return
3836 }
3837 isPropertyExpressionCast := ast.IsPropertyAccessExpression(location) && isTypeAssertion(location.Expression())
3838 if !c.hasTypeFacts(t, TypeFactsTruthy) || isPropertyExpressionCast {
3839 return
3840 }
3841 // While it technically should be invalid for any known-truthy value
3842 // to be tested, we de-scope to functions and Promises unreferenced in
3843 // the block as a heuristic to identify the most common bugs. There
3844 // are too many false positives for values sourced from type
3845 // definitions without strictNullChecks otherwise.
3846 callSignatures := c.getSignaturesOfType(t, SignatureKindCall)
3847 isPromise := c.getAwaitedTypeOfPromise(t) != nil
3848 if len(callSignatures) == 0 && !isPromise {
3849 return
3850 }
3851 var testedNode *ast.Node
3852 switch {
3853 case ast.IsIdentifier(location):
3854 testedNode = location
3855 case ast.IsPropertyAccessExpression(location):
3856 testedNode = location.Name()
3857 }
3858 var testedSymbol *ast.Symbol
3859 if testedNode != nil {
3860 testedSymbol = c.getSymbolAtLocation(testedNode, false)
3861 }
3862 if testedSymbol == nil && !isPromise {
3863 return
3864 }
3865 isUsed := testedSymbol != nil && ast.IsBinaryExpression(condExpr.Parent) && c.isSymbolUsedInBinaryExpressionChain(condExpr.Parent, testedSymbol) ||
3866 testedSymbol != nil && body != nil && c.isSymbolUsedInConditionBody(condExpr, body, testedNode, testedSymbol)
3867 if !isUsed {
3868 if isPromise {
3869 c.errorAndMaybeSuggestAwait(location, true, diagnostics.This_condition_will_always_return_true_since_this_0_is_always_defined, c.getTypeNameForErrorDisplay(t))
3870 } else {
3871 c.error(location, diagnostics.This_condition_will_always_return_true_since_this_function_is_always_defined_Did_you_mean_to_call_it_instead)
3872 }
3873 }

Callers 1

Calls 15

checkExpressionMethod · 0.95
errorMethod · 0.95
hasTypeFactsMethod · 0.95
getSignaturesOfTypeMethod · 0.95
getSymbolAtLocationMethod · 0.95

Tested by

no test coverage detected