一、什么是TS
TS是微软集团开发的,是javaScript的超集。有更严格的语法。
JS在开发时候的缺点:
- 1.js中变量是动态类型的。
let a = 1;
a = "hello TS";//原本给变量(a)赋值一个数值类型(Number)是可以的,再赋值字符串类型也可以(string)
- 2.有的时候不会报错
原来在开发的时候,出现数值为NAN,肯定是计算的时候数值转换出的问题,但由于种种原因找不到错误点,如果要是有类型校验就好了 - 3.js在定义函数的时候,函数的参数和返回值没有具体的类型限制。
Ts要编译为js,浏览器不认识TS
二、TS中的类型
2.1 Js中的数据类型有:
基本数据类型:
- 数值:number
- 字符串:string
- 布尔值:Boolean
- null
- undefined
- symbol
- bigint
复杂数据类型:对象,数组等
2.2Ts中的数据类型
基本数据类型
1. number(数值)
let b:number;
b = 10;
b = "100";//不能将字符串赋值给数值类型
2. string
let c:string;
c = "string";
3. boolean
let d:boolean;
d = true;
4. bigint
let e:bigint;
e = 12n;
补充:什么是bigint
BigInt
是一种内置对象,它提供了一种方法来表示大于 253 - 1
的整数,可以用在一个整数字面量后面加 n
的方式定义一个 BigInt
5. 字面量
let a:10;
a = 11;//错误的,变量a一旦被赋值为10,a以后就只能为10
let student:"男生"
student = "dog";
6. any
自认为这就和js变量没区别了
//变量被赋值为any数据类型就可以赋值任意数据类型
//显示的any
let f:any;
f = 'hi TS';
f = 11;
f = true;
f = 10n;
//隐式的any
let a;
a = 1;
7.unknown
let g:unknown;
g = "hello TS";
any和unknown的区别:
- 类型是any,它可以赋值给任意变量
- 类型是unknown,不能直接赋值给其他变量
举例
let f:any;
f = 'hi TS';
let g:unknown;
g = "hello TS";
let h:string;
h = f;
h = g;//报错
8.联合类型 (|)
let zhu:"小猪佩奇" | "小猪乔治" //zhu这个变量的类型只能为"小猪佩奇"或"小猪乔治"
zhu = "小猪佩奇"
zhu = "小猪乔治"
zhu = "猪妈妈"//报错
let num:1|2|3
num = 230;//报错
9.类型断言
有两种写法:
1)变量 as 类型
let balala:unknown ="凌美雪"
let gongzhu:string =balala;//报错,因为不能将unknow类型的变量赋值给其他变量
let gongzhu:string = balala as string;//这就不会报错
相当于我们告诉ts,你放心我检查过了balala这个变量它就是string类型的
2)<类型> 变量
let gongzhu:string = <string> balala;
复杂数据类型
刚才说道js对函数的形参以及返回值没有做类型的限制,ts在这方面进行了加强
1.函数
函数的返回值
1)void 空,函数返回值为空
function fn():void{
return undefined;//对的
return null;//报错
return 111;//报错
}
2)never 函数没有返回值
function fn1():never{
throw new Error("错误")
}
举例(两数之和)
function sum(a1:number,a2:number):number{
return a1+a2;
}
sum(1,2)
2.数组
1)数组
a.类型[]
let arr1:string[];
arr1 = ["a","b","c"];
b.Array<类型>
let arr2:Array<number> ;
arr2 = [1,2,3];
2)元组(tuple)
let arr3:[number,boolean,string,any]
arr3 = [2,true,"1",1];
区别:
数组:固定类型的数组;
元组:固定长度和类型的数组;
3.对象
1)Object
对象当中最重要的就是key:value。在属性名后面加上问号?意思是可有可没有
let person:{name:string,age?:number};
person = {name:"魔仙小蓝"}
2)枚举(enum)
就是把所有可能的情况列举出来
enum anmail{
rabbit,
dog
}
let obj1 :{name:string,kind:anmail};
obj1 = {
name:"旺财",
kind:anmail.dog
}
2.3总结
类型 | 表示 |
---|---|
字面量 | |
数值 | number |
bigint | bigint |
字符串 | string |
布尔值 | boolean |
空 | null |
未定义 | undefined |
不知道 | unknown |
任何类型 | any |
函数的返回值为undefined | viod |
函数的返回值(没有) | never |
数组 | Array |
元组 | tuple |
对象 | object |
枚举 | enum |
在基本数据类型上增加了any,unknown,复杂数据类型中,对于函数增加了对返回值的限制(void,never);数组增加了元组(tuple);对象增加了枚举(enum);
三、面向对象
3.1类(class)
类里面分为属性和方法;其中属性分为实例属性和静态属性,方法也同样分为实例方法和静态方法
class Person{
name:string = "佩奇";//实例属性
readonly age:number = 18;//实例属性
static sex:string ="男";//类属性(静态属性)
run(){
console.log("佩奇喜欢泥巴")
}
static say(){
console.log("佩奇叫起来是猪")
}
}
console.log(Person.sex)//类属性,不需要new
Person.sex ="女"
const p1 = new Person();//static开头的是实例属性,需要new
console.log(p1.name)
- 静态属性和静态方法前面要加static,静态属性不需要new(实例化)就可以直接访问
- 实例属性需要实例化,new
- readonly是只读
1.继承(extends)
constructor----构造函数
super---- 如果在子类中写了构造函数,在子类构造函数中必须对父类的构造函数进行调用
abstract ---- 抽象类(抽象类和其他类区别不大,只是不能用来创建对象),写在方法前面的话,抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
// 定义抽象类(父类)
abstract class Animal{
name: string;
age: number;
constructor(name: string,age:number){
this.name = name;
this.age = age;
}
abstract say():void;
run(){
console.log("我能跑")
}
}
// 狗子
class Dog extends Animal{
kind:string;
constructor(name: string,age:number,kind:string){
super(name,age);
this.kind = kind;
}
say(){
console.log("汪汪汪")
}
}
const dog = new Dog("旺财",11,"狗");
console.log(dog,"狗子")
console.log(dog.run());
console.log(dog.say());
2.属性/方法的封装
class Person {
public name:string;
protected age:number;
private email:string = "31323232@qq.com";
constructor(name:string,age:number){
this.name = name ;
this.age = age;
}
say(){
console.log(this.email,"邮箱为")
}
}
class New extends Person {
private sex:string = "男";
}
const yong = new New("余淮",20);
console.log(yong,"人")
yong.name = "耿耿"// public
console.log(yong,"人");
总结:属性前面的修饰符
- static 静态属性(类属性)
- readonly 可是可读的不能修改
- public(默认值),可以在类、子类和对象中修改
- protected(受保护的) ,可以在类、子类中修改
- private(私有的) ,可以在类中修改
ts对类的修改:加上了抽象类的概念,还有对属性的封装
3.2接口(interface)
- 接口是用来定义一个类的结构,有什么属性什么方法
- 接口中所有的属性只能定义类型不能赋值
- 接口中定义的方法是抽象方法
- 类可以实现(implements)接口
interface rules{
name:string,
color:string,
drink():void;
}
class naiCha implements rules{
name:string;
color:string;
constructor(name:string,color:string){
this.name = name;
this.color = color
}
drink(){
console.log("嘎嘎好喝")
}
}
const niXue = new naiCha("加薪水","red")
console.log(niXue)
3.3泛型
写函数或者类的时候刚开始不知道类型是什么,就可以用泛型
function sum<T>(num1:T,num2:T){
return (num1 > num2)
}
let res = sum<number>(100,2);