TS 语法进阶:any类型、类型断言、typeof 和 keyof

2,099 阅读3分钟

一、any 类型

1.定义和作用

any: 任意的,一切。当类型设置为 any 时,就取消了类型的限制。我们常称为 any 大法。

{
    let obj: any = 0
    obj='lalala'
    obj.name='Lucy'
}

注意:以上操作编译时不会报任何类型错误提示,即使可能存在错误,运行时才会报错。

2.使用 any 的场景

  • 定义一个函数,输入任意类型的数据,返回该数据类型。 例如,console.log()
  • 临时使用 any 来“避免”书写很长、很复杂的类型。例如,ajax 请求回来的数据
{
    console.log()

    // 假设 data 是从 ajax 拿回来的数据,我们还不知它的类型
    let data
    let d:any = data

    function fn(a: any) {
    }
}

3.隐式 any

  • 声明变量不提供类型也不提供默认值
  • 定义函数时,参数不给类型
{
    let a
    function fn(a){}
}

image.png

注意:不推荐使用 any。 这会让 TypeScript 变为 “AnyScript”(失去 TS 类型保护的优势)

二、类型断言

1.问题导入

假设我们明确知道页面上有一个 img,它的 idimg

{
    const img=document.getElementById('img')
    console.log(img.src)// ts 报错
}

image.png

审查发现,该方法返回值的类型是 HTMLElement | null,该类型只包含所有标签公共的属性或方法,不包含 img 标签特有的 src 等属性,所以无法操作 src 等 img 标签特有的属性或方法。

image.png

2.类型断言的作用和应用场景

作用: 手动指定值的类型

场景:有时候你会比 TS 更加明确一个值的类型,此时,可以使用类型断言来指定更具体的类型。

3.格式与示例

格式:const 变量 = 值 as 类型

示例:

// ◆示例1:
{
    const img = document.getElementById('img') as HTMLImageElement
    console.log(img.src) // 这里就会有 src 的提示
}
// ◆示例2:
{
    type User = {
        name: string,
        age: number
    }

    const u1 = {} as User

    console.log(u1.name) // 这里就会有 name 和 age 的提示
}

小技巧:如何得知 DOM 的类型

  1. 在浏览器控制台,通过 __proto__ 获取 DOM 元素的类型;
  2. document.createElement('img'),然后看代码提示

三、typeof

1.问题导入

res 表示一个复杂的对象,我们把它传给一个函数 fn,但是目前没有办法从形参 obj 中获取提示信息

{
    const res = { name: 'Lucy', age: 18 }
    function fn(obj) {
        // 这里写obj.没有提示
       console.log( obj.name)
    }
    fn(res)
}

image.png

2.typeof

1.JS 中提供了 typeof 操作符,用来在 JS 中获取数据的类型

console.log(typeof 'Hello world') // string

2.TS 也提供了 typeof 操作符:可以用来获取变量或属性的类型

console.log(typeof 'Hello world') // string

3.使用场景

根据已有变量的值,反向推断出获取该值的类型,来简化类型书写

格式:type 类型 = typeof 常量

示例:

{
    const res = { name: 'Lucy', age: 18 }
    type StuType = typeof res
    function fn(obj: StuType) {
        // 这里写obj. 有 name 和 age 的提示了
        console.log(obj.name)
    }
    fn(res)
}

4.小结

  1. 使用 typeof 操作符来获取变量 res 的类型,结果与第一种(对象字面量形式的类型)相同
  2. 注意:typeof 只能用来查询变量或属性的类型,无法查询其他形式的类型(比如,函数调用的类型)

四、keyof

定义:获取某个对象/类型的属性名来构成新类型

格式:

  1. type 类型 = keyof 类型
  2. type 类型 = keyof 对象常量

示例:

{
    // ◆ 第一种:获取某个类型的属性名构成新的类型
    type Point = { x: number; y: number }
    type P = keyof Point
    let p1: P = 'y'
    let p2: P = 'x'
    // ◆ 第二种:获取某个对象的属性名构成新的类型
    type T = keyof { a: 1, b: 2 }
    let keyName: T = 'b'
}