# 35191-Trace
# 题目描述
给定方阵,返回主对角线上所有元素组成的联合类型(不需要真的求和,因为类型层做数字求和昂贵)。
type Arr = [[1, 2], [3, 4]];
type R = Trace<Arr>; // 1 | 4
# 分析
主对角线上的元素就是 M[i][i]。我们需要遍历 i,把每个 M[i][i] 拿出来拼成联合。
在类型层:"遍历 i = 0, 1, 2, ..."可以借助递归剥首行。每一轮:
- 取
M[0][0]贡献到结果; - 把
M的首行 pop、每行的首列也 pop,对剩下的矩阵递归。
这样每一轮处理完都相当于矩阵左上角削掉 1 x 1,剩下右下角的更小方阵。
# 题解
type Trace<M extends any[][]> = M extends [
[infer Head, ...any],
...infer Rest extends any[][],
]
? Head | Trace<DropFirstCol<Rest>>
: never;
type DropFirstCol<M extends any[][]> = {
[K in keyof M]: M[K] extends [any, ...infer R] ? R : [];
};
思路:
M extends [[infer Head, ...any], ...Rest]拿到左上角元素Head和除首行外的子矩阵Rest。DropFirstCol<Rest>把Rest的每一行的首列削掉。- 结果
Head | Trace<...>自动拼成联合。 - 出口:矩阵变空返回
never。
# 验证
type R1 = Trace<[[1]]>; // 1
type R2 = Trace<[[1, 2], [3, 4]]>; // 1 | 4
type R3 = Trace<[[1, 2, 3], [4, 5, 6], [7, 8, 9]]>; // 1 | 5 | 9
# 知识点
- 对二维元组做"削左上角"递归,是 矩阵类 题目的主力技巧(参考 medium/25270-Transpose 的"削首列")。
[K in keyof M]应用在元组上保持元组形态,是DropFirstCol的精髓,见 元组遍历的黑科技。