6. TypeScript—元组
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。
元组中允许存储不同类型的元素,元组可以作为参数传递给函数。
用法举例:定义一对值分别为 string 和 number 的元组:
//定义了一个有字符串和数字的的元组,下面是正确写法: let tom: [string, number] = ['Tom', 25]; console.log(tom[1]) //当当定义了存2个值,却是3个值时就会编译报错,如下: let tom: [string, number] = ['Tom', 25, 123]; console.log(tom[1]) //内容的类型和定义的顺序不一样,也会编译报错,如下 let tom: [string, number] = [ 25,'Tom']; console.log(tom[1])
元组运算
我们可以使用以下两个函数向元组添加新元素或者删除元素:
push()
向元组添加元素,添加在最后面。
pop()
从元组中移除元素(最后一个),并返回移除的元素。
解构元组
我们也可以把元组元素赋值给变量,如下所示:
let a =[10,"haiexijun"] let [b,c] = a console.log( b ) console.log( c )
7. TypeScript—接口
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。接口一般首字母大写。有的编程语言中会建议接口的名称加上 I 前缀。
TypeScript 接口定义如下:
interface interface_name { }
以下实例中,我们定义了一个接口 IPerson,接着定义了一个变量 customer,它的类型是 IPerson。
customer 实现了接口 IPerson 的属性和方法。
interface IPerson { firstName:string, lastName:string, sayHi: ()=>string } let customer:IPerson = { firstName:"zhang", lastName:"chao", sayHi: ():string =>{return "Hi there"} } console.log("Customer 对象 ") console.log(customer.firstName) console.log(customer.lastName) console.log(customer.sayHi())
联合类型和接口
interface RunOptions { program:string; commandline:string[]|string; }
接口和数组
接口中我们可以将数组的索引值和元素设置为不同类型,索引值可以是数字或字符串。
设置元素为字符串类型,如果使用了其他类型会报错:
interface namelist { [index:number]:string } // 类型一致,正确 let list2:namelist = ["Google","CSDN","Taobao"] //类型不一致,错误。编译会报错 let list2:namelist = ["haiexijun",1,"Taobao"]
接口继承
接口继承就是说接口可以通过其他接口来扩展自己。Typescript 允许接口继承多个接口。继承使用关键字 extends。
单继承接口例子:
interface Person { name: string; age: number; } let tom: Person = { name: 'Tom', age: 25 };
多继承举例:
interface IParent1 { v1:number } interface IParent2 { v2:number } interface Child extends IParent1, IParent2 { }
接口的可选属性
interface Person { name: string; age?: number; } //可以不给age属性赋值 let tom: Person = { name: 'Tom' };
接口的任意属性
有时候我们希望一个接口允许有任意的属性,可以使用如下方式:
interface Person { name: string; age?: number; [propName: string]: any; } let tom: Person = { name: 'Tom', gender: 'male' };
使用 [propName: string] 定义了任意属性取 string 类型的值。
需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集
接口的只读属性
有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性:
interface Person { readonly id: number; name: string; age?: number; [propName: string]: any; }
8. TypeScript—类
TypeScript 是面向对象的 JavaScript。类描述了所创建的对象共同的属性和方法。TypeScript 支持面向对象的所有特性,比如 类、接口等,
ES6的语法也有类class的概念。
ES6 中类的用法
属性和方法
使用 class 定义类,使用 constructor 定义构造函数。通过 new 生成新实例的时候,会自动调用构造函数。
class Animal { public name; constructor(name) { this.name = name; } sayHi() { return `My name is ${this.name}`; } } let a = new Animal('害恶细君'); console.log(a.sayHi()); // My name is 害恶细君
类的继承
使用 extends
关键字实现继承,子类中使用 super
关键字来调用父类的构造函数和方法。
class Cat extends Animal { constructor(name) { super(name); // 调用父类的 constructor(name) console.log(this.name); } sayHi() { return 'csdn, ' + super.sayHi(); // 调用父类的 sayHi() } } let c = new Cat('haiexijun'); // haiexijun console.log(c.sayHi()); // csdn, My name is haiexijun
存取器
使用 getter 和 setter 可以改变属性的赋值和读取行为:
class Animal { constructor(name) { this.name = name; } get name() { return 'Jack'; } set name(value) { console.log('setter: ' + value); } } let a = new Animal('Kitty'); // setter: Kitty a.name = 'Tom'; // setter: Tom console.log(a.name); // Jack
静态方法
使用 static
修饰符修饰的方法称为静态方法,它们不需要实例化,而是直接通过类来调用:
class Animal { static isAnimal(a) { return a instanceof Animal; } }
静态属性
可以使用 static
定义一个静态属性:
class Animal { static num = 42; constructor() { // ... } } console.log(Animal.num); // 42
TypeScript 中类的用法
TypeScript 可以使用三种访问修饰符,分别是 public
、private
和 protected
。
class Animal { public name; public constructor(name) { this.name = name; } } let a = new Animal('Jack'); console.log(a.name); // Jack a.name = 'Tom'; console.log(a.name); // Tom
上面的例子中,name 被设置为了 public,所以直接访问实例的 name 属性是允许的。
很多时候,我们希望有的属性是无法直接存取的,这时候就可以用 private 了:
class Animal { private name; public constructor(name) { this.name = name; } } let a = new Animal('Jack'); console.log(a.name);//编译报错 a.name = 'Tom';//编译报错
使用 private 修饰的属性或方法,在子类中也是不允许访问的,这里就不演示了。如果是用 protected 修饰,则允许在子类中访问。当构造函数修饰为 private 时,该类不允许被继承或者实例化。当构造函数修饰为 protected 时,该类只允许被继承。
类的类型
class Animal { name: string; constructor(name: string) { this.name = name; } sayHi(): string { return `My name is ${this.name}`; } } let a: Animal = new Animal('Jack'); console.log(a.sayHi()); // My name is Jack