Erik Johansson
Erik Johansson

Reputation: 389

How to make Typescript understand that value can't be null after function call that throws if value is null

I have a function that checks if a value is not null, that throws if the value is null. If it doesn't throw and returns successfully, i know that the value can't possibly be null.

Typescript doesn't seem to understand this without resorting to if cases. Is there any way to achieve this?

See the code below for clarification:

function ensureNotNull<T>(arg: T | null, paramName: string): arg is Exclude<typeof arg, null> {
    if (arg === null) {
        throw new Error(`arg '${paramName}' is null`);
    }

    return true;
}

var value: string | null = null;

function doStuffIfValueNotNull(value: string | null) : void {
    ensureNotNull<string>(value, "value");
    var strLen = value.length; //Error with strictNullChecks
}

Upvotes: 3

Views: 455

Answers (2)

Maxim Paperno
Maxim Paperno

Reputation: 4869

One way is to cast it to the expected type.

    ensureNotNull<string>(value, "value");
    var strLen = (value as string).length;

Or use the Non-null Assertion Operator Postfix !) (aka "magic punctuation" :-)

    ensureNotNull<string>(value, "value");
    var strLen = value!.length;

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075417

You could make ensureNotNull return the non-null and assign it back (changes marked with ***):

function ensureNotNull<T>(arg: T | null, paramName: string): T {
// *** ------------------------------------------------------^
    if (arg === null) {
        throw new Error(`arg '${paramName}' is null`);
    }

    return arg; // ***
}

var value: string | null = null;

function doStuffIfValueNotNull(value: string | null) : void {
    value = ensureNotNull<string>(value, "value");
//  ^^^^^^^^---- ***
    var strLen = value.length;
}

Alternately, if (but...blech, it suggests the method will return when in fact it will throw):

function doStuffIfValueNotNull(value: string | null) : void {
    if (!ensureNotNull<string>(value, "value")) return;
    var strLen = value.length; //Error with strictNullChecks
}

Upvotes: 5

Related Questions