您现在的位置是:首页 >技术教程 >TypeScript类型注释网站首页技术教程

TypeScript类型注释

Vanghua 2024-07-22 06:01:03
简介TypeScript类型注释

1.类型注释的种类

typescript使用类型注释来进行静态类型检查

  1. JavaScript类型(number,string,boolean,bigInt,symbol,null,undefined,object)

  2. JavaScript内置类(Number,String,Object,Function,等等)

  3. JavaScript具体值(1,“123”,{name: ‘Danny’},等等)

  4. 自定义类型(自定义类,类型别名,接口)

  5. 数组(一维数组,二维数组,等等)

  6. 元组([某种类型,某种类型,等等])

  7. 特殊类型(void,enum,never,any,联合类型,合并类型)

1.1 注释:JavaScript类型和JavaScript内置类

其中基本类型正常注释即可,选择大小写均可。对于引用类型需要特别注意。

1.1.1 注释:Object
  • 如果使用Object或object注释:(1)则会认为对象是空对象,不可以对其属性进行改查。(2)宽松地类型检查,声明obj时赋初始值,属性任何类型都是合理的

    const obj: Object = { school: 'SDU', age: 21 }
    
  • (推荐使用)如果使用对象字面量进行注释:(1)则会认为对象是灵活的,可以对其属性进行改查。(2)正常的类型检查,obj赋值时,属性必须严格对照注释

    const obj: { school: String, age: Number } = { school: 'SDU', age: 21 }
    
1.1.2 注释:Function

注释Function分为箭头函数和普通函数注释。注释为箭头函数时,在箭头后写明返回值。注释为普通函数时在括号后写明返回值。

  • 如果使用Function注释,效果同上。

    const func: Function = (arg1: string, arg2: number) => { console.log(123) }
    
  • (推荐使用)如果使用函数字面量进行注释,效果同上。

    const func: (arg1: string, arg2: number) => void = function(arg1: string, arg2: number) {
        console.log(123)
    }
    

1.2 注释:JavaScript具体值

当声明时指定了具体值之后,变量赋值只能赋为该值,否则会发生错误

let variableA: 2
variableA = 2

1.3 注释:自定义类型

1.3.1 注释:自定义类
class Test {}
let variable: Test
1.3.2 注释:类型别名

使用类型别名指定已经存在的类型

type School = {
    name: String,
    age: Number
}
let variable: School
1.3.3 注释:接口

使用接口指定映射类型

interface School = {
    name: String,
    age: Number
}
let varibale: School
1.3.4 接口和类型别名的区别

区别主要发生在接口和类型别名都表示映射类型时。

  • 扩展属性的方法不同

    • 接口可以像类一样通过继承扩展属性

      interface A {
          name: string
      }
      interface B extends A {
          gender: string
      }
      let obj: B = {
          name: "Danny",
          gender: "male"
      }
      
    • 接口可以使用&运算符扩展属性

      interface A {
          name: string
      }
      interface B {
          gender: string
      }
      type Type = A & B
      
    • 接口可以直接扩展属性

      interface A {
          name: string
      }
      interface A {
          gender: string
      }
      let obj: A = {
          name: "Danny",
          gender: "male"
      }
      
    • 类型别名只能通过&运算符扩展属性

      type A = {
          name: string
      }
      type B = {
          gender: string
      }
      type C = A & B
      
  • 可修改性不同

    • 接口创建后可以通过覆写来添加新的属性
    • 类型别名创建后不能在原有类型上添加新的属性

1.4 注释:数组

let ar1Dim: string[]
let ar2Dim: string[][]

1.5 注释:元组

元组确定了数组每个元素的类型以及数组的长度

let tuple: [string, number, boolean]

1.6 注释:特殊类型

1.6.1 注释:枚举

使用enum声明一个枚举,枚举中又声明了若干枚举值,每一个枚举值又会有一个关联值。

1.6.1.1 默认枚举

默认从第一个枚举值开始关联0,往后关联1,2,3

enum Fruit {
    Apple,
    Orange,
    Melon
}

typescript的默认枚举在实现上实际是一个对象,对象中进行了反向映射

let Fruit = {
    Apple: 0,
    Orange: 1,
    Melon: 2,
    '0': 'Apple',
    '1': 'Orange',
    '2': 'Melon'
}

Fruit.AppleFruit[0]这两种访问形式都有应用场景

1.6.1.2 数值枚举

数值枚举要求给枚举值赋值为数值

enum Fruit {
    Apple = 2,
    Orange,
    Melon
}

反向映射结果为

let Fruit = {
    Apple: 2,
    Orange: 3,
    Melon: 4,
    '2': 'Apple',
    '3': 'Orange',
    '4': 'Melon'
}

也可以给全部枚举值指定关联值

enum Fruit {
    Apple = 2,
    Orange = 1,
    Melon = 4
}

反向映射结果为

