• 阿兰得华
    2019-08-15
    老师你好,请问用interface定义函数(Add)和用type定义函数(Add)有区别么?实际开发中哪个用的比较多?其次,不是很理解混合接口声明函数(Lib)的讲解。可以给一个实际的例子做参照么?直觉上Lib更像是一个对象声明,既有属性也有方法。

    作者回复: type和interface 多数情况下有相同的功能,就是定义类型。但有一些小区别:
    type:不是创建新的类型,只是为一个给定的类型起一个名字。type还可以进行联合、交叉等操作,引用起来更简洁。
    interface:创建新的类型,接口之间还可以继承、声明合并。
    如果可能,建议优先使用 interface。

    混合接口一般是为第三方类库写声明文件时会用到,很多类库名称可以直接当函数调用,也可以有些属性和方法。例子你可以看一下@types/jest/index.d.ts 里面有一些混合接口。

    用混合接口声明函数和用接口声明类的区别是,接口不能声明类的构造函数(既不带名称的函数),但混合接口可以,其他都一样。

    
     4
  • 麦晓杰alwaysu
    2019-07-22
    #### 声明函数的方式:

    1. 通过变量声明:

    ```typescript
    let add: (x: number, y: number) => number
    ```

    2. 通过接口声明:

    ```typescript
    interface Add {
         (x: number, y: number): number
     }
    ```

    3. 通过类型别名声明:

    ```typescript
    type Add = (x:number , y: number) => number
    ```

    #### 混合接口
    声明:
    ```typescript
    interface Lib {
        (): void;
        version: string;
        doSomeThing(): void;
    }
    ```
    构造器:
    ```typescript
    function getLib() {
        let lib: Lib = (() => {}) as Lib
        lib.version = '1.0'
        lib.doSomeThing = () => {}
        return lib;
    }
    ```
    使用:

    ```typescript
    let lib1 = getLib();
    lib1();
    lib1.doSomeThing();
    let lib2 = getLib();
    ```
    展开
    
     2
  • 欧罗巴皇
    2019-12-30
    interface ObjINF1 {
        [key: string]: string | number | undefined;
    }
    interface ObjINF2 {
        id: number;
        title: string;
    }
    interface ObjINF3 {
        parentId: number;
        name: string;
        desc: string
    }
    function a1(objArr: ObjINF1[]) {
        
    }
    function a2(objArr: ObjINF2[]) {
        a1(objArr)
    }
    function a3(objArr: ObjINF3[]) {
        a1(objArr)
    }
    老师这样为什么报错?而且需要怎么处理才行啊!
    展开

    作者回复: 报错因为ObjINFO1 和ObjINFO2、ObjINFO3 类型不兼容,前者成员不固定,后者两者固定。我想到一个方法:
    type ObjINF1 = Partial<ObjINF2 & ObjINF3>
    看看能否解决你的问题

     1
     1
  • msupercoder
    2019-07-23
    为什么lib加了 version doSomething 属性后编译器还是会报错误呢?

    作者回复: TS 在定义一个变量时就会进行类型检查,
    let lib: Lib = () => {} 这一步就已经报错了,
    后续再加属性也是无效的,所以只能用类型断言。

     1
     1
  • 星夜如期
    2019-09-23
    请问一下老师,为什么您说 let lib: Lib = () => {} 这一步就已经报错了 ?

    作者回复: 因为这样定义的lib 还缺少version 和 doSomething 属性

    
    
  • Dean
    2019-09-23
    type Add = (a:number,b:number)=>number;
    let add :Add = (a)=>a; //通过类型检查
    let add2 :Add = (a)=>{};//类型检查报错
    let add3:Add = (a,b,c)=>a+b;//类型检查报错
    add(1) //类型检查报错
    请问老师,这里为什么函数实现的时候只传一个参数就会通过类型检查,只有在调用的时候才报错?而其他函数参数多于定义的个数或者返回值类型不对,在函数实现的时候都会类型检查报错
    展开

    作者回复: 总体来讲是函数兼容性问题,参数多的兼容参数少的,所以类型Add兼容第一个函数,不兼容第三个,第二个函数报错是因为返回值类型不兼容。

    第二个问题是因为你显示地声明了add的类型是Add,所以调用时会按照这个类型检查。

    请参看第16讲。

    
    
  • 鲜于伯德
    2019-09-16
    之前做过单例类的简单封装,所以不太明白这里lib为什么是一个单例?老师能简单说一下吗?

    作者回复: 这里的含义是,如果不封装一下 lib,它就是一个全局变量,封装后就可以通过闭包创建多个 lib。虽然与纯oop中单例的实现有些区别,但思想是一致的。

    
    
我们在线,来聊聊吧