TS-补充: TS语法细节

163 阅读4分钟

黑缎缠目

夜深了, 再写点博客就睡了...我曾想过无数次放弃, 我已经习惯了这种心态崩溃和自我重建的过程。不过后来我发现了这未尝不是一件好事,你将建立强大的自信心和自我驱动力。还好我不曾放弃,坚定信仰,不断打磨... 图片.png

联合类型和交叉类型

  • 联合类型是一种特殊的数据类型, 由两个或者多个其他类型组成的类型
type infoType = string | number
const info: infoType
  • 交叉类型: 交叉是相对于联合类型的, 一般用于对象
interface Person {
    name: string
    age: number
}
interface Student {
    id: string
    student: () => void
}
type stuType = Person & Student
const stu: stuType = {
    name: "susan",
    age: 18,
    id: 2101,
    student: function() {
        consle("学习ts~")
    }
}

类型别名和接口声明

  • 类型别名:给类型起一个别名, 方便在上下文各个地方使用。特别是声明对象类型函数类型的场景使用频繁。开发规范: 一般在类型别名后缀添加Type
type objType = {
    name: string
    age: number
}
const obj: objType = {
    name: "messi",
    age: 33
}
  • 接口声明: 接口是一种特殊的类型声明,用于描述对象的类型。注意: 可以重复声明同一个接口添加新的属性, 由于接口声明的方式后期扩展性更强, 所以开发中一般定义非对象类型使用type, 定义对象类型使用interface, 推荐写法: 前缀大写的 "I",
interface IPerson {
    name: stirng
    age: number
}

类型缩小

我们可以缩小比声明时更小的类型, 常见的类型缩小有以下几种方式:

// 方式一: typeof -- 最常用
  type dataType = string | number
  function dataFn(data: dataType)  {
    if(typeof data === "string") {
      console.log(data.length)
    } else {
      console.log(data)
    }
  }
// 方式二: 平等缩小
  type sectionType = "top" | "bottom" | "left" | "right"
  function sectionFn(section: sectionType) {
    if(section === "top") console.log("top")
    else if(section === "bottom") console.log("bottom")
    else if(section === "left") console.log("left")
    else console.log("right")
  }
// in: 判断是否有某一属性
  interface Irun { run: (runing: string) => void }
  interface Idance { dance: (dancing: string) => void }
  
  const p1: Irun = {
    run: function(runing: string) {
      console.log("running")
    }
  }
  const p2: Idance = {
    dance: function(dancing: string) {
      console.log("dancing~")
    }
  }
  
  function isActive(active: Irun | Idance) {
    if("run" in p1) console.log(p1.run)
    else if("dance" in p2) console.log(p2.dance)
  }

字面量类型

字面量类型是一种特殊的类型声明,用于指定变量可以具有的确切值,而不仅仅是类型。通过字面量类型,我们可以限制变量的取值,从而提高程序的类型安全性。可以分为以下几类:

  • 字符串字面量类型: 字符串字面量类型使用字符串常量作为类型,表示一个变量只能取其所指定的字符串值
  • 布尔字面量类型: 布尔字面量类型使用布尔常量作为类型,表示一个变量只能取其所指定的布尔值。
  • 数字字面量类型: 数字字面量类型使用数字常量作为类型,表示一个变量只能取其所指定的数字值。

我们处理以下这个细节问题: 这里调用getfetch, 正常传入参数会报错: getfetch(obj1.url, obj1.method), 因为函数参数methodType的类型为字面量类型, 而obj1对象中的method属性值是string类型。

type methodType = "POST" | "GET"
function getfetch(url: string, method: methodType) {
// 接收参数进行网络请求
}
const obj1 = {
  url: "https://baidu.com",
  method: "GET"
}
getfetch(obj1.url, obj1.method as methodType)

处理方法一: 单一属性类型断言:getfetch(obj1.url, obj1.method as methodType)

处理方法二: 对象类型断言: 使该对象的类型变为字面量类型

const obj2 = {
    url: "https://baidu.com",
    method: "GET"
  } as const

类型断言

类型断言(Type Assertion)是一种告诉编译器变量类型的方式。它可以让开发者手动指定变量类型, 可以让ts更好的处理类型问题。注意只允许类型断言转换为更加具体或者更加宽泛的类型版本,此规则可防止不可能的强制转换。

非空类型断言: 直接确定某个标识符是有值的, 开发中慎用属于危险操作

// 定义对象类型是添加可选类型的时候, 创建对象时, 若没有添加该可选类型是可以访问的但不能操作
// 解决方法有两个: 类型缩小, 类型断言
interface Iobj {
    name: string
    age: number
    dog?: {
      name: string
      age: number
    }
  }
  const obj: Iobj = {
    name: "curry",
    age: 33,
  }
  obj.dog!.age = 11