skip to Main Content

I’m using typescript in React and I’m facing the following problem.

Here is a function that checks that arr is an Array and is not empty.

export const isNotEmptyArr = (arr?: unknown[]) => {
  return Array.isArray(arr) && arr.length > 0  // If true, arr is not undefined.
}

I think that if isNotEmptyArr(data) is true for data that may be undefined, then data is guaranteed to be not undefined.

  const { data } = useSWR(  // data is possibly undefined
    ...
  )

  useEffect(() => {
    if (isNotEmptyArr(data)) {
      setName(data[0].name)  // error occured - TS2532: Object is possibly 'undefined'.
    }
  }, [data])

But, typescript generates an error as shown above, saying that data may be undefined. Why is that so? Is there a beautiful way to solve this problem?

For now, I am solving this problem using optional chaining (like this: data?.[0].name ?? ''), but I hope there is a better way.

typescript version: 4.5.4

2

Answers


  1. Similar to what you have, but won’t trigger a render:

    useEffect(() => {
        setName(prev => data[0]?.name || prev);
    }, [data]);
    

    or, as bergie has mentioned, you could go with something like:

    useEffect(() => {
       if (isNotEmptyArr(data) && data[0]) {
         setName(data[0].name)
       }
    }, [data]);
    
    Login or Signup to reply.
  2. Not by default. You can define a function as a type predicate, and then it will use that type information.

    function isNotEmptyArr (arr?: unknown[]): arr is unknown[] {
      return Array.isArray(arr) && arr.length > 0  // If true, arr is not undefined.
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search