TypeScript

188 阅读8分钟

Ts

基本类型

1.布尔类型 boolean

let flag: boolean = false

2.数字类型 number

let a: number = 123

3.字符串类型 string

let str: string = 'this is string'

4.数组类型 array 定义数组两种方式

(1) 第一种

let arr: number[] = [1,2,3,4] 接收一个数组 数组里面的元素是对象类型 (实际开发) let arr1: {id:string,name:string}[]

(2) 第二种(泛型)

let arr: Array<number> = [1,2,3,4]

5.元组类型 tuple 属于数组得一种 可以定义数组里每一个元素得类型

let arr: [string,number,boolean] = ['字符串',123,false]

6.枚举类型 enum

定义得格式:

enum 枚举名 { 标识符[=整型常数], 标识符[=整型常数], ... 标识符[=整型常数], };

适用于参数映射表示 标识状态码

  0 未支付 1 支付 2 交易成功

enum Flag {success=1,error=-1} let f: Flag=Flag.success

定义的枚举值是可以赋值默认值得 如果没有给值 默认从下标值开始 如果赋值 这个值就是洗一个值得起始值

eg:

enum Color {red,blue=5,orange} let c: Color = Color.red let o: Color = Color.orange 打印c是0 o是6

7.任意类型 any

用处 给Dom节点添加样式 获取dom节点时使用

