TypeScript 中“R['length'] extends N”语法的解释
Explanation of " R['length'] extends N " syntax in TypeScript
TypeScript 新手,正在寻找一种方法来定义固定大小的数组并遇到 :
type Tuple<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never;
type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>;
type Tuple9<T> = Tuple<T, 9>;
type Board9x9<P> = Tuple9<Tuple9<P>>;
...使用递归条件类型获得所需的结果。
我试图理解正在使用的语法,但我无法真正理解幕后发生的事情,尤其是在这一点上:R['length'] extends N
.
我知道它会检查数组是否具有所需的长度,如果不是,它将使用额外的元素递归调用 _TupleOf
,直到该条件变为真。但为什么会这样?
我搜索了答案,但找不到任何有用的东西。
如果应用于类型,R['length']
return 是作为数字的实际长度吗?为什么 extends
在这种情况下看起来像 ==
运算符?
我也试过仔细检查它的行为是否如我在 playground 中所理解的那样(您可以将鼠标悬停在 b
和 c
上以检查类型)并且似乎确实如此,还是不明白为什么。
任何link或解释?提前致谢!
因为:
- 元组的
length
属性类型是文字数字类型,等于元组中元素的数量。所以不仅仅是 number
,而是 特定的 数字(例如 42
)。
- 数字文字类型扩展
number
。 (嗯...我不确定我为什么提到这个,但它在下面的例子中所以我会保留它。)
- 数字字面量类型仅“扩展”自身(与其相同或子类型)。
type TwoThings = [string, string];
type TwoThingsLength = TwoThings["length"];
// ^? −−− type TwoThingsLength = 2
type IsNumber<T> = T extends number ? true : false;
type A = IsNumber<27>;
// ^? −−− type A = true
type B = IsNumber<"example">;
// ^? −−− type B = false
type IsThisNumber<T, Num> = T extends Num ? true : false;
type C = IsThisNumber<27, 27>;
// ^? −−− type C = true
type D = IsThisNumber<27, 42>;
// ^? −−− type D = false
// Which leads us to
type E = IsThisNumber<TwoThingsLength, 2>; // true, they're the same literal number
// ^? −−− type E = true
type F = IsThisNumber<TwoThingsLength, 3>; // false, they aren't
// ^? −−− type F = false
所以 R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>
的工作人员是:
- 如果
R['length']
与目标长度 N
相同,则评估为 R
类型本身
- 如果不是,则创建一个新的元组类型,其中包含元素
T
加上所有先前的元素 (...R
)——例如,添加一个——并递归
TypeScript 新手,正在寻找一种方法来定义固定大小的数组并遇到
type Tuple<T, N extends number> = N extends N ? number extends N ? T[] : _TupleOf<T, N, []> : never;
type _TupleOf<T, N extends number, R extends unknown[]> = R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>;
type Tuple9<T> = Tuple<T, 9>;
type Board9x9<P> = Tuple9<Tuple9<P>>;
...使用递归条件类型获得所需的结果。
我试图理解正在使用的语法,但我无法真正理解幕后发生的事情,尤其是在这一点上:R['length'] extends N
.
我知道它会检查数组是否具有所需的长度,如果不是,它将使用额外的元素递归调用 _TupleOf
,直到该条件变为真。但为什么会这样?
我搜索了答案,但找不到任何有用的东西。
如果应用于类型,R['length']
return 是作为数字的实际长度吗?为什么 extends
在这种情况下看起来像 ==
运算符?
我也试过仔细检查它的行为是否如我在 playground 中所理解的那样(您可以将鼠标悬停在 b
和 c
上以检查类型)并且似乎确实如此,还是不明白为什么。
任何link或解释?提前致谢!
因为:
- 元组的
length
属性类型是文字数字类型,等于元组中元素的数量。所以不仅仅是number
,而是 特定的 数字(例如42
)。 - 数字文字类型扩展
number
。 (嗯...我不确定我为什么提到这个,但它在下面的例子中所以我会保留它。) - 数字字面量类型仅“扩展”自身(与其相同或子类型)。
type TwoThings = [string, string];
type TwoThingsLength = TwoThings["length"];
// ^? −−− type TwoThingsLength = 2
type IsNumber<T> = T extends number ? true : false;
type A = IsNumber<27>;
// ^? −−− type A = true
type B = IsNumber<"example">;
// ^? −−− type B = false
type IsThisNumber<T, Num> = T extends Num ? true : false;
type C = IsThisNumber<27, 27>;
// ^? −−− type C = true
type D = IsThisNumber<27, 42>;
// ^? −−− type D = false
// Which leads us to
type E = IsThisNumber<TwoThingsLength, 2>; // true, they're the same literal number
// ^? −−− type E = true
type F = IsThisNumber<TwoThingsLength, 3>; // false, they aren't
// ^? −−− type F = false
所以 R['length'] extends N ? R : _TupleOf<T, N, [T, ...R]>
的工作人员是:
- 如果
R['length']
与目标长度N
相同,则评估为R
类型本身 - 如果不是,则创建一个新的元组类型,其中包含元素
T
加上所有先前的元素 (...R
)——例如,添加一个——并递归