TypeScript 高级类型

学习目标:

TS 中的高级类型有很多,重点学习以下高级类型:

1. class 类

2. 类型兼容性

3. 交叉类型

4. 泛型 和 keyof

5. 索引签名类型 和 索引查询类型

6. 映射类型

//以下只说明了class类,需要其他的请跳转主页TypeScript

目录

学习目标:

class 类

class的基本使用

为class类添加属性(实例属性初始化)

构造函数

实例方法

类的继承

extends(继承父类)

implements(实现接口)

可见性修饰符

public

protected

private

readonly



class 类

class的基本使用

TypeScript 全面支持 ES2015 中引入的 class 关键字,并为其添加了类型注解和其他语法(比如,可见性修饰符等)
//class的基本使用

class Person{}

const p = new Person()


// 解释:

// 1. 根据 TS 中的类型推论,可以知道 Person 类的实例对象 p 的类型是 Person。

 

// 2. TS 中的 class,不仅提供了 class 的语法功能,也作为一种类型存在。

为class类添加属性(实例属性初始化)

// 实例属性初始化:

class Person2{
  age: number

  //ts中的类型推断会推断gender类型为string

  gender = '女'
}

const p2 = new Person2();

console.log(p2.age);
console.log(p2.gender);//女

// 解释:

// 1. 声明成员 age,类型为 number(没有初始值)。

// 2. 声明成员 gender,并设置初始值,此时,可省略类型注解(TS 类型推论 为 string 类型)。

构造函数

// 构造函数:

class Person3{
  age: number
  gender: string

  constructor(age: number, gender:string){
    this.age = age;
    this.gender = gender
  }
}

const p3 = new Person3(20,'男');
console.log(p3.age,p3.gender);//20 男

// 解释:

// 1. 成员初始化(比如,age: number)后,才可以通过 this.age 来访问实例成员。

// 2. 需要为构造函数指定类型注解,否则会被隐式推断为 any;构造函数不需要返回值类型

实例方法

// 实例方法:

class Point {
  x = 10
  y = 20

  scale(num: number):void {
    this.x *= num
    this.y *= num
  }
}

//new的是一个方法
const pi = new Point()
pi.scale(10)//放大10倍
console.log(pi.x,pi.y)//100 200
// 解释:方法的类型注解(参数和返回值)与函数用法相同

// 解释:方法的类型注解(参数和返回值)与函数用法相同

类的继承

类继承的两种方式:1 extends (继承父类) 2 implements (实现接口)。
说明:JS 中只有 extends,而 implements 是 TS 提供的。

extends(继承父类)


//父类
class Animal {
  move(){
    console.log(' 动物 ! ')
  } 
}
//子类
class Dog extends Animal {
  name = '中华田园狗'
  bark(){
    console.log(' 狗叫 ! ')
  }
}

const d = new Dog()
d.move(); // 动物 ! 
d.bark() // 狗叫 !
console.log(d.name) //中华田园狗

// 解释:

// 1. 通过 extends 关键字实现继承。

// 2. 子类 Dog 继承父类 Animal,则 Dog 的实例对象 dog 就同时具有了父类 Animal 和 子类 Dog 的所有属性和方法。


 

implements(实现接口)

interface Singable {
  name : string
  sing(): void
}

class Person4 implements Singable{
  name = 'zys'
  sing() {
    console.log('敲代码不如唱歌 ')
  }
}

const  p4 = new Person4()
console.log(p4.name)//zys
p4.sing()//敲代码不如唱歌 

// 解释:

// 1. 通过 implements 关键字让 class 实现接口。

 

// 2. Person 类实现接口 Singable 意味着,Person 类中必须提供 Singable 接口中指定的所有方法和属性

例如:

如果Person 类中没有实现接口中的所有属性和方法则会报错

可见性修饰符

类成员可见性:可以使用 TS 来 控制 class 的方法或属性对于 class 外的代码是否可见
可见性修饰符包括:1 public(公有的) 2 protected (受保护的) 3 private (私有的)。

public

public:表示公有的、公开的, 公有成员可以被任何地方访问 ,默认可见性

class Animal {
  public move(){
    console.log(' 公共类中的动物 ! ')
  } 
}

