1

I have the following types

export type Player = 'x' | 'o'
export type GameFieldValue = null | Player;
export type Board = [
    [GameFieldValue, GameFieldValue, GameFieldValue],
    [GameFieldValue, GameFieldValue, GameFieldValue],
    [GameFieldValue, GameFieldValue, GameFieldValue],
]

Say I have an object of type Board

const board : Board = [
    ['x','x','o'],
    ['o','x','x'],
    ['x','x','x']
]

Now, I need a function that can invert all the values of the board (eg. 'x' becomes 'o' and the other way around)

const boardInverted : Board = [
    ['o','o','x'],
    ['x','o','o'],
    ['o','o','o']
]

The function I've come up with

function invertBoardValues(b:Board):Board {
    return b.map(row => row.map(val => val === 'x' ? 'o' : 'x'))
}

However, I get the error

Type '("x" | "o")[][]' is not assignable to type 'Board'.
Target requires 3 element(s) but source may have fewer.

What do I do to fix this?

Boris Grunwald
  • 2,602
  • 3
  • 20
  • 36
  • 2
    TypeScript's typing for `Array.map` does not attempt to represent length preservation; see [microsoft/TypeScript#29841](https://github.com/microsoft/TypeScript/issues/29841) for details. If you want to merge in your own overload for `map()` which does this, as in [this answer](https://stackoverflow.com/a/57913509/2887218) here, you can do so like [this](https://tsplay.dev/wgrdbW). – jcalz Jun 08 '21 at 18:21
  • Wow, thank you for this really detailed answer. – Boris Grunwald Jun 08 '21 at 18:23
  • Oops, forgot to link to [the answer in question](https://stackoverflow.com/a/57913509/2887218). – jcalz Jun 08 '21 at 18:26

1 Answers1

0

You could use as Board:

function invertBoardValues(b:Board):Board {
    return b.map(row => row.map(val => val === 'x' ? 'o' : 'x')) as Board;
}
obe
  • 7,378
  • 5
  • 31
  • 40