0
点赞
收藏
分享

微信扫一扫

TypeScript学习笔记(类型篇二)----- any,unknown和对象类型

Ewall_熊猫 2022-02-14 阅读 80

1. TypeScript 中 any 和 unknown 都可以指任意类型,那么这两者之间有什么不同呢?

  • TypeScript 可以推导出 any 类型,但无法推导出 unknown 类型,如果要使用 unknow 类型,必须显式注解

  • 使用 unknown 类型,除了相等比较外,都需要先说明变量的类型:

    let num: unknown = 1
    
    if (num > 2) { // 此时编辑器会对 num 报错,提示:Object is of type 'unknown'.
        // 
    }
    
    if (typeof num === 'number' && num > 2) { // OK, 已经通过typeof判断num是否是number类型了,所以可以比较
        
    }
    

    如果是 any 类型的话,那就是随便用了,但这样做就丢失了类型安全,所以一般如果不知道当前变量的类型,建议先使用 unknown,除非特殊情况,否则不建议使用 any,如果要使用any,则最好是显式注解

2. TypeScript 对象类型中的 object, {} , Object 有什么区别?

它们之间的相同之处就是都可以用来表示对象的类型,它们之间的区别比较细微:

  • object

    object 可以指代除了基本类型或者说原始类型(number, string, null, undefined, symbol)之外的类型,如果是不关心属性的对象,可以使用 object 类型

  • 对象字面量类型 {}

    这个类型有点微妙,如果是非空的字面量对象,TypeScript 会要求你严格按照定义的属性名和类型来给变量赋值,但如果是个空的字面量对象用作类型的时候,在初始化的时候,可以指代除了 nullundefined 之外的所有类型,而编辑器不会报错,不过如果是要对这个数据进行后续的操作时,编辑器有时还是会报错的:

    // 这些声明都是可以的,在声明的时候编辑器不会报错
    let n: {} = 1
    let s: {} = 'string'
    let arr: {} = [1, 2, '3']
    let func: {} = () => console.log('something')
    let symb: {} = Symbol('symb')
    let o: {} = {}
    
    // 下面这两个声明,编辑器会报错
    let nl: {} = null       // Type 'null' is not assignable to type '{}'.
    let u: {} = undefined   // Type 'undefined' is not assignable to type '{}'.
    
    // 以下的一些操作会报错
    n.toFixed(2)   // Property 'toFixed' does not exist on type '{}'.
    s.slice(0, 2)  // Property 'slice' does not exist on type '{}'.
    arr.push(1)    // Property 'push' does not exist on type '{}'.
    func()         // This expression is not callable. Type '{}' has no call signatures.
    

    通过测试和观察,可以大致得出,用空对象字面量声明类型时,会根据原型链定位到 Object 上,而除了nullundefined 外,其他的类型通过 prototype 或者 __proto__ 最后都会找到 Object 上,所以为什么用空对象字面量可以注解 nullundefined 之外的所有类型了。也因此,对这些变量调用不在Object.prototype 上的方法时会报错的原因了

  • Object 表现基本与空对象字面量类型 {} 一致,大概的区别就是,{} 是通过原型链定位到 Object,而 Object 是显式指明

举报

相关推荐

0 条评论