ts中数组、字符串、索引类型的重新构造

129 阅读2分钟

1、数组类型的重新构造

1、push

type Push21<Arr extends unknown[], Ele> = [...Arr, Ele];
//类型参数 Arr 是要修改的数组/元组类型,元素的类型任意,也就是 unknown。
//类型参数 Ele 是添加的元素的类型。
//返回的是用 Arr 已有的元素加上 Ele 构造的新的元组类型。
type push21Test = Push21<['a', 'b', 'c'], 4>
//type push21Test = ["a", "b", "c", 4]

2、unshift

type Unshift21<Arr extends  unknown[], Ele> = [Ele, ...Arr];
type unshift21Test = Unshift21<['a', 'b', 'c'], 4>
//type unshift21Test = [4, "a", "b", "c"]

3、zip合并两个元素的元组

type Zip21<One extends [unknown, unknown], Other extends [unknown, unknown]> =
  One extends [infer OneFirst, infer OneSecond]
  ? Other extends [infer OtherFirst, infer OtherSecond]
  ? [[OneFirst, OtherFirst], [OneSecond, OtherSecond]] : []
  : [];
type zipTest1 = [1, 2];
type zipTest2 = ['a', 'b'];
type zipTest3 = Zip21<zipTest1,zipTest2>;
//type zipTest3 = [[1, "a"], [2, "b"]]

4、zip合并多个元素的元组

type Zip21_2<One extends unknown[], Other extends unknown[]> =
  One extends [infer OneFirst, ...infer OneRest]
  ? Other extends [infer OtherFirst, ...infer OtherRest]
  ? [[OneFirst, OtherFirst], ...Zip21_2<OneRest, OtherRest>] : []
  : [];
type zipTest4 = [1, 2, 3, 4, 5];
type zipTest5 = ['a', 'b', 'c', 'd', 'e'];
type zipTest6 = Zip21_2<zipTest4, zipTest5>;
//type zipTest6 = [[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"]]

2、字符串类型的重新构造这就是字符串类型的重新构造:

从已有的字符串类型中提取出一些部分字符串,经过一系列变换,构造成新的字符串类型。

1、把字符串字面量类型转为首字母大写

type CapitalizeStr22<Str extends string> =
  Str extends `${infer First}${infer Rest}`
  ? `${Uppercase<First>}${Rest}` : Str;
type testCapitalize22 = CapitalizeStr22<'hello'>
//type testCapitalize22 = "Hello"

2、把字符串字面量类型转为驼峰

type CamelCase22<Str extends string> =
  Str extends `${infer Left}_${infer Right}${infer Rest}`
  ? `${Left}${Uppercase<Right>}${CamelCase22<Rest>}`
  : Str;
type testCamelCase22 = CamelCase22<'hello_hello_hello'>
//type testCamelCase22 = "helloHelloHello"

3、删除字符串中的某个子串

//删除字符串中的某个子串
type DropSubStr22<Str extends string, SubStr extends string> =
  Str extends `${infer Prefix}${SubStr}${infer Suffix}`
  ? DropSubStr22<`${Prefix}${Suffix}`, SubStr> : Str;
//类型参数 Str 是待处理的字符串
//SubStr 是要删除的字符串,都通过 extends 约束为 string 类型。
//通过模式匹配提取 SubStr 之前和之后的字符串到 infer 声明的局部变量 Prefix、Suffix 中。
//如果匹配,那就用 Prefix、Suffix 构造成新的字符串
//然后继续递归删除 SubStr。直到不再匹配,也就是没有 SubStr 了。
type testDropSubStr = DropSubStr22<'hellooooo', 'o'>;
//type testDropSubStr = "hell"

3、索引类型的重新构造

1、映射类型的语法

type Mapping<Obj extends object> = { 
    [Key in keyof Obj]: Obj[Key]
}

2、对 Value 做修改

type Mapping23_2<Obj extends object> = {
  [Key in keyof Obj]: [Obj[Key], Obj[Key], Obj[Key]]
}

type test_Mapping23_2=Mapping23_2<{name:'a',age:18}>
//type test_Mapping23_2 = {
//  name: ["a", "a", "a"];
//  age: [18, 18, 18];
//}

3、对 Key 做修改

//对 Key 做修改
type UppercaseKey23<Obj extends object> = {
  [Key in keyof Obj as Uppercase<Key & string>]: Obj[Key]
}
//类型参数 Obj 是待处理的索引类型,通过 extends 约束为 object。
//新的索引类型的索引为 Obj 中的索引,
//也就是 Key in keyof Obj,但要做一些变换,也就是 as 之后的。

//通过 Uppercase 把索引 Key 转为大写,
//因为索引可能为 string、number、symbol 类型,而这里只能接受 string 类型,
//所以要 & string,也就是取索引中 string 的部分。
type test_UppercaseKey23 = UppercaseKey23<{ name: 'a', age: 18 }>
//type test_UppercaseKey23 = {
//  NAME: "a";
//  AGE: 18;
//}