一直想写一篇关于TypeScript相关的文章,对于TypeScript的基本概念,我不去做过多解释,学习完基本语法之外,我想补充一点,TypeScript是图灵完备
的,因此我们不仅仅可以使用TypeScript去定义一些接口,类型;我们还可以使用TypeScript解决计算、构建、循环等所有的编程问题;
因此TypeScript的实质就是对类型进行编程
,在使用TypeScript进行开发时,大部分时间我们都是自定义类型,但是TypeScript也有很多内置类型,我们如果对其足够熟悉,那么将可以大大提高我们的开发效率,如果懂其原理,那对我们深入理解TypeScript将会更有帮助!
温馨提示:本文的前提是掌握TypeScript基本语法;对于语法不熟悉的小伙伴可先收藏哦!
so are you ready? let*s get start it?
Parameters
作用:根据传入的函数类型,推断这个函数的参数类型;
实现
type Parameters any> = T extends (
...args: infer P
) => any
? P
: never;
// test
type Fun = (name: string, age: number) => string;
const p: Parameters = ["", 10]; // const p: [name: string, age: number]
其实原理并不难,就是利用的infer来推测出参数的类型;
ReturnType
type ReturnType any> = T extends (
...args: any[]
) => infer R
? R
: never;
// test
const r: ReturnType = ""; // const r: string
这个和Parameters是一个套路;都是利用infer来进行推导,infer在进行类型构造时非常有用,它的本质就是当我们想要获取某个类型的一部分的时候,就可以用它来进行推导并获取;
ConstructorParamters
type ConstructorParamters any>
= T extends new (...args: infer P) => any
? P
: never;
type Instance = {
name: string;
age: number;
};
interface ClassDemo {
new (name: string, age: number): Instance;
}
//test
const c: ConstructorParamters = ["", 10]; //const c: [name: string, age: number]
InstanceType
type InstanceType any> = T extends new (
...args: any[]
) => infer R
? R
: never;
const i: InstanceType = {
age: 10,
name: "",
}; //const i: Instance
Partial
type Partial = {
[K in keyof T]?: T[K];
};
const f: Partial<{
name: string;
age: number;
}> = {
age: 10,
}; // no error
这里要提到一个类型映射的概念
映射类型
keyof T
K in keyof T
T[K]
通过上面的方式我们可以去获取一个类型的每一个Key,并重新根据这个Key构造新的类型;在这个案例中其实就是加了一个可选条件而已;
Required
type Required = {
[K in keyof T]-?: T[K];
};
const h: Required<
Partial<{
name: string;
age: number;
}>
> = {
age: 10,
name: "",
}; // 相当于给复原了
Readonly
type Readonly = {
readonly [K in keyof T]: T[K];
};
const j: Readonly = {
age: 10,
name: "",
};
// test
// j.age = 19 // error
Pick
type Pick = {
[R in U]: T[R];
};
// test
type TestP = {
age: number;
name: string;
sex: boolean;
};
type Keys = "age" | "name";
const l: Pick = {
age: 10,
name: "",
};
Record
type Record = {
[K in T]: P;
};
// test
const y: Record = {
// key可以为任意一个字符串,值为number类型
anystring: 10,
};
Exclude
* 作用:当想从一个联合类型中去掉一部分类型时,可以用 Exclude 进行构造
* 实现:
```
type Exclude = T extends U ? never : T;
// test
const n: Exclude<"a" | "b" | "c" | "d" | "e", "a" | "c"> = "b"; //const n:"b" | "d" | "e"
```
Exclude的实现有个技巧,其实也不算技巧,就是当泛型接受的是一个联合类型的时候,实际上TypeScript在检测的时候,会依此把联合类型的每一个元素传入得到结果再联合起来;得到never时等价于没有得到任何东西。因此就有了去除的效果;
* 作用:取两个联合类型的交集
* 实现:
```
type Extract = T extends U ? T : never;
// test
const m: Extract<"a" | "b" | "c" | "d" | "e", "a" | "c"> = "c"; //const m: "a" | "c"
```
原理和10一样,我就不解释啦
* 作用:接受连个类型,从其中一个类型当中去除掉可以被另一种类型分配的属性,然后组成一个新的类型
* 实现:
```
type Omit = Pick>;
const v: Omit = {
name: "sf",
};
```
这个有点绕,多看两遍就可以理解啦;相当于从T类型当中取出一些符合条件的属性,符合什么条件呢?就是不能分配给U的的属性,那可不就是去掉啦指定的某些属性么!
* 作用
* 实现:
```
type NonNullable = T extends undefined | null ? never : T;
type Res = NonNullable; //type Res = never
```
* 作用:可以用来判断一个Promise的值类型,
* 实现:
```
type Awaited = T extends Promise
? Awaited
: T
type Test = Awaited>>>> // string
```
看不到它的源码,但是我简单讲一下他们的作用
type Uppercase 将传入的字符串类型转为大写
type Lowercase 将传入的字符串类型转为小写
type Capitalize 将传入的字符串类型首字母转为大写
type Uncapitalize 将传入的字符串类型首字母转为小写
本文结合了自己对于TypeScript的浅薄理解所写,实现方面可能与源码有所出入,但是每一种类型的实现都做了测试,但是功能都是一样的,主要便于自己理解,所以敬请谅解,如果有觉得不对的欢迎指正;
另外今年的小目标是希望能够升级到L3哈哈,如果觉得有帮助的,还望点赞,关注哦,我会持续输入高质量文章的;多谢多谢