这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
TypeScript入门 | 青训营笔记
本堂课重点内容:
- TypeScript和JavaScript区别
- 对象类型
- 函数类型
- 数组
- 枚举
- 泛型
- 联合交叉类型
1.TypeScript和JavaScript区别
TS是弱类型语言,JS是强类型语言。 什么意思呢?举个例子说明一下:
let a = 123
a = 'abc'
这段代码在JS里面是可以执行的,但是在TS中是会报错的。例子中的a一开始赋值为number属性,后面改为string属性。强类型语言可以在任意类型中转换,但是弱类型语言是不可以的吗,一旦规范了一种属性类型,那么就无法改变。
2.对象类型
当我们使用TS给对象规范的时候,我们通常会使用接口来规范。看个例子:
interface IBytedancer {
// 只读属性: 约束属性不可在对象初始化外赋值
readonly jobId: number;
name: string;
sex: 'max' | 'woman' | 'other',
// 可选属性:可有可无
hobody?: string;
// 任意属性: 约束所有对象key属性必须是string值, value 为any
[key: string]: any;
}
// obj继承接口
let obj: IBytedancer = {
jobId: 1,
name: 'zs',
sex: 'max',
hobody: 'st',
}
// obj.jobId = 2 这个会报错
- 这里的readonly限制jobId为只读属性,只能在初始化时候赋值。
- sex可以选择三种其中的一种值。
- hobody为可选属性,可有可无。
- key必须为string类型,value必须为any类型。
3.函数类型
以下是箭头函数和普通函数使用接口的用法:
interface ItFn {
(x: number, y: number): number;
}
// 箭头函数
const mult:ItFn = (x: number, y: number) => x + y
// 普通函数
const fn:ItFn = function(x: number, y: number): number {
return x + y
}
4.数组类型
type a1 = number[]
type a2 = Array<string | number>
type a3 = [number, string]
interface IArr4 {
[key: number]: any;
}
let arr1:a1 = [1,2]
let arr2:a2 = [1,'ew',2]
let arr3:a3 = [1,'3']
let arr4:IArr4 = ['string', ()=>null, {}, []]
- 这里的a1定义为纯数字的数组。
- 这里的a2定义数字或者字符串的数组。
- 这里的a3定义为第一个值必须为number,第二个值为string,不能有第三个值。
- 这里的IArr4定义key为number,值为any,数组里面可以存放任意类型。
5.枚举
数值类枚举
enum Fn {
one = 1,
two,
three
}
console.log(Fn.one, Fn.two, Fn.three); // 1,2,3
我们可以通过赋值枚举类中的某个值,然后其他值就会自动赋值。
字符串类枚举
enum Fn2 {
One = 'one',
Two = 'two',
Three = 'three'
}
有时候数值类枚举难以表达意思,我们就可以通过字符串类枚举实现。
6.泛型
type IFn = (target:any) => any[]
type IFn2 = <T>(target:T) => T[]
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候在指定类型的一种特性。如上面例子中,第一个例子我们定义为any类型,就是来解决使用时才知晓函数参数为何类型,但是这种方法并不好。第二个例子就是使用了泛型来定义,无论我们传入什么类型的数值,都能够解决。
7. 联合交叉类型
interface Ifn1 {
a: string;
b: string;
range: string;
}
interface Ifn2 {
a: string;
b: string;
author: string;
}
type List = Array<Ifn1 | Ifn2>
const bookList = [
{
a:'a',
b: 'b',
range: '2022'
},
{
a:'a',
b: 'b',
author: '张三'
},
]
上述例子中,我们的bookList要使用range和author属性的话,我们就必须使用两种接口,a和b属性是重复的,这样声明就比较繁琐重复了,不利于开发。
type IBookList = Array<{
a: string;
b: string;
} & ({
author: string
} | {
range: string
})>
我们可以使用联合/交叉类型,以上例子我们抽离出a和b这两个公共属性,然后通过&和|来划分出不同的属性。