typescript(二)

1. 接口

1. 接口约束对象

接口可以约束对象的属性和其对应的类型。

interface Rectangle {
  readonly width: number,//该属性必须存在,且只读,不能被赋值
  height?: number,// 该属性可有可无
  [x: string]: any //对象的属性不确定个数
}
let myRec: Rectangle = {
  width: 10,
  age: 10,
  gender: 'female'
}

2. 接口约束数组

相当于对象的特殊形式。

interface MyArray{
  [x: number]: any
}
let arr: MyArray = [1,2];

3. 接口约束类的方法实现

接口中的方法都是抽象方法。类实现接口的时候,要将接口中的方法全部实现。

1. 一个类可以实现多个接口

interface Animal {
  eat(): void;
  run(): void; 
}
interface Person{
  speak(): void;
}
class Tom implements Animal,Person {
  eat() { }
  run() { }
  speak(){ }
}

2. 接口可以继承;类实现继承的接口时,要实现接口和接口继承的抽象方法。

interface Animal {
  eat(): void;
  run(): void;
}
interface Bird extends Animal{
  fly():void;
}
// 要实现接口本身的抽象方法,还要实现继承的抽象方法
class Tommy implements Bird {
  eat() {}
  run() {}
  fly(){}
}

4. 接口约束类(构造函数)的参数和静态方法

interface UserInterface {
  new(name: string): User; // 指定构造函数必须传参
  age: number //类上的属性,即静态属性
}
class User {
  constructor(public name: string){} //public也可以不存在
  static age = 10;
  /*
    使用public后,相当于
    name: string;
    constructor(name: string) {
      this.name: name;
    }
  */
}
function generateInstance(targetClass: UserInterface, name: string) {
  return new targetClass(name);
}
generateInstance(User, 'lyra');
console.log(generateInstance(User, 'lyra'))

5. 接口约束函数

1. 约束函数表达式的变量

interface DiscountInterface {
  (price:number):number
}
let discount:DiscountInterface = function(price: number):number {
  return price*0.8
}

当参数个数不确定时

interface SumInterface{
  (...args:Array<number>): number
}
let sum = function(...args: number[]):number {
  return args.reduce((a,b) => a+b , 0);
}

2. 类数组

和数组一样具有索引,可以通过索引访问。但是本质上又不是数组的类型。

//1. 函数参数类型IArguments
function sum(): void {
  let args: IArguments = arguments;
}
// 2. HTMLCollection
let root = document.getElementById('root');
let children: HTMLCollection = (root as HTMLElement).children;

// 3. NodeList
  let childNodes: NodeList = root!.childNodes;

3. 泛型

泛型指的是当声明函数,接口或者类时,不预先指定具体的类型,到调用的时候再指定的特性。

1. 默认泛型

<T = number>中的number类型为默认泛型的类型。

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

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

2. 泛型类

泛型类指的是用到了泛型的类

class MyArray<T>{
  private list: T[] = [];
  add(element: T):void {
    this.list.push(element);
  }
  getMax(): T {
    let maxValue = this.list[0];
    for(let i=0; i<this.list.length; i++) {
      if(maxValue < this.list[i]) {
        maxValue = this.list[i];
      }
    }
    return maxValue;
  }
}
// 测试用例
const arr = new MyArray<number>();
arr.add(1);
arr.add(2);
arr.add(3);
console.log(arr.getMax()); // 3

3. 泛型接口

泛型接口即使用了泛型的接口。

1. 可以用来约束函数。

interface Calculator {
  <T>(temp: T): T
}

// 测试用例
let test: Calculator = function(temp) {
  return temp;
}

2. 定义接口的时候也可以使用泛型。

interface Cart<T> {
  list: T[]
}
let cart: Cart<number> = {list: [1,2,3]}

4. 多个泛型

/**
 * 用于不使用中间变量交换数据
 * A、B都是自定义变量名
 */

function swap<A,B>(temp: [A, B]): [B, A] {
  return [temp[1], temp[0]];
}

console.log(swap([1, 'a']))

5. 泛型约束

对泛型进行约束

interface LoggerType {
  length: number
}
// 该泛型继承了接口,即该类型必须含有length属性
function logger<T extends LoggerType>(val: T) {
  return val.length;
}
// 测试用例
console.log(logger('hello'));// 5
console.log(logger(true)); //❌ true,布尔类型不具有length属性

6. 泛型的别名-type

适用于联合类型(即多种类型的组合)或者元组类型。类型别名不能使用extends和implements。

// 既可以是含length属性的对象,也可以是数组
type Cart2<T> = {length: T[]} | T[];
let c1:Cart2<number> = {length: [1,2,3]};
// 也可以是
let c2: Cart2<number> = [1,2,3];

 

posted @ 2020-01-03 23:50  Lyra李  阅读(249)  评论(0编辑  收藏  举报