1

I was looking for a way to separate an array into 2 arrays given a validation function & found this question that helped a lot. The answer is the following:

function partition(array, isValid) {
  return array.reduce(([pass, fail], elem) => {
    return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]];
  }, [[], []]);
}

const [pass, fail] = partition(myArray, (e) => e > 5);

Now I want to write the same question but now using typescript:

      const separateArray = <T>(array: T[], condition: (e: T) => boolean): [T[], T[]] => {
        return array.reduce(([passed, failed], elem: T) => condition(elem) ? [
          [...passed, elem], failed
        ] : [passed, [...failed, elem]],[[],[]])
      }

The above works just fine, the thing is that when I try to set the type for the first param of the reduce function TO [T[], T[]] I get an error:

Code:

    return array.reduce(([passed, failed]: [T[], T[]] ......

Error:

Type 'T[][]' is not assignable to type '[T[], T[]]'.
  Target requires 2 element(s) but source may have fewer.

I tried setting the type to [any[],any[]] and [any, any] but I still get the same error.

Does anyone know how can I solve this?

Ignacio Ambía
  • 479
  • 5
  • 16
  • 1
    Do not be afraid of a little bit of type assertion when justified, especially for initially empty arrays. I do not know if you are able to see @Crice 's deleted answer, but it seems to me as a totally valid solution. – ghybs Aug 16 '22 at 02:12

1 Answers1

1

Typescript is inferring the type of the first parameter as T[][] based on the return value in the conditional operation: [[…passed, elem], failed] and so on since type of either passed or failed isn’t defined and elem has type T. You can tell typescript explicitly that the type is [T[], T[]] instead.

const separateArray = <T>(array: T[], condition: (e: T) => boolean): [T[], T[]] => {
    return array.reduce(([passed, failed]: [T[], T[]], elem: T) => condition(elem) ? [
      [...passed, elem], failed
        ] as [T[], T[]]: [passed, [...failed, elem]] as [T[], T[]],[[],[]])
  }
Rahul Sharma
  • 5,562
  • 4
  • 24
  • 48
  • In case @CRice does not undelete their answer: the above answer can be improved by type asserting directly the initial value, instead of having to it 3 times (the argument and the 2 possible returns). – ghybs Aug 16 '22 at 09:56