Skip to content

Inconsistency with boolean negation as void type guards with --strictNullChecks #33180

@timhwang21

Description

@timhwang21

TypeScript Version: [email protected]

Search Terms: void guard strictNullChecks boolean negation refinement

Code

// Toggle strictNullChecks off and see the type error appear
// on line 7, while 2nd fn never errors and 3rd always errors
const getMaybeStringLen = (maybeString: string | void) => {
  if (maybeString === null || maybeString === undefined) {
    return undefined;
  }
  return maybeString.length;
};

const getMaybeStringLenBoolNegation = (maybeString: string | void) => {
  if (!maybeString) {
    return undefined;
  }
  return maybeString.length;
};

const getMaybeStringLenBoolCoercionNegation = (maybeString: string | void) => {
  if (!Boolean(maybeString)) {
    return undefined;
  }
  return maybeString.length;
};

Expected behavior:

  • strictNullChecks: false behaves less strictly than strictNullChecks: true. Admittedly a loose criterion, but it seems like the stricter check fails with strictNullChecks: false and passes with strictNullChecks: true, while the type coercive check passes in both cases.

My confusion stems from the fact that ! is a valid type guard for void for both compiler flags, while checking against null and undefined is valid for strictNullChecks: true only.

As a bonus, while ! is always valid, !Boolean(x) is never valid.

Actual behavior:

  • getMaybeStringLen...
    • ...typechecks with strictNullChecks: true
    • ...does NOT typecheck with strictNullChecks: false
  • getMaybeStringLenBoolNegation...
    • ...typechecks with strictNullChecks: true
    • ...typechecks with strictNullChecks: false
  • getMaybeStringLenBoolCoercionNegation...
    • ...does NOT typecheck with strictNullChecks: true
    • ...does NOT typecheck with strictNullChecks: false

Playground Link: http://www.typescriptlang.org/play/#code/PTAEBUHsHNoGwKagM4BcBOBLAxqgcgK5xwDCAFgtgNbKiQBm9oAhgHYAmKCSqFoqATwAOSBOnSR0LISOboAUCDqtQcTKyQB2ADSgA7mUyJQAJg6h6KjQDcxoMRPS02nAMzpOzOHuYDaDyWR5bEhWNFBoBFQAWV8AIwQAZQx1aAAZBBUAXlAACgBbeKSU1mgALhQS6FAAH1BrSEx2AEpQLIA+UABveVBQTCYCouSsUrasnNYiOFq6woEEkdTxnIIOBHp1BBbu3r7QdCiCdBU19g2t9gBuPYBfPcPUY5V5xaqAOkRS3hvbm+DQuFIjFhlUMqwAEKQSBwPAIaDMVCYUJtPKvYqjcqVTG1eqNHYdXZ9AZ5ACE6KWpVaPX2ByOJ1AZwuGmudwe9JeoMxn0y0B+8j+8gBYVQESisQWGNS4KhMJIkDE2GRrDhCKRKJyQ0llKxaBxdQaTVahJp-UGpNliDYWremOa1L2fUez0Z602LJufXuTo5oApHy+fLIvxuQA

Related Issues: #1806, #8322, #10564

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions