初探

我们先来对一个函数做一个参数约定

    function test(args: { title: string }) {
        return args.title;
    }
    test({ title: 'x' }) // x
复制代码

类型检查器会查看test的调用参数,并检查参数是否符合约定规范,为一个对象,包含一个sting类型title字段,如果不符合,则会在检查阶段跑出错误。

interface

有时候,我们的参数多,我们也希望接口可以进行代码复用,那么就可以这么写

    interface Args {
        title: string;
        body: string;
    }
    function test(args: Args) {
        return args.title;
    }
    function test2(args: Args) {
        return args.body;
    }
复制代码

函数的参数会逐个进行检查,要求对应位置上的参数类型是兼容的。 如果你不想指定类型,TypeScript的类型系统会推断出参数类型,因为函数直接赋值给了函数类型变量。 函数的返回值类型是通过其返回值推断出来的(此例是 false和true)。 如果让这个函数返回数字或字符串,类型检查器会警告我们函数的返回值类型与接口中的定义不匹配。

可选参数、动态参数

在上述接口定义中,属性是必须的,不能多也不能少,在一些情况下,我们希望有些参数是可选的,甚至是动态的,那么我们可以改造成这样:

    interface Args {
        title: string;
        body: string;
        x?: number; // 可选属性
        [y: string]: any; // 动态属性
    }
    function test(args: Args) {
        return args.title;
    }
    function test2(args: Args) {
        return args.body;
    }
复制代码

函数返回类型

为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。

这样定义后,我们可以像使用其它接口一样使用这个函数类型的接口。

    interface SearchFunc {
        (source: string, subString: string): boolean;
    }
    let mySearch: SearchFunc;
    mySearch = function(source: string, subString: string) {
        let result = source.search(subString);
        return result > -1;
    }
复制代码

接口编程

有些时候,我们会在一个实例初始化的时候做一些事情,这时候,interface可以用class来实现

    class Cat {
        name: string;
        color: string;
        constructor(name: number, color: number) {
            this.name = name;
            this.color = color;
        }
    }
    function cloneCat(cat: Cat): Cat {
        return new Cat(cat.name, cat.color)
    }
复制代码

接口继承

和类一样,接口也可以相互继承。

    interface Shape {
        color: string;
    }

    interface Square extends Shape {
        sideLength: number;
    }