Home > database >  TS: Non-null assertions are not done at runtime?
TS: Non-null assertions are not done at runtime?

Time:11-10

I am JS developer and new to TS. If I have the following line of code:

  let corners = Boolean(checkTypes[userAccess]);

if I change it to this:

  let corners = Boolean(checkTypes![userAccess]);

why is that frowned upon? I had a comment saying non null assertions are not a runtime check so when would they happen?

CodePudding user response:

Non-null assertions are not done at runtime?

Correct, the JavaScript code will be just:

let corners = Boolean(checkTypes[userAccess]);

...and as a result, if checkTypes is nullish, that code will throw.

so when would they happen?

They won't, unless you code them. Type assertions are just that: assertions. You're promising TypeScript that you know that the assertion is true. TypeScript doesn't insert code to check that you're right. You've asserted that you are right.

Some options for you:

  1. If you want a checked assertion, you can write an assertion function (sadly not yet documented in the handbook):

    function assertIsNotNullish<T>(
        value: T | null | undefined,
        message?: string,
    ): asserts value is T {
        if (value == null) { // Which checks both `null` and `undefined`
            throw new Error(message ?? `Expected non-nullish value`);
        }
    }
    

    Then your code would be:

    assertIsNotNullish(checkTypes, "checkTypes was unexpectedly nullish");
    let corners = Boolean(checkTypes[userAccess]); // No assertion needed
    
  2. Optional chaining and nullish coalescing (both now JavaScript features):

    // Assuming you want `false` if `checkTypes` is nullish
    let corners = Boolean(checkTypes?.[userAccess] ?? false);
    //                              ^^            ^^^^^^^^^^
    
  3. You could have a type predicate:

    function isNotNullish<T>(value: T | null | undefined): value is T {
        return value != null; // Which checks both `null` and `undefined`
    }
    

    and then

    let corners = isNotNullish(checkTypes)
        ? Boolean(checkTypes[userAccess])
        : false; // Or `true` if that should be the default
    
  • Related