The transpose of a matrix is an operator which flips a matrix over its diagonal; that is, it switches the row and column indices of the matrix A by producing another matrix, often denoted by AT.
type TransPoseImplement<M extends number[][],Row extends any[]=[],Column extends any[]=[],Result extends number[][]=[],Tmp extends number[]=[]>=
Row['length'] extends M[0]['length']?
Result
:Column['length'] extends M['length']?
TransPoseImplement<M,[...Row,1],[],[...Result,Tmp]>
:TransPoseImplement<M,Row,[...Column,1],Result,[...Tmp,M[Column['length']][Row['length']]]>
type Transpose<M extends number[][]> = TransPoseImplement<M>
우선 사용처에서 구현용 제네릭을 사용하지 못하게 하기 위해 구현과 실제 타입을 분리했다.
행과 열을 순회하며 [i][j]의 배열을 [j][i]와 같은식으로 바꾸어서 구현하였다.
type Transpose<M extends number[][],R = M['length'] extends 0?[]:M[0]> = {
[X in keyof R]:{
[Y in keyof M]:X extends keyof M[Y]?M[Y][X]:never
}
}
보고 감탄을 한 풀이이다.
배열은 객체이므로 keyof를 사용해 각각의 row(X)와 column(Y)을 구한뒤, 두 값을 바꿔주는 방식으로 문제를 해결하였다.
이때, keyof M[Y]를 확인하는 이유는 X가 M[Y]에 대응한다는 것을 명시적으로 보여주기 위함이다.
https://github.com/type-challenges/type-challenges/issues/25297