2

This might seem like an odd question at first, but I'll try to explain it the best I can.

Let's take a look at this following (and non-realistic) example:

const foo = (x: number) => {
    return x * x;
}

const isXUndefined = (x?: number) => x === undefined;

const boo = (x?: number) => {
    if (isXUndefined(x)) {
        return 0;
    }

    return foo(x);
}

As expected, this code fails compiling since x can be both number and undefined. What I struggle to see here - is why invoking isXUndefined isn't enough for the type inferrer to assure that x is an actual number?

A working example on the other hand would be:

const foo = (x: number) => {
    return x * x;
}

const isXUndefined = (x?: number) => x === undefined;

const boo = (x?: number) => {
    if (x === undefined) {
        return 0;
    }

    return foo(x);
}

Why is this validation only working when making it "on the surface" but not from within another function?

Here's a playground with both examples

0

3 Answers 3

3

You can solve this by doing the following

const foo = (x: number) => {
    console.log("foo")
    return x * x;
}

const isXUndefined = (x?: number) => x === undefined;

const boo = (x?: number) => {
    if (isXUndefined(x)) {
        return 0;
    }

    return foo(x!);
}

By adding the !, you're telling the compiler that x won't be null or undefined here, and it won't complain.

JSFiddle: https://jsfiddle.net/nrd7hmkp/

Sign up to request clarification or add additional context in comments.

1 Comment

i don't think this should be an answer, the question is "Why compiler can't figure out X can't be undefined at the point when foo is called."
3

Add x is undefined as return type for the function. See docs

const foo = (x: number) => {
    console.log("foo")
    return x * x;
}

const isXUndefined = (x?: number): x is undefined => x === undefined;

const boo = (x?: number) => {
    if (isXUndefined(x)) {
        return 0;
    }

    return foo(x);
}

1 Comment

Good answer, though not exactly my case..but it's because of the example I gave which is too general , not your answer. Thanks anyway :)
0

I have a more difficult case where x is a member of an obj and the I pass obj into a validation function where I check x (and others validation if needed). Here's my code:

const foo = (obj: IOBJ) => {
    return obj.x * obj.y;
}

interface IOBJ {
    x?: number;
    y: number;
}

const isObjValid = (obj: IOBJ) => obj.x !== undefined;

const boo1 = (obj: IOBJ) => {
    if (!isObjValid(obj)) {
        return 0;
    }

    return foo(obj);
}

and here's my playground

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.