前言
正式开始工作的第一天,克隆了一个项目代码来看,发现全是react+ts的,十分陌生。于是迅速阅览了一下基本的语法,顺便也把学到的总结一下。Ts其实已经出了有一段时间了,它是Js的超集,也就是说他吸取了Js的精华并融入了其它语言的一些优点,将Js推到了一个新的高度,例如,它支持静态类型声明、接口编写等,使开发人员能够开发出更便于维护的高效代码。
静态类型声明
在Ts中,最基本也是最常用的就是静态类型的声明,学过Js的小伙伴都知道,Js是弱数据类型语言。而Ts正是将这一点进行优化,使得变量具有明确的数据类型,也避免了许多不必要的错误。
- 基础类型声明
let num: number = 1; // 数字
let str: string = 'yellowbird'; // 字符串
let bool: boolean = true; // 布尔值
let undefined1: undefined = undefined; // 未定义
let null1: null = null; // 空
let any1: any = 'sdfdf'; // 任意值
let b:number = '1'; // Error,不能混着用
如果你希望一个变量可以是number,也可以是string,可以用一个"|"来声明
let numOrStr: number | string = 111;
numOrStr = '111';
- 对象类型声明
// 对象
const people: {
name: string;
age: number;
} = {
name: 'zhangCan',
age: 28
};
// 数组
const arr: number[] = [1, 2, 3];
const arr1: (number | string)[] = [1, 2, '3']; // 数组同样也可以用"|"表示多类型的数组
// 类
class Person {};
const teacher: Person = new Person();
另外还有一个就是函数的参数以及返回值的静态变量声明,它也是属于对象类型声明。除了以上提到number、string、boolean等基本类型以外,函数的返回值还可以是void和never。
// 传的参数为number类型,返回值为string类型的函数
function example1(num: number): string {
return num.toString();
}
example1(111);
example2('111') //Error,传参类型不对
当函数没有返回值时,返回值声明为void:
function example1(num: nmuber): void {
console.log(num)
}
当函数不可能执行通过时,则用never,代表永远不可能存在的变量:
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
while (true) {
}
}
- 类型推断
还有一种情况就是如果你不写任何静态类型声明的话,它默认为你赋的值的类型,这个就是类型推断。也就是说:
let num = 123;
// 等价于
// let num: number = 123
num = '123'; // 仍然报错,因为Ts已经默认该变量为number类型
元组
元组是一个和数组非常类似的数据结构,有别于数组的是,元组可以约束数组中的每一项的类型,举个例子:
// 定义一个数组,存储的是火山老师的信息
const teacherInfo: (number | string)[] = ['huoshan', 'man', 28];
teacherInfo[1] = 123; // 性别
以上例子定义了一个火山老师的信息,但是我在修改信息时误将性别改为123,从逻辑上来说,这是错误的,但是代码并没有报错,元组在这一点上很好的约束了他每一项的数据类型。
const teacherInfo: [string, string, number] = ['huoshan', 'man', 28];
teacherInfo[1] = 123; // Error
接口
- 作用
我们先从一段代码了解接口是个啥玩意
const getUserInfo = ({name: string, age: number, username: string}):void => {
console.log(name, age, username)
}
从上面这段代码我们可以看到这是传一个用户信息并打印的一个函数,我这里只罗列了三个信息,试想一下,假如要传的参数很多,又或者是我有多个函数需要传这个参数,那代码将变得十分不美观,也不好维护。于是接口他来了!
// 优雅,又易于维护
interface UserInfo {
name: string;
age: number;
username: string;
}
const getUserInfo = (user: UserInfo): void => {
console.log(user.name, user.age, user.username)
}
- 可选属性
然而项目中不一定每个数据都是必需的,所以接口还提供了可选属性的写法。
interface UserInfo {
name: string;
age?: number; //可选属性
}
const getUserInfo = (user: UserInfo): void => {
console.log(user.name)
}
getUserInfo({name: 'yellowbird'}) //可以不输入age
- 只读属性
Ts还提供了只读属性,设置了只读属性之后,我们不能直接修改该属性。直接上代码
interface UserInfo {
readonly name: string;
}
const setUserInfo = (user: UserInfo): string => {
return user.name = 'hp' // 报错,因为name是只读属性
}
setUserInfo({name: 'yellowbird'})
- 接口之间的继承
接口之间也是可以互相继承的,如下
interface Person {
name: string;
age: number;
}
interface Teacher extends Person {
subjects: string // 科目
}
const teacher1 = {
name: '火山老师',
age: 28,
subjects: 'typescript'
}
类
- 封装与继承
类的继承和封装其实没啥好讲的,其实就是ES6的语法,都2020了还不会就很夸张,我感觉很简单,我就不再赘述,可以直接去看我的这篇文章学习JS设计模式总结(1)—— 理解面向对象,文中详细的写了一下关于类的封装和继承。看到这篇文章就想起自己没填完的坑,拖延症啊!
- 应用接口 类除了继承类以外,还可以应用接口,语法和继承还是挺像的,写个例子
interface UserInfo {
name: string;
age?: number; //可选属性
}
class User implements UserInfo {
name: 'yellowbird'
}
总结
本文是看完一些网课,然后再结合TS中文网的文档来写的,算是一个对TS基本的总结与复习,罗列了一些我认为比较重要的点,看完之后再去看项目也不至于太陌生。但这个过程我写吐了,看的时候感觉没啥,内容很少,但是越写感觉越多东西,主要还是忘得快,忘了就去查看文档,在边查边写的过程中又一次的加深印象。
其实Ts远不止这些,这些都是基础的语法和用法,加上有些知识点我自己的理解了,看懂了但可能还不到位,比如抽象类,或者存取器这些,所以干脆先不写了,照抄文档没意义,强行自己写又怕误人子弟,以后在实际项目中如果有什么新发现,会在以后的文章中补充更新。
喜欢就关注个公众号吧!(有没人告诉我,这句话在markdown里怎么居中啊)