美文网首页spring boot
TypeScript接口深入理解

TypeScript接口深入理解

作者: nomooo | 来源:发表于2019-06-12 22:50 被阅读0次

    TypeScript 的核心原则之一是对值所具有的结构进行类型检查。它有时被称做“鸭式辨型法”或“结构性子类型化”。 在 TypeScript 里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。

    类静态部分与实例部分的区别

    当你操作类和接口的时候,你要知道类是具有两个类型的:静态部分的类型和实例的类型。 你会注意到,当你用构造器签名去定义一个接口并试图定义一个类去实现这个接口时会得到一个错误:

    interface ClockConstructor {
      new (hour: number, minute: number)
    }
    
    // error
    class Clock implements ClockConstructor {
      currentTime: Date
      constructor(h: number, m: number) { }
    }
    

    这里因为当一个类实现了一个接口时,只对其实例部分进行类型检查。constructor 存在于类的静态部分,所以不在检查的范围内。

    类类型的例子

    我们定义了两个接口, ClockConstructor 为构造函数所用和 ClockInterface 为实例方法所用。 为了方便我们定义一个构造函数 createClock,它用传入的类型创建实例。

    // 定义实例接口
    interface ClockInterface {
        tick()
    }
    // 定义构造器接口
    interface ClockConstructor {
        new(hour: number, minute: number): ClockInterface
    }
    /**
     * 定义工厂函数
     * @param ctor 传入时钟类
     * @param hour 小时
     * @param minute 分钟
     */
    function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
        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('tick toc')
        }
    }
    // 创建实例
    let digital = createClock(DigitalClock, 12, 17)
    let analog = createClock(AnalogClock, 6, 31)
    

    因为 createClock 的第一个参数是 ClockConstructor 类型,在 createClock(AnalogClock, 7, 32) 里,会检查 AnalogClock 是否符合构造函数签名
    继承接口

    // 继承接口
    // 定义类
    interface Shape {
        color: string
    }
    interface PenStroke {
        penWidth: number
    }
    // 继承Shape和PenStroke  用 , 分割,同时继承
    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 (start: number) {
    
        }) as Counter
        counter.interval = 100
        counter.reset = function () {
    
        }
    
        return counter
    }
    
    let c = getCounter()
    c(1)
    c.reset()
    c.interval = 5.0
    
    

    接口继承类

    class Control {
        private state: any
    }
    
    interface SelectableControl extends Control {
        select()
    }
    
    class Button extends Control implements SelectableControl {
        select() {
    
        }
    }
    
    class TextBox extends Control implements SelectableControl {
        select() {
    
        }
    }
    
    // Error:“ImageC”类型缺少“state”属性。
    class ImagesC implements SelectableControl {
        select(){
    
        }
    }
    
    

    在上面的例子里,SelectableControl 包含了 Control 的所有成员,包括私有成员 state。 因为 state 是私有成员,所以只能够是 Control 的子类们才能实现 SelectableControl 接口。 因为只有 Control 的子类才能够拥有一个声明于Control 的私有成员 state,这对私有成员的兼容性是必需的。

    Control 类内部,是允许通过 SelectableControl 的实例来访问私有成员 state 的。 实际上,SelectableControl 接口和拥有 select 方法的 Control 类是一样的。ButtonTextBox 类是 SelectableControl 的子类(因为它们都继承自Control 并有 select 方法),但 ImageC 类并不是这样的。

    相关文章

      网友评论

        本文标题:TypeScript接口深入理解

        本文链接:https://www.haomeiwen.com/subject/eiwrfctx.html