一、静态类型
使用了静态类型,变量的类型不能改变,类型的属性和方法也跟着确定。
interfaceXiaoJieJie{
uname:string,
age:number
}
constxiaohong:XiaoJieJie={
uname:'xiaohong',
age:18
}
基础静态类型
对象类型:对象、数组、类、函数
constcount:number=918;
constmyName:string='cq';
// null, undefined, boolean, void, symbol 基础静态类型
// 对象类型、数组、类、函数
constxiaojiejie: {
name:string,
age:number
}={
name:'cq',
age:23
}
constxiaojiejies:string[]=['cq1','cq2','cq3']
classPerson{ }
constdajiao:Person=newPerson()
constjianxiaojiejie: ()=>string=()=>{
return'dajiao'
}
二、类型注释和类型推断
类型注释
letcount:number;
count=123
functiongetTotal(one:number,two:number) {
returnone+two;
}
consttotal=getTotal(1,2);
类型推断
letone=1;
lettwo=2;
constthree=one+two;
constXiaojiejie={
name:'nancy',
age:23,
}
每个变量,每个对象的属性都是固定的,如果能推断就让它推断,推断不出来的时候需要进行类型注释。
三、函数的参数定义和返回值定义
给函数的返回值加上类型注释
// 数值类型返回值的函数
functiongetTotal5(one:number,two:number):number{
returnone+two;
}
// 没有返回值的函数
functionsayHello():void{
console.log('hello');
}
// never返回值类型(执行不完)
functionerrorFunction():never{
thrownewError();
console.log('hello');
}
functionforNever():never{
while(true) { }
console.log('hello');
}
函数参数为对象对,需要解构对类型进行注释
// 参数为对象
functionadd({one,two}: {one:number,two:number}) {
returnone+two;
}
四、数组类型的定义
一半数组类型的定义
constnumberArr:number[]=[1,2,3];
conststringArr:string[]=['1','2'];
constundefinedArr:undefined[]=[undefined];
constarr: (number|string)[]=[1,'111'];
数组中对象类型的定义
constxiaogege: {name:string,age:number}[]=[
{
name:'Jarry',
age:10,
},
{
name:'Tom',
age:8,
}
]
类型别名 type alias
typePeople={name:string,age:numebr};
classLady={
name:string;
age:number;
}
constxiaogege:People[]=[
{
name:'Jarry',
age:10,
}
]
constxiaojiejie:Lady[]=[
{
name:'Nancy',
age:15,
}
]
五、元组的使用和类型约束
元组可以把数组中每个元素类型的位置固定
constxiaojiejie: [string,string,number]=['dajiao','teacher',28]
元组的使用
constarray: [string,string,number][]=[
['a','b',12],
['c','d',19],
]
六、interface 接口
接口的定义和使用
interfaceBoy{
name:string;
age:number;
height:number;
waistline?:number;// 可选值
}
constscreenResume=(boy:Boy)=>{
const{age,name,height}=boy;
age<30&&height>180&&console.log(name+' pass');
(age>30||height<180)&&console.log(name+' refuse');
}
constgetResume=(boy:Boy)=>{
const{age,name,height,waistline}=boy;
console.log(name+'年龄是'+age);
console.log(name+'身高是'+height);
waistline&&console.log(name+'腰围是'+waistline);
sex&&console.log(name+'性别是'+sex);
}
constboy={
name:'Tom',
age:28,
height:185,
}
screenResume(boy);
getResume(boy);
接口可以约束类
interfaceBoy{
name:string;
age:number;
height:number;
waistline?:number;// 可选值
[propname:string]:any,// key字符串类型,value任意类型
say():string,// say()方法,返回值为string类型
}
classXiaogegeimplementsBoy{
name:'LiuTao';
age:26;
height:183;
say: ()=>{
return'hello';
},
}
接口的继承
// 接口的继承
interfaceTeacherextendsBoy{
teach():string
}
constboy={
name:'Tom',
age:28,
height:185,
waistline:100,
sex:'男',
say: ()=>{
return'hello';
},
teach: ()=>{
return'teach';
}
}
七、类的概念和使用
类的基本使用和继承
classLady{
content='hi';
sayHello() {
returnthis.content;
}
}
classXiaojiejieextendsLady{
// 重写父类的方法
/* sayHello() {
return 'hello';
} */
// 重写并调用父类的方法
sayHello() {
returnsuper.sayHello()+' 你好';
}
sayLove() {
return'love you';
}
}
constNancy=newXiaojiejie();
console.log(Nancy.sayHello());
console.log(Nancy.sayLove());
八、类的访问类型
public 公共的,默认访问类型,允许在类的内部和外部被调用
private 私有的,只允许在类的内部被调用
protected 被保护的,允许在类的内部及继承的子类中使用
classPerson{
protectedname:string;
publicsayHello() {
console.log(this.name+' say hello')
}
}
classTeacherextendsPerson{
publicsayBye() {
console.log(this.name+'say bye')
}
}
九、类的构造函数
定义一个类,类里面有一个name,不给值。使用构造函数在new出对象的时候,通过传递参数的形式,name赋值。
classPerson{
publicname:string
constructor(name:string){
this.name=name;
}
}
constperson=newPerson('cq')
// 简单的写法
clasaPerson{
constructor(publicname:string){}
}
类继承中的构造器写法,在子类中使用构造函数必须用super调用父类的构造函数。如果需要传值,也必须进行传值操作。就算是父类没有构造函数,子类也要使用super()进行调用,否则会报错
classPerson{
constructor(publicname:string){}
}
classTeacherextendsPerson{
constructor(publicage:number){
super('cq')
}
}
constteacher=newTeacher(18)
十、TypeScript 类的Getter、Setter、static和readonly使用
用private封装一个属性,然后通过Getter和Setter的形式来访问和修改这个属性。
classXiaojiejie{
constructor(private_age:number){
}
getage(){
returnthis._age-10;
}
setage(age:number){
this._age=age+3;
}
}
constdajiao=newXiaojiejie(28);
console.log(dajiao.age)18
// _age是私有的,类的外部没办法改变,可以用setter属性进行改变
dajiao.age=25;
console.log(dajiao.age);18
类中的static,用static声明的属性和方法,不需要进行声明对象,就可以直接使用。
classGirl(){
staticsayLove(){
return'Love you';
}
}
console.log(Girl.sayLove());
readonly只读属性,在实例化对象时赋值,以后不能再更改。
classPerson{
publicreadonly_name:string;
constructor(name:string){
this._name=name;
}
}
constperson=newPerson('cq');
// 报错,因为_name是只读属性,不能修改
person._name='cqq''
console.log(person._name);
十一、抽象类
抽象类跟父类很像,都需要继承,但是抽象类中有抽象方法。继承抽象类必须实现抽象方法才可以,抽象类的关键词是abstract,里面的抽象方法也是abstract开头。
abstractclassGirl{
abstractskii()// 没有具体的实现
}
classTeacherextendsGirl{
skill(){
console.log('教师')
}
}
classWaiterextendsGirl{
skill(){
console.log('服务员')
}
}
十二、联合类型和类型保护
联合类型:可以认为一个变量可能有两种或者两种以上的类型。
interfaceWaiter{
anjiao:boolean;
say: ()=>{};
}
interfaceTeacher{
anjiao:boolean;
skill: ()=>{};
}
functionjudgeWho(animal:Waiter|Teacher){
// 报错:因为animal可能是Waiter可以能是Teacher
animal.say();
}
类型保护-类型断言
interfaceWaiter{
anjiao:boolean;
say: ()=>{};
}
interfaceTeacher{
anjiao:boolean;
skill: ()=>{};
}
functionjudgeWho(animal:Waiter|Teacher){
if(animal.anjiao){
(animalasTeacher).skill()
}
else{
(animalasWaiter).say();
}
}
类型保护-in语法
functionjudgeWho(animal:Waiter|Teacher){
if("skill"inanimal){
animal.skill();
}else{
animal.say();
}
}
类型保护-typeof语法
functionadd(first:string|number,second:string|number){
// 报错:这两个参数可能是数字,也可能是字符串,不做类型保护就相加会报错。
returnfirst+second;
}
functionadd(first:string|number,second:string|number){
// 使用typeof解决
if(typeoffirst==='string'||typeofsecord==='string'){
return`${first}${second}`;
}
returnfirst+second;
}
类型保护-instanceof语法
// 如果类型保护一个对象,使用instanceof语法
classNUmberObj{
count:number;
}
functionaddObj(first:object|numberObj,second:object|numberObj){
if(firstinstanceofNumberObj&&secondinstanceofNumberObj){
returnfirst.count+second.count;
}
return0;
}
十三、TypeScript 函数泛型-难点
generic 通用、泛指的意思,泛型使用<>定义。
给join方法一个泛型,名字随便起,后边的参数也是用泛型的名称。在正式调用这个方法的时候,具体指明泛型的类型。
functionjoin<T>(first:T,second:T){
return`${first}${second}`;
}
join<string>('baidu','com')
泛型中数组的使用,第一种直接使用[],第二种使用Array<泛型>
functionmyFun<ANY>(paramsANY[]){
returnparams;
}
// 第二种写法
functionmyFun<ANY>(paramsArray<ANY>){
returnparams;
}
myFun<string>['123','234'];
多个泛型的定义
functionjoin<T,P>(first:T,second:P){
return`${first}${second}`
}
join<number,string>(1,'2')
泛型的类型推断
functionjoin<T,P>(first:T,second:P){
return`${first}${second}`
}
join(1,'2');
十四、TypeScript 类中泛型-难点
classSelectGirl<T>{
constructor(privategirls:T[]){}
getGirl(index:number):T{
returnthis.girls[index];
}
}
constselectGirl=newSelectGirl()<string>['q','d','h']
泛型中的继承
interfaceGirl{
name:'string';
}
classSelectGirl<TextendsGirl>{
constructor(privategirls:T[]){}
getGirl(index:number):string{
returnthis.girls[index].name;
}
}
constselectGirl=newSelectGirl([
{name:'a'},
{name:'b'},
{name:'c'},
])
console.log(selectGirl.getGirl(1));
泛型的约束
classSelectGirl<Textendsnumber|string>{
constructor(privategirls:T[]){}
getGirl(index:number):T{
returnthis.girls[index];
}
}
constselectGirl=newSelectGirl<string>(['a','b','c')
console.log(selectGirl.getGirl[1]);