let oBox: any = document.getElementById('html)

8.空类型 null 和 undefined(其他类型(never类型)的子类型)

报错写法飘红

var num: number; console.log(num) 输出undefined 这个会飘红

正确写法

var num: undefined; console.log(num) 输出undefined 这个不会飘红

日常写法:存在或者不存在的写法 变量定义但没有被赋值

var num: number | undefined | null

9.void类型表示方法没有返回任何类型 一般是定义一个方法的时候没有返回值

function run(): void{ console.log('无任何返回') }

10.never类型 是其他类型(null和undefined)的子类型代表从不会出现的值

声明never的变量只能被never类型赋值 eg:

var a: undefined; a=undefined 不会报错 a=123 报错 var b: null; b=null 不会报错 b=123 报错 一般用于抛出异常错误 a:never a=(()=>{ throw new Error('错误') })()

Ts中函数的定义

第一种:入参和返回值都有定义类型

1.配置可选参数

function run (name:string,age?:number):string{
  return '字符串'
}

age可传可不传 ?配置可选参数

配置可选参数 可选的必须要放置参数的最后面!!!!

2.配置默认参数

function run (name:string,age:number=20):string{
  return '字符串'
}

调用时仍然可以传age参数,这个时候生效值是传入的值

  1. 配置剩余参数
function run (...result:number[]):string{
  return '字符串'
}
or
function run (a:number,b:number...result:number[]):string{
  return '字符串'
}
run(1,2,3,4,5) a就是1,b就是2 剩下的给result

4.函数重载 同(名函数)一个函数 传入不同的参数 实现不同的功能

  function getInfo(name: string): string;
  function getInfo(age: number): number;
  function getInfo(str: any): any{
   if(typeof str === 'string'){
        return `${str}`;
     }eles{
        return str;
     }
   }
   
   getInfo(20)

Ts中类的定义

定义一个类

class Person{

 name: string; // 定义属性
 
 constructor(n: string){ // 实例化类的时候触发的方法
  this.name=n;
 }
 
 run(): void{
  console.log(this.name)
 }
 
}

var p = new Person('张三');
p.run() // 打印 张三

继承一个类

class Person{

 name: string; // 定义属性
 
 constructor(n: string){ // 实例化类的时候触发的方法
  this.name=n;
 }
 
 run(): void{
  console.log(this.name)
 }
 
}

//继承
class Web extends Person {
 constructor(name: string){ // super必须要有
  super(name) // 用来调用父类的constructor方法 把name传过去 初始化父类的构造函数
 }
}

var w = new Web('李四')
w.run() // 打印 李四

子类里面也可以实现自己的方法

如果子类里面有一个方法和父类相同 那就执行子类里面的方法 先去找自己有没有这个方法 如果自己上没有找到这个方法 则去父类里面找

类里面的修饰符(默认是public公有的)

public:公有的 在当前类,子类,类外面都可以访问

protected: 受保护的 在当前类里面,子类里面可以访问 在类外面不可访问

private: 私有的 在当前类里面可以访问,子类 类外面都访问不了

静态属性 静态方法

是指直接挂载到类本身上的属性和方法 访问的时候直接是类获取而不是实例化之后获取方法和属性

eg(Es5里面的写法):

function Person(){
 this.run1=function(){
 console.log('不是静态的方法,构造函数里的方法')
   }
  }
Person.run2 = function(){
 console.log('静态方法')
 }
Person.name = '静态属性'
// 访问静态属性和方法
Person.name // 打印 静态属性
Person.run2() // 打印 静态方法

eg(ts中写静态方法和静态属性 静态方法里没法直接调用类里面的属性 要想在静态方法里面访问类的属性 那也要定义一个静态的属性)

class Per{
 public name: string;
 public age: number=20;
 static sex='男' // 静态属性
 constructor(name: string){
  this.name=name;
 }
 run(){
  console.log('实例的方法')
 }
 static print(){
  console.log(Per.sex,'访问类里面的静态属性')
  console.log('静态的方法',this.name) // 这个位置应该是undefined 只能访问静态的方法
 }
}
var p = new Per('入参')
Per.print()

多态 (父类定义一个方法不去实现,让继承他的子类去实现,每一个子类有不同的表现)属于继承的一种方式

eg:

// 父类 定义了一个eat方法 并没有具体实现
class Animal{
 name: string;
 constructor(name: string) {
  this.name=name
 }
 eat(){
  console.log('吃的方法')
 }
}
// 继承的子类去实现
class Dog extends Animal{
 constructor(name: string){
  super(name);
 }
 eat(){
  return this.name+'吃骨头'
 }
}

class Cat extends Animal{
 constructor(name: string){
  super(name);
 }
 eat(){
  return this.name+'吃鱼'
 }
}

抽象类(用abstract关键字来定义抽象类)

ts中的抽象类 是提供给其他类继承的基类 不能直接被实例化 他是来定义是继承的那个类里面的标准的(例如上一个例子,继承他的子类里面可以没有eat方法 但是如果是抽象类 那就必须要有这个抽象的方法)

用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现

抽象方法只能放在抽象类里面

eg:

abstract class Animal{
 name: string;
 constructor(name: string){
  this.name = name;
 }
 abstract eat(): any; // 抽象方法 这个方法必须要在子类实现 不是抽象的方法可以不实现
}

// 继承他的子类

class Dog extends Animal{
 constructor(name: string) {
  super(name);
 }
 eat(){
  return this.name+'吃骨头';
 }
}

// 继承他的子类
class Cat extends Animal {
 constructor(name: string){
  super(name);
 }
 eat(){
  return this.name+'吃鱼'
 }
}

Ts接口

ts中接口就是规范 定义行为和动作的规范 就是一种标准

1.属性接口

函数传入的参数是个对象 对传入的对象进行一个约束 对批量的方法进行约束

function printInfo(labelInfo:{label: string}):void{
  console.log(labelInfo,'传入的参数是对象类型')
}
// 调用 printInfo({label:'字符串'})

这个例子是一个函数的入参规范 如果有多个函数入参都是这个规范 那就需要接口来定义这个

eg属性接口:

// 这个就是传入的对象的约束 属性的接口定义
interface FullName{
  firstName: string; // 分号结束
  lastName: string;
}

// 具体实现
function printName(name:FullName){
 console.log(name.firstName+'--'+name.lastName)
}

// 调用 
var obj = {
 age:20,
 firstName: '张',
 lastName: '三'
}
printName(obj) // 这种方法ok
// 下面这个写法会报错 因为接口里面没有age 而上面那种写法 只要包含接口里面定义的就行 
printName({
 age:20,
 firstName: '张',
 lastName: '三'
})

2.可选属性接口

eg可选属性接口:

// 这个就是传入的对象的约束 属性的接口定义
interface FullName{
  firstName: string; // 分号结束
  lastName?: string; // 可传可不传
}

// 具体实现
function printName(name:FullName){
 console.log(name.firstName+'--'+name.lastName)
}

// 调用 
printName({
 firstName: '张',
})

3.函数类型接口

对方法传入的参数 以及返回值进行约束

eg函数类型接口:

interface encrypt {
 (key: string,value: string):string;
}

const md5:encrypt = function(key: string, value:string): string{
 return key+value;
}
console.log(md5('name','张三'))

4.可索引接口(对象/数组的约束 不常用

1.可索引对数组的约束

eg:

interface UserArr{
 [index: number]: string // 表示数组的索引值是number 数组里的每一个元素是string类型
}
var arr: UserArr = ['子1','子2']
console.log(arr[0]) 
2.可索引对对象的约束

eg:

interface UserObj{
 [index: string]: string // 表示是一个对象
}
var arr1: UserObj = {name:'张三'}

5.类类型接口 是对类的约束 和抽象类似 必须要实现这个里面的属性和方法

implements 实现 这个关键字(写法)

// 定义一个类的接口
interface Animal{
 name: string;
 eat(str: string): void;
}

// 类里面去用这个接口
class Dog implements Animal{
 name:string;
 constructor(name: string){
  this.name = name;
 }
 eat(){// eat里面不传参数也可以 但是这个方法必须要有
  console.log(this.name + '吃骨头')
 }
}

var d = new Dog('小黑')
d.eat()

接口的扩展 接口可以继承接口

eg:

// 定义一个父类接口
interface Animal{
 eat():void;
}

// 接口继承
interface Person extends Animal{
 work(): void;
}

// 创建一个父类
class Programmer {
 name: string;
 constructor(name: string){
  this.name=name
 }
 coding(code:string){
  console.log(this.name+code)
 }
}

// 继承父类 并且实现Person接口
class Web extends Programmer implements Person{
  constructor(name: string){
   super(name);
  }
  
  eat(){
   console.log(this.name+'吃零食')
  }
  work(){
   console.log(this.name+'写代码')
  } 
}

var w = new Web('小李')
w.eat();
w.coding('写ts代码')

Ts泛型

泛型就是解决 类 接口 方法的复用性

1.泛型函数

泛型表示 用T关键字表示 具体表示什么类型 是调用这个方法的时候决定的 传入的参数和返回的参数类型一样

eg:

function getData<T>(value: T):T{
 return value;
}
// 调用
getData<number>(123)

2.泛型类

eg:

// 创建一个类的泛型
class MinClass<T>{
 public list:T[]=[];
 add(value:T){
  this.list.push(value);
 }
 min():T{
  var minNum=this.list[0];
  for(var i=0;i<this.list.length;i++){
   if(minNum>this.list[i]){
    minNum=this.list[i];
   }
   return minNum;
  }
 }
}

// 实例化一个类
var m1 = new MinClass<number>() // 实例化一个类 并且指定了T代表的是number类型
m1.add(1);
m1.add(2);
console.log(m1.min())

3.泛型接口

1.eg:

inetrface Config{
  <T>(value:T):T;
}
var getData:Cofig = function<T>(value:T):T{
 return value;
}
getData<string>('张三')

2.eg:

inetrface Config<T>{
 (value:T):T;
}
function getData<T>(value:T):T{
 return value;
}

var myGetData:Config<string>=getData;
myGetData('20') //  正确调用的
myGetData(20)   //  错误调用的

4.把类作为参数类型的泛型类

麻烦的写法

class User{
  username:string | undefined;
  password:string | undefined;
}

class MysqlDb{
 add(user: User):boolean{
   return true;
 }
}

var u = new User();
u.username='kk';
u.password='123456';
var Db = new MysqlDb();
Db.add(u)

eg正常的写法:

class MysqlDb<T>{
 add(info:T):boolean{
  return true;
 }
 
 class User{
  username: string | undefined;
  password: string | undefined;
 }

var u = new User();
u.username='张三'
u.password='12344';
var Db = new MysqlDb<User>();
Db.add(u) // 正确写法
Db.add('ghhhh') // 错误写法