如何让TypeScript识别自定义Hook返回的状态变量与Setter函数为明确的不同类型(解决TS7053错误)
The issue here is how you've defined the return type of your useRotation hook. Right now, you're returning an array where each element is a union of Matrix or () => void (((Matrix | (() => void))[])), which makes TypeScript treat both destructured values (board and rotateBoard) as that union type—so it can't be sure which one is the matrix and which is the function.
The Fix: Use a Tuple Type Instead of a Union Array
TypeScript tuples let you define a fixed-length array where each position has a specific, explicit type. Changing your hook's return type to a tuple will tell TypeScript exactly what each element in the returned array is:
function useRotation(matrixNeedingRotation: Matrix): [Matrix, () => void] { const [matrix, setMatrix] = useState<Matrix>(matrixNeedingRotation); function rotateMatrix(): void { const newMatrix = zip(...matrix); setMatrix(newMatrix); } return [matrix, rotateMatrix]; }
Why This Works
- A tuple like
[Matrix, () => void]enforces that the first element is always aMatrixand the second is always a function that returnsvoid. - When you destructure
const [board, rotateBoard] = useRotation(testBoard);, TypeScript will now correctly infer:boardas typeMatrix(so you can safely access indices likeboard[y][x])rotateBoardas type() => void(so you can call it directly in youronClickhandler)
Optional: Let TypeScript Infer the Return Type
If you prefer, you can even omit the explicit return type entirely—TypeScript will automatically infer the tuple type based on what you return:
function useRotation(matrixNeedingRotation: Matrix) { const [matrix, setMatrix] = useState<Matrix>(matrixNeedingRotation); function rotateMatrix(): void { const newMatrix = zip(...matrix); setMatrix(newMatrix); } return [matrix, rotateMatrix]; // TypeScript infers this as [Matrix, () => void] }
This works because TypeScript recognizes that you're returning an array with two distinct, fixed types. However, explicitly defining the return type can make your code more readable for other developers (or future you!) and catch any accidental changes to the return value structure.
After making this change, your component will no longer have TypeScript errors when accessing board indices or calling rotateBoard.
内容的提问来源于stack exchange,提问作者ElZilcho

