继续学习Typescript
1.定义类型
- 数组类型
创建一个数组元素,并给其设置类型,跟昨天的方法是一致的,这里有两种写法
//数组类型
let arr: number[] = [1, 2, 3, 4, 56, 8]
//泛型写法
let arr1: Array<number> = [1, 2, 3, 4, 5, 6, 7, 8]
- 函数类型
创建一个函数并给函数中每一个值以及整个函数最后输出的结果设置类型
function sum(x: number, y: number): number {
return x + y
}
2.类型的断言
此时定义两个接口,两个接口中分别有不同类型的属性。但通过函数调用两个接口时,只需要用到其中一个类型时,编译会报错。因此采用断言 as ,用于告诉编译器只采用其中一属性
//分别定义的两个接口
interface dog {
name: string
run(): void
}
interface fish {
name: string
swim(): void
}
//在函数中只需要采用dog中的全部属性
function isDog(animal: dog | fish) {
//if(aniaml.run){}若这样写,编译器会报错
//此时需要加上括号并标注采用哪个接口的属性即可
if ((animal as dog).run) {
return true
} else {
return false
}
}
断言的使用有相关的原则方法:
- 聚合类型可以断言为其中类型
- 父类可以断言为子类
- 任何类型可以断言为any类型
- any类型可以断言为任意类型
3.类型
- 类型取别名
为了更加方便使用多个类型时不需要反复重复的设置类型,因此可以通过设置 type 给类型取上别名
type NewString = string
let username: NewString = '123'
//设置多个类型,此时在使用这个别名时,数据可以是字符串或是数字
type BothString = string|number
//也可以定义字符串
type EventName = 'click' | 'move'
let test: EventName = 'click'
}
- 枚举类型
指的是通过enum设置类型的取值被限定在一定的范围内,超出这个范围都会报错
enum Number {1,2,3,4,5,6,7}
//若取值超出Number中的值即会报错
4.类
- TS中的类使用的三个用法
public
是共有的,所有地方都可以被访问
class Gelx {
public name;
public constructor(name) {
this.name = name;
}
}
let test = new Gelx('吴亦凡');
console.log(test.name); // 吴亦凡
//此时允许再次修改name值
test.name = '帅哥';
console.log(test.name); // 帅哥
private
是私有的,不能在声明它的类的外部访问(子类也不可以)。若构造类也是private
,则这个类不能被继承或者实例化
class Gelx {
private name;
public constructor(name) {
this.name = name;
}
}
let test = new Gelx('吴亦凡');
console.log(test.name); // 吴亦凡
//此时不允许再次修改name值
test.name = '帅哥';
console.log(test.name); // 编译器报错
protected
是受保护的,允许在子类中访问。若构造函数修饰为protected
时,该类只允许被继承
class Gelx {
protected name;
public constructor(name) {
this.name = name;
}
}
//此时子类可以正常访问name值
class Test extends Gelx{
constructor(name) {
super(name);
console.log(this.name)
}
}
- 类的属性
在上述的代码中,其实可以再次简化代码,直接设置参数的属性
class Gelx {
public constructor(public name) {
}
}
也可以通过readonly
设置参数是否只读
class Gelx {
readonly name;
public constructor(name) {
this.name = name;
}
}
//此时只能第一次创建的时候赋值,不可再次更改
let test = new Gelx('吴亦凡');
console.log(test.name); // 吴亦凡
//若想再次更改,则会报错
test.name = '帅哥';
- 抽象类
抽象类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');
4.类与接口
类可以通过implements
实现接口,并且通过逗号间隔,可以师姐与载入多个接口
interface Alarm {
alert(): void;
}
class Door {
}
class SecurityDoor extends Door implements Alarm {
alert() {
console.log('SecurityDoor alert');
}
}
class Car implements Alarm {
alert() {
console.log('Car alert');
}
}
5.泛型
泛型可以使定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
function createArray(length: number, value: any): Array<any> {
let result = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
正常的函数可以这样写,但会有一个缺陷在于value和整个数组返回的类型都是any,一但函数变得复杂起来,有可能回出现value和返回的Array不是同一类型。因此需要采用泛型来解决这个问题
通过加上T来实现对属性的(我个人称之为预定属性),在需要调用该函数时,即可设置需要返回的值的类型,即可确保输入输出的数据类型保持一致。
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}