TypeScript 入门到理解

219 阅读7分钟
  1. 类(Class)的基本
    1. readonly:该属性在一个接口里使用readonly来标记属性,只能只读,不被允许修改
    2. public: 公有成员,类的所有属性的默认都是public,它的含义是对所有人都是可见的
    3. private:私有成员,只能在类的实例化之后被调用,而不能被类的本身调用,也不能被子类调用
    4. protected:受保护成员,只能在类本身可访问,而不能在类的实例中访问
    5. readonly:成员可被声明为只读属性,也就是说这个属性不可以被更改
    6. static:静态成员,只能通过类名和子类名来调用,而不能通过类的实例化调用
    7. abstract:抽象类,无法创建抽象类的实例,它只能被继承,好处是可抽离出一些事物的共性,这样就有利于代码的复用和扩展,抽象类可实现多态,所谓多态就是在父类中定义一个抽象方法,在多个子类中,对这个抽象类的方法有不同的实现
  2. 类型检查机制TypeScript编译器在做类型检查时,所秉承的一些原则,以及表现出的一些行为。 作用:辅助开发,提高开发效率
    1. 类型推断:
      1. 不需要指定变量的类型(函数的返回值类型),TypeScript可根据某些规则自动地为其推断出一个类型
        1. 基础类型推断
        2. 最佳通用类型推断
        3. 上下文类型推断
    2. 类型兼容性:
      1. 当一个类型Y可被赋值给另一个类型X时,我们就可以说类型X兼容类型Y,
        • X兼容Y:X(目标类型)= Y(源类型)
    3. 类型保护:
      1. TypeScript能够在特定的区块中保证变量属于某种确定的类型,可在此区块中放心地引用此类型的属性,或者调用此类型的方法。
  3. 交叉类型:合适做对象的混入
  4. 联合类型:可使类型具有一定不确定性,可增强代码的灵活性,比如说取值可以为多种类型种的一种
    // 允许 multiType 的类型是 string 或者 number,但是不能是其他类型。
    let multiType: number | string;
    multiType = 'hello string';
    multiType = 3;
    
  5. 对象类型:来定义对象的类型
    1. 什么是接口:
      1. 在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)
      2. TypeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述
    2. 可选属性(?):不要匹配一个形状,那么可以使用可选属性(?),含义该属性可以不存在
    3. 任意属性:一个接口允许有任意的属性
    4. 只读属性:对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性
    interface Person {
        name: string;
        age?: number; // 这是可选属性
        [gender: string]: any; // 这是任意属性
        readonly education: string;
    }
    
    let me: Person = {
        name: 'mooncheung';
        education: '南开大学'
        // 在接口类定义age属性定义一种类型,在me对象中没有赋值给age属性这样不会引发报错,当做不存在的属性,gender属性同样类似情况
    }
    // me.education = '某大学' 再次赋值给me对象会报错,只能读取属性
    
  6. 数组类型:数组类型有很多种定义方式,比较灵活
    1. [类型+方括号]表示法,但是不允许在数组的项中有其他类型
    2. 数组泛型:Array
    3. 用接口表示数组
    interface NumberArray {
        [index: number]: number;
    }
    // NumberArray 表示:只要索引的类型是数字时,那么值的类型必须是数字
    let fibonacci: NumberArray = [1, 1, 2, 3, 5];
    
    1. 类数组:类数组不是数组类型,比如说arguments
    2. any 在数组中的应用:any表示数组中允许出现任意类型
  7. 函数类型:支持函数声明和函数表达式的类型定义,包括接口定义函数的形状
    1. 可选参数(?):输入多余的(或者少于要求的)参数,是不允许的。可以采用接口中的可选属性类型(?)表示
      • 注意:可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必需参数了
    2. 参数默认值:TypeScript会将添加了默认值的参数识别为可选参数
      • 注意:不受[可选参数必须接在必需参数后面]的限制
    3. 剩余参数:可以使用...rest的方式获取函数中的剩余参数
    function push(array: any[], ...items: any[]) {
        items.forEach((item)=>{
            array.push(item);
        });
    }
    let a = [];
    push(a, 1, 2, 3);
    
    1. 重载:重载允许一个函数接受不同数量或类型的参数时,作出不同的处理
    function reverse(x: number): number;
    function reverse(x: string): string;
    function reverse(x: number | string): number | string {
        if (typeof x === 'number') {
             return Number(x.toString().split('').reverse().join(''));
        } else if (typeof x === 'string') {
             return x.split('').reverse().join('');
        }
    }
    
  8. 索引类型
    1. 要点:
      1. [keyof T]:泛型类型 T 公共属性名的字面量联合类型
      2. T[K]:对象T的属性K所代表的类型
    2. 应用场景:从一个对象中选取某些属性的值
  9. 映射类型:本质上是一种预先定义的泛型接口,通常还会结合索引类型,获取对象的属性和属性值,从而将一个对象映射成我们的结构
    type Readonly<T> = { 
        // readonly属性是只读的
        readonly [ P in keyof T ]: T[ P ]; 
    } 
    type Partial<T> = { 
        [ P in keyof T ]?: T[ P ]; 
    }
    
  10. 条件类型
    1. 含义:
      1. T extends U?X:Y(如果类型T可以赋值给类型U,那么结果类型就是X,否则就是Y)
      2. 应用场景:
        1. Exclude<T,U>:从T中过滤掉可以赋值给U的类型
        2. Extract<T,U>:从T中抽取出可以赋值给U的类型
        3. NonNullable<T>:从T中除去undefined和null
        4. ReturnType<T>:获取函数的返回值类型
  11. 类型断言
    1. 简介:类型断言(Type Assertion),可用来手动指定一个值的类型
    2. 语法:值 as 类型 或者<类型>值
    3. 总结:
      • 联合类型可被断言为其中一个类型
      • 父类可以被断言为子类
      • 任何类型都可以被断言为 any
      • any 可以被断言为任何类型
      • 要使得 A 能够被断言为 B,只需要 A 兼容 B 或 B 兼容 A 即可
    4. 类型断言的限制:
      • 若 A 兼容 B,那么 A 能够被断言为 B,B 也能被断言为 A , 意思是说A作为父类有name,B作为子类有name,run函数,互相兼容,不会引起报错
    5. 双重断言:
      1. 特点:
        • 任何类型都可以被断言为 any
        • any 可以被断言为任何类型
      2. 使用:
        1. 可以打破「要使得 A 能够被断言为 B,只需要 A 兼容 B 或 B 兼容 A 即可」的限制,将任何一个类型断言为任何另一个类型
        2. 除非迫不得已,千万别用双重断言
    interface One{
        run(): void;
    }
    
    interface Two{
        swin(): void;
    }
    function testCat(one: One{
        return (one as anyas Two; // 若直接使用 one as Two 肯定会报错,因为 Cat 和 Fish 互相都不兼容
    }
    
  12. 谓词类型
    1. 简介:谓词采用形式param is Typeparam必须当前函数名中参数名称,会将变量缩小为特定类型执行
    interface One  {
        type: 'one';
        occupation: string;
    }
    interface Two {
        type: 'two';
        role: string;
    }
    function isOne(person: One | Two): person is One{
        return person.type === 'one'
    }
    ...省略
    
  13. 声明文件
    1. 简介:当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能
    2. 语法索引:
      • declare var 声明全局变量
      • declare function 声明全局方法
      • declare class 声明全局类
      • declare enum 声明全局枚举类型
      • declare namespace 声明(含有子属性的)全局对象
      • interface 和 type 声明全局类型
      • export 导出变量
      • export namespace 导出(含有子属性的)对象
      • export default ES6 默认导出
      • export = commonjs 导出模块
      • export as namespace UMD 库声明全局变量
      • declare global 扩展全局变量
      • declare module 扩展模块
      • ///  三斜线指令
    3. 全局变量:
      • declare var 声明全局变量
      • declare function 声明全局方法
      • declare class 声明全局类
      • declare enum 声明全局枚举类型
      • declare namespace 声明(含有子属性的)全局对象
      • interface 和 type 声明全局类型

参考资料

  1. www.tslang.cn/docs/home.h…
  2. ts.xcatliu.com/