zoukankan      html  css  js  c++  java
  • Typescript 接口(interface)

    概述

    typescript 的接口只会关注值的外形,实际就是类型(条件)的检查,只要满足就是被允许的。

    接口描述了类的公共部分。

    接口

    interface Person {
        firstName: string;
        lastName: string;
    }
    function greeter(person: Person) {
        return 'Hello, ' + person.firstName + ' ' + person.lastName;
    }
    var user = {
        firstName: 'Jane',
        lastName: 'User'
    };
    document.body.innerHTML = greeter(user);
    
    // 可选属性
    interface SquareConfig {
        color?: string;
        width?: number;
    }
    function createSquare(config: SquareConfig): { color: string; area: number } {
        let newSquare = { color: 'white', area: 100 };
        if ( config.width ) {
            newSquare.area = config.width * config.width;
        }
        return newSquare;
    }
    let mySquare = createSquare({color: 'black'});
    
    // 只读属性(只能在对象刚刚创建的时候修改其值)
    interface Point {
        readonly x: number;
        readonly y: number;
    }
    let p1: Point = { x: 10, y: 20 };
    p1.x = 5;   // error
    
    // ReadonlyArray<T>
    let a: number[] = [1, 2, 3, 4];
    let ro: ReadonlyArray<number> = a;
    ro[0] = 12; // error
    ro.push(5); // error
    ro.length = 100;    // error
    a = ro; // error
    // 可以使用断言重写
    a = ro as number[];
    
    // const vs readonly
    // 作为变量则用 const
    // 作为属性则使用 readonly
    
    // 对于会额外带有任意数量的其他属性,最佳方法是添加一个字符串索引签名
    // 一旦定义了任意属性,那么确定属性和可选属性都必须是它的子属性,如下代码,即string、number为any的子属性
    interface SquareConfig {
        color?: string;
        width?: number;
        [propName: string]: any;    // 字符串索引签名
    }
    

    接口(函数类型)

    interface SearchFunc {
        // 定义调用签名
        (source: string, subString: string): boolean;
    }
    
    let mySearch: SearchFunc;
    mySearch = function(source: string, subString: string) {
        let result = source.search(subString);
        if ( result == -1 ) {
            return false;
        } else {
            return true;
        }
    }
    // 对于函数类型的类型检查,函数的参数名不需要与接口定义的名字相匹配,但是要求对应位置上的参数类型是兼容的。
    

    接口(可索引的类型)

    // 当用 number 去索引 StringArray 时会得到 string 类型的返回值
    interface StringArray {
        [index: number]: string;
    }
    let myArray: StringArray;
    myArray = ['Bob', 'Fred'];
    let myStr: string = myArray[0];
    
    // 防止给索引赋值
    interface ReadonlyStringArray {
        readonly [index: number]: string;
    }
    let myArray: ReadonlyStringArray = ['Alice', 'Bob'];
    myArray[2] = 'Mallory'; // error
    
    // 确保所有属性与其返回值类型相匹配
    interface NumberDictionary {
        [index: string]: number;
        length: number;
        name: string;   // 错误,name的类型不是索引类型的子类型
    }
    

    类类型

    // 强制一个类去符合某种契约
    interface ClockInterface {
        currentTime: Date;
    }
    class Clock implements ClockInterface {
        currentTime: Date;
        constructor(h: number, m: number) { }
    }
    
    // 在接口中描述一个方法,在类中实现它
    interface ClockInterface {
        currentTime: Date;
        setTime(d: Date);
    }
    class Clock implements ClockInterface {
        currentTime: Date;
        setTime(d: Date) {
            this.currentTime = d;
        }
        constructor(h: number, m: number) { }
    }
    
    // 类静态部分与实例部分的区别
    interface ClockConstructor {
        new (hour: number, minute: number): ClockInterface;
    }
    interface ClockInterface {
        tick();
    }
    
    function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
        return new cotr(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 tock');
        }
    }
    
    let digital = createClock(DigitalClock, 12, 17);
    let analog = createClock(AnalogClock, 7, 32);
    

    扩展接口

    和类一样,接口也可以相互扩展。能够从一个接口里复制成员到另一个接口里,更灵活地将接口分割到可重用的模块里。

    interface Shape {
        color: string;
    }
    
    interface Square extends Shape {
        sideLength: number;
    }
    
    let square = <Square>{};
    square.color = 'blue';
    square.sideLength = 10;
    
    // 继承多个接口
    interface Shape {
        color: string;
    }
    
    interface PenStroke {
        penWidth: number;
    }
    
    interface Square extends Shape, PenStroke {
        sideLength: number;
    }
    
    let square = <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 = <Counter>function (start: number) { };
        counter.interval = 123;
        counter.reset = function() { };
        return counter;
    }
    
    let c = getCounter();
    c(10);
    c.reset();
    c.interval = 5.0;
    

    接口继承类

    当接口继承类类型时,它会继承类的成员但不包括其实现。接口同样会继承到类的private和protected成员。意味着这个接口只能被这个类或其子类所实现。

    class Control {
        private state: any;
    }
    
    interface SelectableControl extends Control {
        select(): void;
    }
    
    class Button extends Control {
        select() { }
    }
    
    class TextBox extends Control {
        select() { }
    }
    
    class Image {
        select() { }
    }
    
    class Location {
        select() { }
    }
    
  • 相关阅读:
    PrintWriter write与println方法的区别
    java线程之一 单线程
    Android系列之ListView实现分页和类似异步加载效果(转载)
    Failed to fetch URL http://dlssl.google.com/android/repository/addons_list
    java rpc 综述(上)
    横竖屏切换时候Activity的生命周期
    【转载】C# 大数相乘
    ASP.NET 2.0 中使用PreviousPage的强类型属性
    人生一世
    SQL 中的indexof函数CHARINDEX
  • 原文地址:https://www.cnblogs.com/Hao-Killer/p/7305780.html
Copyright © 2011-2022 走看看