typescript - 接口初探

76 阅读2分钟
function print(labelObj: {label: string}) {
    console.log(labelObj.label)
}

let myObj = {size: 10, label: 'size 10'};
print(myObj);

需要注意的是,我们传入的对象参数实际上会包含很多属性,但是编译器只会检查那些必须的属性是否存在,以及类型是否匹配,然而,有时候,typescript 却并不会这么宽松,稍后会举例子;

使用接口改写上边的代码

interface LabeValue {
    label: string;
}

function print(labelObj: LabeValue) {
    console.log(labelObj.label)
}

let myObj = {size: 10, label: 'size is 10'}
print(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) {
        newSquare.color = config.color
    }
    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: 10};
p1.x = 20 // error

let a: number[] = [1, 2, 3, 4, 5];
let ro: ReadonlyArray<number> = a;

ro[0] = 12 // error
a = ro // error

只读属性不可以被修改,重新赋值,但可以通过断言来重写

a = ro as number[];

额外的属性检查

interface Square {
    color?: string;
    width?: string;
}

function createSquare (config: Square): {color: string; area: number} {
    let newSquare = {color: "white", area: 100}
    if (config.color) {
        newSquare.color = config.color
    }
    if (config.width) {
        newSquare.width = config.width;
    }
    return newSquare;
}

let mySquare = createSquare({colour: "red", width: 100}) // 这里的参数故意传错

let mySquare = createSquare({colour: "red", width: 100}) // error

报错了,colour 不存在类型 Square 中;因为 此时 进行了额外属性检查;

解决这个问题有三种方法,

第一种通过类型断言:

let mySquare = createSquare({colour: "red", width: 100} as Square)

第二种是绕过这种类型检查:

const obj = {colour: "red", width: 100};
let mySquare = createSquare(obj);

第三种通过字符串的索引签名:

interface Square {
    color?: string;
    width?: number;
    [propName: string]: any;
}