const Am = new Animal()
Am.move();//公共类中的动物

// 解释:

// 1. 在类属性或方法前面添加 public 关键字,来修饰该属性或方法是共有的。

// 2. 因为 public 是默认可见性,所以,可以直接省略。

protected

protected :表示 受保护的 ,仅对其 声明所在类和子类中 (非实例对象)可见。
 
// protected(受保护的)
//父类
class Animal3 {
  protected move(){
    console.log(' 受保护的动物  ')
  } 

  run() {
    console.log('凑数的')
    //同个类中掉用 move方法
    this.move()
  }
}
//子类
class Dog extends Animal3 {
  bark(){
    console.log(' 狗  ')
    //子类中调用 move方法
    this.move()
  }
}

const dd = new Do();
dd.run() //  凑数的   受保护的动物
dd.bark()  // 狗   受保护的动物

 

// 解释:

// 1. 在类属性或方法前面添加 protected 关键字,来修饰该属性或方法是受保护的。

// 2. 在子类的方法内部可以通过 this 来访问父类中受保护的成员,但是,对实例不可见

例如:实例方法move会报错

private

private :表示 私有的 只在当前类中可见(只能在本类中使用) ,对 实例对象以及子类也是不可见的

// 私有的private

// 父类
class Fu {
  // 私有的  这里的__run__ 命名类似于python 合法的
  private __run__() {
    console.log('Animal 内部辅助函数')
  }

  // 受保护的
  protected move() {
    this.__run__()
    console.log('走两步')
  }

  // 公开的
  public run() {
    this.__run__()
    this.move()
    console.log('跑起来')
  }
}
//实例化父类
const a = new Fu()
// a.__run__()  //报错

// 子类
class Zi extends Fu {
  bark() {
    // this.__run__()  //报错
    console.log('旺旺!')
  }
}
//实例化子类
const dg = new Zi()
// dg.__run__()  //报错

实例对象

//实例化父类

//实例化子类

// 解释:

// 1. 在类属性或方法前面添加 private 关键字,来修饰该属性或方法是私有的。

// 2. 私有的属性或方法只在当前类中可见,对子类和实例对象也都是不可见的!

 

readonly

除了可见性修饰符之外,还有一个常见修饰符就是: readonly(只读修饰符)
readonly :表示 只读 用来防止在构造函数之外对属性进行赋值
 // 注意:只要是 readonly 来修饰的属性,必须手动提供明确的类型

class Person5 {
  //只读属性
  // 注意:只要是 readonly 来修饰的属性,必须手动提供明确的类型
  readonly age: number = 18

  constructor(age: number) {
    this.age = age;
  }

  //错误演示:
  // readonly setAge(){
  //   this.age = age
  // }

}

// 解释:

// 1. 使用 readonly 关键字修饰该属性是只读的,注意只能修饰属性不能修饰方法

 // readonly  修饰符  表示 只读 使用在普通方法中无法就行赋值, 用来防止在构造函数之外对属性进行赋值
// readonly  修饰符只能用于属性, 不能修饰方法

// 2. 注意:属性 age 后面的类型注解(比如,此处的 number)如果不加,则 age 的类型为 18 (字面量类型)。

class Person6 {

  //错误演示:
  readonly age = 18
  //使用readonly 修饰属性时,如果这个属性有默认值,则一定要指定其类型
  //否则会根据类型推断, 推断 age 为 18 这个类型,而不是number
 
  constructor(age: number) {
  
    //this.age = age; //报错
  }

}

 

又如果 使用readonly(只读修饰符)为 age 时没有定义类型,又没定义默认值

此时的 age 为any类型

class Person7 {
  //错误演示:
  readonly age 
  //age 为any类型

}

 

// 3. 接口或者 {} 表示的对象类型,也可以使用 readonly。

接口

//接口
interface IPerson{
//readonly 只读不能修改
  readonly name: string
}

let obj: IPerson = {
  name: 'zys'
}
//错误示范:
// obj.name = 'rose'
//无法为“name”赋值,因为它是只读属性。

对象类型{}

//{} 表示的对象类型

let object: { readonly name: string} = {
  name: 'jack'
}

//错误示范:
//无法为“name”赋值,因为它是只读属性。
// obj.name = 'rose'

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值