1

I have an issue with typescript and react. Bellow is a small exmaple that illustrates the problem.

const Example = (props: { x?: number, fn: (x: number) => void}) => {
        if (props.x !== undefined) {
            return <button onClick={() => props.fn(props.x)}>Click me</button>
        }
        return null;
}

Code checks explicitly that x is defined but typescript won't compile it because fn requires x to be a number. It can be solved using casting

const y = props.x as number;
return <button onClick={() => props.fn(y)}>Click me</button>

It works but looks weird. Any ideas how to handle such cases. It's just an example in my code we have an object instead of a number and it also either defined and then we render some html for it or not defined (=== undefined) and than we just return null.

1 Answer 1

3

This is a limitation in how control flow analysis works. The analysis does not cross function boundaries. You can read more here. The basic idea is that there is no guarantee prop.x will still not be undefined by the time the callback is called.

The workaround is to put prop.x in a local variable. This will capture the flow type in the variable type:


const Example = (props: { x?: number, fn: (x: number) => void}) => {
        if (props.x !== undefined) {
            const x = props.x
            return <button onClick={() => props.fn(x)}>Click me</button>
        }
        return null;
}

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

3 Comments

thanks, it works, now it looks better, still a bit strange but at least no casting.
the point is that this is callback. in time of call your x can be theoretically undefined.
@JurajKocan 10x, added to the answer, I was being lazy, good thing SO community keeps me honest 😉

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.