005--TypeScript接口

TypeScript里面的接口就是为了我们的变量类型或者代码做一些契约

function printLabel(labelObj: {label:string}) {
  console.log(labelObj.label)//Size 10 object
}

let myObj = {
  size: 10,
  label: 'Size 10 object'
}
printLabel(myObj)
//改成接口类型的
interface labeldValue {
  label: string
}
function printLabel(labelObj: labeldValue) {
  console.log(labelObj.label)//Size 10 object
}

let myObj = {
  size: 10,
  label: 'Size 10 object'
}
printLabel(myObj)

接口里面的可选属性 

interface Square {
  color: string
  area: number
}
interface SquareConfig {
  color?: string//?表示这个参数是可选的
  width?: number
}

function createSquare(config: SquareConfig): Square {
  let newSquare = {color: 'white', area: 100}
  if (config.color) {
    //因为参数是可选的,所以要做判断.
    //这样做的好处是,如果config.color拼错了就会提示
    newSquare.color = config.color
  }
  if (config.width) {
    newSquare.area = config.width * config.width
  }
  return newSquare
}
let mySquare = createSquare({color: 'black'})
console.log(mySquare)//{ color: 'black', area: 100 }

只读属性

interface Point {
  readonly x: number
  readonly y: number
}

let p1: Point = {x: 10,y: 20}//创建完以后就不能改变了
// p1.x = 6 //报错,因为是常数或者是只读属性

typeScript泛型只读数组

let a: number[] = [1, 2, 3, 4]

let ro: ReadonlyArray<number> = a
//ro[0] = 12//报错
//ro.push()//不存在属性push
//可以使用类型断言
a = ro as number []
//和const的区别,const是作为一个变量,readonly是作为一个属性

额外属性检查

上述第一个例子中我们多传了一个size字面量属性,并没有报错,因为传入了label值,符合预期

interface Square {
  color: string,
  area: number
}
interface SquareConfig {
  color?: string,//?表示这个参数是可选的
  width?: number
}

function createSquare(config: SquareConfig): Square {
  let newSquare = {color: 'white', area: 100}
  if (config.color) {
    //因为参数是可选的,所以要做判断.
    //这样做的好处是,如果config.color拼错了就会提示
    newSquare.color = config.color
  }
  if (config.width) {
    newSquare.area = config.width * config.width
  }
  return newSquare
}
let mySquare = createSquare({colorr: 'black', 100})
//这里我们的color拼错了
//这里报错,因为这里color是一个对象字面量,typeScript会对这种字面量做检查
//一旦发现传入的属性不在定义的属性当中就会报一个错误
//解决方式1 类型断言
//这种方式并不好
//let mySquare = createSquare({colorr: 'black', 100} as SquareConfig)
//解决方式2 添加一个字符串的签名索引,前提是确定这个对象会有额外的属性
// interface SquareConfig {
//   color?: string//?表示这个参数是可选的
//   width?: number
//   [propName: string]: any
// }
//解决方式3 放入一个变量里
//let squareOptions = {colorr: 'black', 100}
//let mySquare = createSquare(squareOptions)//这样会跳过检查
//真正的如果我们要使用colorr,应该加入inteface里面

接口描述函数类型

interface SearchFunc {
  (source: string, subString: string): boolean
}

let mySearch: SearchFunc
mySearch = function (src: string, sub: string): boolean {
  let result =src.search(sub)
  return result > -1
}
//也可以这样写
// mySearch = function (src, sub): boolean {
//   //不写参数类型,让TypeScript自行做推断
//   let result =src.search(sub)
//   return result > -1
// }

可索引的类型

interface StringArray {
  [index: number]: string 
}
let myArray: StringArray
myArray = ['Bob', 'Raze']
let myStr: string = myArray[0]
console.log(myStr)//Bob

类类型

//类的接口
//这里实现的实例类型的接口
//constructor是一个静态类型的接口
interface ClockInterface {
  currentTime: Date
  setTime(d: Date)
}

class Clock implements ClockInterface {
  currentTime: Date
  constructor(m: number,h:number ) {

  }
  setTime(d: Date) {
    this.currentTime = d
  }
}
//编译后
var Clock = /** @class */ (function () {
  function Clock(m, h) {
  }
  Clock.prototype.setTime = function (d) {
      this.currentTime = d;
  };
  return Clock;
}());

构造器接口

interface ClockConstructor {
  new(hour: number, minute: number )//构造器接口
}

什么时候该使用构造器接口(类的静态类型),什么时候使用实例接口呢

interface ClockInterface {
  tick()
}
interface ClockConstructor {
  new(hour: number, minute: number ): ClockInterface
  //返回值为构造器实例接口类型
}

function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface{
  //传入一个构造器ctor,传入构造器的参数hour,minute,返回值类型为实例接口类型
  return new ctor(hour, minute)
}
class DigitalClock implements ClockInterface {
  constructor(h: number, m: number) {

  }
  tick(){
    console.log('beep beep')
  }
}
class AnalogClock implements ClockInterface {
  constructor(h: number, m: number) {

  }
  tick(){
    console.log('tik tok')
  }
}
let digital = createClock(DigitalClock,12, 17)
let analog = createClock(AnalogClock,10, 10)
digital.tick()//beep beep
analog.tick()//tik tok

编译后的代码

function createClock(ctor, hour, minute) {
    //传入一个构造器ctor,传入构造器的参数hour,minute,返回值类型为实例接口类型
    return new ctor(hour, minute);
}
var DigitalClock = /** @class */ (function () {
    function DigitalClock(h, m) {
    }
    DigitalClock.prototype.tick = function () {
        console.log('beep beep');
    };
    return DigitalClock;
}());
var AnalogClock = /** @class */ (function () {
    function AnalogClock(h, m) {
    }
    AnalogClock.prototype.tick = function () {
        console.log('tik tok');
    };
    return AnalogClock;
}());
var digital = createClock(DigitalClock, 12, 17);
var analog = createClock(AnalogClock, 10, 10);
digital.tick();
analog.tick();

继承接口

interface Shape {
  color: string
}
interface PenStroke {
  penWidth: number
}
interface Square extends Shape, PenStroke {
  sideLength: number
}

let square = {} as Square
square.color = 'blue'
square.sideLength = 10
square.penWidth = 5.0

混合类型

interface Counter {
  (start: number): string //函数签名
  interval: number //对象属性
  reset(): void
}
function getCounter(): Counter {
  let counter = (function(star:number) {

  }) as Counter
    counter.interval = 123
    counter.reset = function () {

    }
    return counter
}
let c = getCounter()
c(10)
c.reset()
c.interval = 5.0

编译后

function getCounter() {
    var counter = (function (star) {
    });
    counter.interval = 123;
    counter.reset = function () {
    };
    return counter;
}
var c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

接口继承类

class Control {
  private state: any
}
interface SelectControl extends Control {
  select()
}
class Button extends Control implements SelectControl {
  select(){}
}
class TextBox extends Control {
  select(){}
  //虽然没有实现SelectCntrol,仍然可以定义select()方法 
}
// class ImageC implements SelectControl {
//   //报错imageC缺少属性state
//   select(){}
// }

2019-05-24  15:10:34

工欲善其事,必先利其器
原文地址:https://www.cnblogs.com/ccbest/p/10918269.html