添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
const getUser = ( user: User ) => { console . log (user. name , user. age . toString ()) // user.age 🐛 可能不存在但是调用方法

age 是可选的,但是在 console.log 中调用了 toString 方法。

  • ts: Object is possibly 'undefined'.ts(2532) 我们可以使用 ?. 来解决这个🐛,严格检查
  • console.log(user.name, user.age?.toString())
    
  • boolean 布尔类型
  • string 字符串类型
  • void/null/undefined 三种空类型
  • any/any[] 类型
  • tuple 元祖类型
  • never/unknown
  • 函数/构造函数字面量类型
  • 函数调用类型
  • 构造函数签名
  • 按级别划分类型

    顶级类型 top type

  • any/unknown. 包含所有类型的集合。
  • 底部类型 bottom type

  • never 空集合
  • 从类型 type 引出接口 interface

    在 TypeScript 中,使用 type 关键字,定义类型别名

    type User = number | string; // 定义 number | string 的联合类型为 User
    

    ⚠️:别名 type 一旦定义定义就不能扩展自己,只能用 type 定一个其他的类型。基于别名 type 自生不可扩展,引出 接口 interface 的概念就很合适了。

    interface Global {
        api1: number
    

    我们想要扩展 Global 接口,就可以直接重新定义(重新定义不是简单的覆盖行为)

     interface Global {
         api2: number
    

    api2接口属性是补充在 Global 属性上面的,而不是覆盖之前定义的 api1。

    TypeScript 对象类型 Object Types

    对象类型应该是我们最常用的复合类型在之一了。

    定义对象类型的方式:

  • interface
  • 他们的最主要的区别之一就是:能不能不产生新的类型的基础上扩展自己。

    可选/只读的类型属性

  • 可选: ?.<your option>
  • 只读: readonly <you option>
  • 有时候,我们不确定属性的名称,此时我们就可以定义索引类型

    interface User {
        [index: string]: any
    

    index 表示索引,索引的类型是 string,属性对应的类型是 any

    interface 的类型扩展

  • 重新定义接口,然后补充新的属性,不产生一个新的接口
  • 使用 extend 关键字补充,产生一个新的接口
  • type 的类型补充

  • 使用 | 联合类型,进行扩展,产生一个新的类型。
  • 两个类型交叉,将两个不同类型组合成一个新的类型没有重复的新的类型

    type A = {
        name: string
        age: number
    type B = {
        age: number
        sex: string
    const C: A & B = {
        name: 'sdfd',
        age: 123,
        sex: 'male'
    const D: A | B = {
        name: 'sdf',
        age: 123
    

    重要关键字

  • extends 赋值(也可以叫分配) 。 广泛应用于条件类型,是高级类型的基石。
  • keyof 获取索引值,并组合成新的索引值联合类型。
  • 范型,有一个广义上的类型,但是这个类型具体还不确定,由于不确定所有可以是多种类型。是一对多的关系。常使用 T, U 表示范型,常用于函数参数的约束。

    function fn<T>(a: T) {};
    

    T 就范型类型,范型类型确定后,fn 函数参数的类型就确定了。 T 可以对应多个类型。

    开始可以粗糙的理解为: 数学中的并集。联合类型使用 |操作符来联合类型

    type A = string | number; // A 就是 string 和 number 的联合类型,A 可以是 string 也可以是 number;
    

    注意,黏合类型在切换类型的时候,整个值切换

    type B = boolean | {z: string};
    let binst: B = {z: 123};
    binst = false;
    // 整个切换之后就能在访问 z 属性了。
    

    开始可以粗糙的理解为: 数学中的交集。联合类型使用 &操作符来交叉类型

    type X = string & number; // never 我们知道 string 和 number 类型是没有相交的可能性的
    

    所以交叉类型常用于一下相对复杂点的类型.

    type C = string | number;
    type D = string | Function
    type CxD = C & D; // string
    // 示例
    const h: CxD = 'this is cxd type'; // 类型检查成功
    const hF: CxD = 12312; // 类型检查失败
    const gF: CxD = () => {}; // 类型检查失败
    

    类型中也有索引操作,获取索引,设置索引

  • keyof 获取类型索引
  • 使用 [] 来定义索引类型和索引值类型
  • // 访问索引
    type INN = {
      a: string;
      b: string;
    const kea: keyof INN = "a";
    const keb: keyof INN = "b";
    const kec: keyof INN = "c"; // 类型检查出错 没有 c 索引
    
    type INN = {
      a: string;
      b: string;
      [index: string]: any; // 添加字符串的索引
    const kea: keyof INN = "a";
    const keb: keyof INN = "b";
    const kec: keyof INN = "c"; // 类型检查不会出错,因为又添加字符串的索引
    

    与 js 的三元表达式相似。常与 extends 关键字以及范型配合使用形成高级类型。

    T extends U ? X : Y;
    

    理解: T 赋值给 U 之后正确吗?正确取 X 类型,否则取 Y 类型。

    因为 extends 关键字是 TypeScript 高级类型的基石。所以下面会啰嗦一下,用 js 类型打好基础:

    // string
    type StrT = "abc" extends string ? "StrTrue" : "StrFalse"; // StrTrue
    type StrF = "abc" extends unknown ? "StrTrue" : "StrFalse"; // StrFalse
    // boolean
    type BoolT = true extends boolean ? "BoolTrue" : "BoolFalse"; // BoolTrue
    type BoolF = true extends unknown ? "BoolTrue" : "BoolFalse"; // BoolFalse
    // number
    type NumT = 123 extends number ? "NumTrue" : "NumFalse"; // NumTrue
    type NumF = 123 extends unknown ? "NumTrue" : "NumFalse"; // NumFalse
    // null
    type NullT = null extends null ? "NullTrue" : "NullFalse"; // NullTrue
    type NullT1 = null extends unknown ? "NullTrue" : "NullFalse"; // NullTrue
    type NullT2 = null extends any ? "NullTrue" : "NullFalse"; // NullTrue
    type NullT3 = null extends void ? "NullTrue" : "NullFalse"; // NullFalse
    type NullT4 = null extends boolean ? "NullTrue" : "NullFalse"; // NullFalse
    // ...
    // object
    type ObjT = {} extends Object ? "ObjTrue" : "ObjFalse"; // ObjTrue
    type ObjT1 = {} extends unknown ? "ObjTrue" : "ObjFalse"; // ObjTrue
    type ObjT2 = {} extends any ? "ObjTrue" : "ObjFalse"; // ObjTrue
    type ObjT3 = {} extends void ? "ObjTrue" : "ObjFalse"; // ObjFalse
    type ObjT4 = {} extends boolean ? "ObjTrue" : "ObjFalse"; // ObjFalse
    type ObjT5 = {} extends null ? "ObjTrue" : "ObjFalse"; // ObjFalse
    

    Footnotes

    最佳的 TypeScript Null 类型检查实践

    分类:
    前端
    标签: