TypeScript学习笔记(二)

1、字符串字面量类型

type EventNames = 'click' | 'scroll' | 'mouseover'

字符串字面量类型用来约束取值只能是某几个字符串中的一个

2、元祖(Tuple)

数组:同一类型的集合
元祖:不同类型的集合

let value: [string, number] = ['xiaoming', 18]

3、枚举(Enum)

枚举使用 enum 关键字来定义

eunm Colors {White, Black, Red}

枚举成员会被赋值为从 0 开始递增的数字,同时也会对枚举值到枚举名进行反向映射

console.log(Colors['White']) // 0
console.log(Colors['Black']) // 1
console.log(Colors['Red']) // 2

可以给枚举项手动赋值:

eunm Colors {White = 7, Black = 2, Red}

console.log(Colors['White']) // 7
console.log(Colors['Black']) // 2
// 未手动赋值的枚举项会接着上一个枚举项递增
console.log(Colors['Red']) // 3

未手动赋值的枚举项与手动赋值的重复时,会被后赋值的那一次覆盖。

上面的例子都是常数项,下面是一个计算所得项的例子:

eunm Colors {White, Black, Red = 'Red'.length}

注意:如果紧接在计算所得项后面的是未手动赋值的项,那么它就会因为无法获得初始值而报错

常数枚举

常数枚举使用 const enum 定义,不能包含计算成员

const enum Colors {
	White,
	Black,
	Red
}

外部枚举

外部枚举使用 declare enum 定义,常出现在声明文件中,declare 定义的类型只会用于编译时的检查,编译结果中会被删除

4、类

TypeScript可以使用三种访问修饰符(修饰属性或方法):

  • public:修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是public的
  • private:修饰的属性或方法是私有的,不能在声明它的类的外部访问;当构造函数修饰为 private 时,该类不允许被继承或者实例化
  • protected:修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的;当构造函数修饰为 protected 时,该类只允许被继承

以上三种修饰符和readonly关键字还可以用在构造函数的参数中,等同于类中定义该属性并同时给该属性赋值

class Animal {
  // public name: string;
  public constructor(public name) {
    // this.name = name;
  }
}

readonly关键字

只读属性关键字,只允许出现在属性声明或索引签名或构造函数中。
readonly 和其他访问修饰符同时存在的话,需要写在其后面。

class Animal {
  readonly name;
  public constructor(name) {
    this.name = name;
  }
}

let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';

// index.ts(10,3): TS2540: Cannot assign to 'name' because it is a read-only property.

抽象类

使用abstract定义抽象类和其中的抽象方法,抽象类不允许被实例化,抽象类中的抽象方法必须被子类实现

abstract class Animal {
  public name;
  public constructor(name) {
    this.name = name;
  }
  public abstract sayHi();
}

class Cat extends Animal {
  public sayHi() {
    console.log(`Meow, My name is ${this.name}`);
  }
}

let cat = new Cat('Tom');

给类加上TS的类型

class Aniaml {
	name: string,
	constructor(name: string) {
		this.name = name
	}
	sayHi(): string {
		return 'Hello'
	}
}

let cat: Animal = new Animal('Tom')
console.log(cat.sayHi())

5、类与接口

接口的两个作用:

  • 用于对对象的形状进行描述
  • 对类的一部分进行抽象

类实现接口(implements)

interface Alarm {
    alert(): void;
}

interface Light {
    lightOn(): void;
    lightOff(): void;
}

class Car implements Alarm, Light {
    alert() {
        console.log('Car alert');
    }
    lightOn() {
        console.log('Car light on');
    }
    lightOff() {
        console.log('Car light off');
    }
}

接口继承接口

interface Alarm {
    alert(): void;
}

interface LightableAlarm extends Alarm {
    lightOn(): void;
    lightOff(): void;
}

接口继承类

在Java等面向对象的语言中,接口是不能继承类的,但是在TypeScript中可以:

class Point {
    x: number;
    y: number;
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
}

interface Point3d extends Point {
    z: number;
}

let point3d: Point3d = {x: 1, y: 2, z: 3};

接口继承类,实际上也是接口继承接口。
实际上,当我们声明class Point的时候,会同时做这件事:

  • 创建一个名为Point的类
  • 创建一个名为Point的类型
    所以我们既可以将Point当作一个类来用:
const p = new Point(1, 2)

也可以将Point当作一个类型来用:

let p: Point = {x: 1, y: 2}

在上面的例子中,interface Point3d extends Point Point3d继承的实际上是Point的实力的类型,可以按下面这个例子理解: Point3d 继承另一个接口 PointInstanceType

class Point {
    x: number;
    y: number;
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
}

interface PointInstanceType {
    x: number;
    y: number;
}

// 等价于 interface Point3d extends PointInstanceType
interface Point3d extends Point {
    z: number;
}

let point3d: Point3d = {x: 1, y: 2, z: 3};

注意:声明 Point 类时创建的 Point 类型只包含其中的实例属性和实例方法。同样的,在接口继承类的时候,也只会继承它的实例属性和实例方法。

6、泛型

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

function createArray<T>(length: number, value: T): Array<T> {
	let result: T[] = [];
	for(let i = 0;i < length; i++) {
		result[i] = value
	}
	return result;
}

createArray<string>(3, 'x'); // ['x', 'x', 'x']

使用泛型:函数名后添加 <T>

多个类型参数

function swap<T, U>(tuple: [T, U]): [U, T] {
    return [tuple[1], tuple[0]];
}

swap([7, 'seven']); // ['seven', 7]

在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法,这时,我们可以对泛型进行约束,只允许这个函数传入那些包含该属性的变量。这就是泛型约束:

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值