TypeScript接口用法(基础)

1,484 阅读2分钟

接口

作用:定义契约(如类型命名、属性检查、函数类型定义等)

1. 类型命名

interface LwhValue {
    l: number,
    w: number,
    h: number,
}

function getLWH(lwhObj: LwhValue) {
    return '长宽高:' + lwhObj.l + ',' + lwhObj.w + ',' + lwhObj.h;
}

console.log(getLWH({ l: 3.45, w: 23.12, h: 23 })); // 长宽高:3.45,23.12,23

2. 属性检查

interface NameValue {
    readonly firstName: string,
    lastName?: string,
}

function getName(nameObj: NameValue) {
    return `Hello,${nameObj.firstName}${nameObj.lastName ? (' ' + nameObj.lastName) : ''}`;
}

// readonly属性检查
let myName: NameValue = { firstName: 'Huang' };
myName.firstName = 'Song'; // 报错:Cannot assign to 'firstName' because it is a constant or a read-only property.

// 额外属性检查
let hisName: NameValue = { firstName: 'Song', secondName: 'Yangyang' };
// 报错:
// Type '{ firstName: string; secondName: string; }' is not assignable to type 'NameValue'.
// Object literal may only specify known properties, and 'secondName' does not exist in type 'NameValue'.

3. 函数类型

interface DealImgUrlFn {
    (jsfUrl: string, isMain?: boolean, w?: number, h?: number): string;
}

let dealImgUrlFn: DealImgUrlFn;
dealImgUrlFn = function (jsfUrl: string, isMain?: boolean, w?: number, h?: number): string {
    if (!jsfUrl) return '';
    if (jsfUrl.indexOf('http:') > -1 || jsfUrl.indexOf('https:') > -1) return jsfUrl;

    const protocolStr = location.protocol;

    // 若传入了图片尺寸,按照该尺寸裁切,否则不裁切
    let imgStr = '';
    if (w || h) {
        imgStr = `s${w || h}x${h || w}_`;
    }

    if (isMain) {
        return `${protocolStr}//img12.360buyimg.com/n1/${imgStr}${jsfUrl}`;
    } else {
        const urlArr = jsfUrl.split('/');
        const anotherArr = urlArr.slice(1);
        return `${protocolStr}//img12.360buyimg.com/${urlArr[0]}/${imgStr}${anotherArr.join('/')}`;
    }
}

const imgUrl = dealImgUrlFn('/jfs/t1/29894/13/4041/12884/5c2ed0adE75ec21a9/8949817d0cc9492e.jpg', false, 200, 100);
console.log(imgUrl); // http://img12.360buyimg.com//s200x100_jfs/t1/29894/13/4041/12884/5c2ed0adE75ec21a9/8949817d0cc9492e.jpg

4. 实现接口

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

const time = new Clock(24, 0);
time.setTime(new Date());
alert(time.currentTime);

5. 接口继承接口

interface Shape {
    color: string;
}

interface Cicle extends Shape {
    radius: number;
}

let cicle = <Cicle>{};
cicle.color = 'red';
cicle.radius = 2;

console.dir(cicle);

6. 类继承接口

当接口继承了一个类类型时,它会继承类的成员但不包括其实现。

class Shape {
    private color: string;
    constructor(c: string) {
        this.color = c;
    }
}

interface SquareInterface extends Shape {
    getColor(): string;
}

class Square extends Shape implements SquareInterface {
    private squareColor: string;
    constructor(c: string, squareColor: string) {
        super(c);
        this.squareColor = squareColor;
    }
    getColor() {
        return this.squareColor;
    }
}

const square = new Square('red', 'blue');
console.dir(square);

若将Square类修改为以下:

class Square implements SquareInterface {
    private squareColor: string;
    constructor(c: string, squareColor: string) {
        super(c);
        this.squareColor = squareColor;
    }
    getColor() {
        return this.squareColor;
    }
}
// 报错: Class 'Square' incorrectly implements interface 'SquareInterface'.
// Property 'color' is missing in type 'Square'.

这意味着若一个接口继承了拥有私有成员的类时,这个接口类型只能被这个类或其子类所实现(implement)。