let Fruit = {
    Apple: 2,
    Orange: 1,
    Melon: 4,
    '2': 'Apple',
    '1': 'Orange',
    '4': 'Melon'
}
1.6.1.3 字符串枚举

字符串枚举要求每个枚举值必须赋一个字符串关联值

enum Fruit {
    Apple = 'Apple',
    Orange = 'Orange',
    Melon = 'Melon'
}

反向映射结果为

let Fruit = {
    Apple: 'Apple',
    Orange: 'Orange',
    Melon: 'Melon',
}
1.6.1.4 异构枚举

异构枚举要求每个枚举值必须赋一个字符串或数值关联值。不推荐使用异构枚举,一般枚举值都有相关性,异构枚举破坏了相关的联系。

enum Fruit {
    Apple = 0,
    Orange = 'Orange',
    Melon = 'Melon'
}

反向映射结果为

let Fruit = {
    Apple: '0',
    0: 'Apple',
    Orange: 'Orange',
    Melon: 'Melon'
}
1.6.1.5 常量枚举

常量枚举在编译时会被删除,不产生枚举对应的对象形式。因此声明常量枚举后直接访问枚举是非法的,只能访问枚举值。

const enum Fruit {
    Apple,
    Orange,
    Melon
}

console.log(Fruit) // 非法的
console.log(Fruit.Apple) // 合理的

因为不会生成对象形式,因此最后结果只会输出0

1.6.1.6 何时使用枚举

在typescript中枚举,数组,对象相互之间的功能比较相似,需要在特定场景进行分析。

  • 语意明确时用枚举: 当常量具有清晰明确的语意时,应该使用枚举类型。枚举类型为常量提供了明确的命名和类型,可以使代码更加可读和维护。

    enum DaysOfWeek {
      Monday,
      Tuesday,
      Wednesday,
      Thursday,
      Friday,
      Saturday,
      Sunday
    }
    
    function isWeekend(day: DaysOfWeek): boolean {
      return day === DaysOfWeek.Saturday || day === DaysOfWeek.Sunday;
    }
    
    isWeekend(DaysOfWeek.Saturday); // true
    
  • 值不需要变动用对象或数组: 如果固定的值不会发生变化,可以考虑使用常量数组或对象。

    const weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"];
    const maxFileSize = { txt: 1024, jpg: 2048, gif: 3072 };
    
  • 值需要从动态来源获得用对象或数组:如果值需要从动态来源获取,例如从后端API中获取,则应该使用对象或数组类型,并根据需要进行类型定义。

    interface User {
      id: number;
      name: string;
      role: "admin" | "member";
    }
    
    function hasAdmin(users: User[]) {
      return users.some(user => user.role === "admin");
    }
    
    // 从API中获取用户信息
    fetch("/users")
      .then(response => response.json())
      .then(data => {
        if (hasAdmin(data)) {
          // do something
        }
      });
    
1.6.1.7 注释:枚举

枚举和枚举值都可以作为类型来进行注释。

将变量注释为枚举类型,指的是变量的取值范围固定在枚举值的关联值当中。

let variableEnum: Fruit = 0
if(variableEnum === Fruit.Apple)
    console.log('Apple')
else if(variableEnum === Fruit.Orange)
    console.log('Orange')
else if(variableEnum === Fruit.Melon)
    console.log('Melon')
else
    console.log('None')

将变量注释为枚举值类型,指的是变量只能取枚举值的关联值。

let variableA: Fruit.Apple
variableA = 0
1.6.2 注释:联合类型,合并类型

联合类型指的是用|来表示变量可以取不同的类型

let variableA: string | number | boolean

合并类型指的是用&来表示变量取多种类型中的交集。

  • 对于接口,对象字面量类型,使用&合并会合并属性,因为可以做到同时满足。

    interface A {
        name: string
    }
    interface B {
        gender: string
    }
    type C = A & B
    let obj: C = {
        name: 'Danny',
        gender: 'male'
    }
    
  • 对于普通类型,使用&合并会直接取交集,因为无法同时满足。

    type TypeA = string | number
    type TypeB = number | boolean
    type TypeC = TypeA & TypeB
    let variable: TypeC = 123 // variable只能取数值类型
    
1.6.3 注释:any,never,void

any表示任何类型,不推荐使用,使用后效果和JavaScript相同。

never表示不能取到的类型,例如使用合并类型时为空集,那么就是never类型。

type Type = string & number // Type就是never类型,没有任何一种类型可以既是string又是number
let empty: () => never // empty无法被赋值,因为函数默认返回undefined,存在返回值

void表示返回值为undefined的情景。用于函数返回值时never比void更严格。

let empty: () => void = () => {} // empty可以被赋值,因为void类型允许返回undefined

2.类型注释的场景

声明变量

let name: String
let func: Function

声明函数

function func(): void {}
function func2(): Number {
    return 123
}
const func3: () => void = () => {}

声明形参

function func(name: String, age: Number): void {}

声明解构

const { school, age } : { school: String, age: Number } = obj
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。