TS类型体操练习 3
If
实现一个 IF
类型,它接收一个条件类型 C
,一个判断为真时的返回类型 T
,以及一个判断为假时的返回类型 F
。 C
只能是 true
或者 false
, T
和 F
可以是任意类型。
type A = If<true, 'a', 'b'> // expected to be 'a'
type B = If<false, 'a', 'b'> // expected to be 'b'
实现:
type If<C, T, F> = C extends true ? T : F;
Length of String
Compute the length of a string literal, which behaves like String#length
.
计算字符串的长度,类似于 String#length
。
测试用例:
type cases = [
Expect<Equal<LengthOfString<"">, 0>>,
Expect<Equal<LengthOfString<"kumiko">, 6>>,
Expect<Equal<LengthOfString<"reina">, 5>>,
Expect<Equal<LengthOfString<"Sound! Euphonium">, 16>>
];
实现:
之前有练习过,获取array的长度,可以直接用length属性获取,也就是T["length"]
, 所以一种思路就是把字符串转换成数组;对于要把字符串转为数组,最简单能够想到的就是将字符串的首位或者尾位一个个取出来加入一个数组当中
在 TS 的泛型里面,首先我们要定义一个数组来进行存放,那就只能是定义在类型参数当中,可以给出一个默认的空值,在之后的递归当中不断地往里面添加属性。
type LengthOfString<S extends string, T extends any[] = []> = S extends ""
? T["length"]
: S extends `${infer Start}${infer Rest}`
? LengthOfString<Rest, [Start, ...T]>
: never;
Type Lookup
In this challenge, we would like to get the corresponding type by searching for the common type
field in the union Cat | Dog
. In other words, we will expect to get Dog
for LookUp<Dog | Cat, 'dog'>
and Cat
for LookUp<Dog | Cat, 'cat'>
in the following example.
通过在联合类型Cat | Dog
中通过指定公共属性type
的值来获取相应的类型。
interface Cat {
type: 'cat'
breeds: 'Abyssinian' | 'Shorthair' | 'Curl' | 'Bengal'
}
interface Dog {
type: 'dog'
breeds: 'Hound' | 'Brittany' | 'Bulldog' | 'Boxer'
color: 'brown' | 'white' | 'black'
}
type MyDogType = LookUp<Cat | Dog, 'dog'> // expected to be `Dog`
实现:
用条件类型 U extends { type: T } ? U : never
来过滤出 type
属性为 T
的子类型。如果找到匹配的子类型,则返回它,否则返回 never
类型。
type LookUp<U, T> = U extends { type: T } ? U : never;
Flatten
In this challenge, you would need to write a type that takes an array and emitted the flatten array type.
需要写一个接受数组的类型,并且返回扁平化的数组类型。
type flatten = Flatten<[1, 2, [3, 4], [[[5]]]]> // [1, 2, 3, 4, 5]
实现:
分别取第一个元素,和剩余元素通过递归实现数组的扁平化