Jeffrey Chen
Jeffrey Chen

Reputation: 1967

Pass an object that has an optional property to a function that guarantee it will not be undefined but editor/compiler still think it can be undefined

function f1(
    toolbox: {
       tool1?: Tool1,
       tool2?: Tool2,
    }
) {
    if (!toolbox.tool1) {
        toolbox.tool1 = fetchTool1();
    }
    if (!toolbox.tool2) {
        toolbox.tool2 = fetchTool2();
    }
    // Do something else
}

function f2(
    toolbox: {
        tool1?: Tool1,
        tool2?: Tool2,
    }
) {
    f1(toolbox);
    // tool1 and tool2 are no longer undefined.
    const x = toolbox.tool1.value // Editor shows error, tool1 may be undefined.
}

The design above passes a toolbox object to different functions, so the program doesn't need to fetch the tools that are already fetched by other functions. The problem is, even if I know for sure toolbox.tool1 and toolbox.tool2 will not be undefined after calling f1, the editor still shows error.

I know I can use exclamation mark like const x = toolbox.tool1!.value, or maybe just turn off the warning. But I'm looking for a way that is more friendly to the default type checking.

I have tried let f1 return the toolbox that has no question mark in it, and call toolbox = f1(toolbox). It doesn't work, the line const x = toolbox.tool1.value still shows error.

Upvotes: 0

Views: 30

Answers (1)

tenshi
tenshi

Reputation: 26324

You're looking for asserts.

f1 now looks like this:

function f1(
    toolbox: {
       tool1?: Tool1,
       tool2?: Tool2,
    }
): asserts toolbox is { tool1: Tool1; tool2: Tool2 } {

You can think of this as "changing" the type in the scope it was called:

f1(toolbox);

toolbox // now { tool1: Tool1; tool2: Tool2 }

const x = toolbox.tool1.value; // fine

Playground

Upvotes: 1

Related Questions