美文网首页
TS初学笔记

TS初学笔记

作者: YukiWeng | 来源:发表于2021-07-30 16:46 被阅读0次

    整理之前学习ts时的一些笔记。


    安装
    npm install -g typescript // 报无权限 
    sudo npm install -g typescript 
    tsc -v // tsc,ts编译器,查看版本
    
    // hello.ts 
    const hello = (name:string)=>{ return `hello ${name}` } 
    hello('yuki')
    
    tsc hello.ts  //编译 ===> 生成 hello.js
    tsc -w hello.ts //监听hello.ts 的变化
    node hello.js //运行 js 文件
    

    或者安装 ts-node ,将以上两步合并为一步 ts-node hello.ts

    编译后,函数会出现(2393)函数实现重复,猜测可能是vscode的bug(不确定)
    在项目根目录添加配置文件 tsconfig.json即可(空文件也可)


    基础类型
    let isDone: boolean = false;
    let age: number = 18; 
    let firstName: string = "yuki"; 
    let message: string = `Hello,${firstName},age is ${age}`; 
    let u: undefined = undefined; 
    let n: null = null; 
    let num: number = undefined;
    
    any 和 联合类型
    let notSure: any = 4; 
    notSure = "a string"; 
    notSure = true; 
    notSure.getName(); 
    
    let numberOrString: number | string; 
    numberOrString = "hhh"; 
    numberOrString = 1;
    
    数组Array 和 元祖Tuple
    // 数组 Array 
    let arrOfNumbers: number[]=[1,2,3] 
    arrOfNumbers.push(5) 
    
    // 元祖 Tuple
    let user:[string,number]=['1',3]
    
    interface 接口

    对象的形状(shape)进行描述
    类(class)进行抽象

    interface Person { 
      readonly id:number, // readonly 用于对象属性,不允许修改该值 
      name: string; 
      age?: number; // ? 表示 非必须 
    } 
    let yuki: Person = { 
      id:1111, 
      name: "yuki",
      age: 20, // 此处允许不加age 
    };
     yuki.id = 2222 // error , id readonly,不允许修改
    
    函数 和 类型推断

    如下,
    z 为可选参数。需要注意,必选参数 必须放在 可选参数 之前,否则报错
    或者用es6的写法, z:number = 0 ,不传的话默认为0

    // function add ():number{} 此处的number 规定了输出的类型为number
    function add(x:number,y:number,z?:number):number{ 
      if(typeof z ==='number'){ 
        return x+y+z 
      } 
      return x+y 
    } 
    let result1 = add(1,2,3) 
    let result2 = add(1,2)
    

    注意,下图中,不是es6中的箭头函数。而是tsc(ts编译器)的 类型推断

    image.png
    let str= 'str' 
    str= 123 // error , 因为ts推断出 str 是string类型
    
    Class 类

    默认是public,允许外部和子类访问
    private 不允许外部和子类访问
    protected 不允许外部访问,允许子类访问
    readonly 可访问,不可修改

    class Animal { 
      private name:string 
      constructor(name:string){ 
        this.name=name
      }
    } 
    const snake = new Animal('lili') 
    console.log(snake.name) // error,外部不允许访问 
    snake.name='lucy' // error,外部不允许访问 
    
    class Dog extends Animal { 
      break() { 
        return `${this.name} is barking`; // error 子类同样无法访问
      }
     }
    

    子类继承父类,复杂场景时可能无法满足需求,故,可用接口interface提供公共部分
    类可以同时继承多个接口,implements (类继承接口就必须实现这个接口里面写的方法)
    接口可以继承接口,extends

    interface Radio { 
      switchRadio():void // void 什么都不返回
    } 
    interface Battery{ 
      checkBatteryStatus() 
    } 
    
    // 方法一:CellPhone 同时implements Radio,Battery 
    class Car implements Radio { 
      switchRadio(){ } 
    } 
    class CellPhone implements Radio,Battery{ 
      switchRadio(){ } 
      checkBatteryStatus(){ } 
    } 
    
    // 方法二:RadioWithBattery 继承 Radio, CellPhone implements RadioWithBattery 
    interface RadioWithBattery extends Radio{ 
      checkBatteryStatus(){ } // 继承了Radio的switchRadio(){ } ,并添加checkBatteryStatus(){ } 
    }
    class CellPhone implements RadioWithBattery{ 
      switchRadio(){ } 
      checkBatteryStatus(){ } 
    }
    
    Enum 枚举

    默认从0开始赋值,每个值自动递增
    也可以自行赋值,numberstring 等均可

    enum Direction { 
      Up, // 若 赋值 Up=10,则Down为11, Direction[10]为Up 
      Down,
      Left,
      Right
    } 
    console.log(Direction.Up) // 0 
    console.log(Direction[0]) // 'Up'   双向
    

    编译后,可发现转为js后,是一个自执行函数

    // js 
    var Direction; 
    (function (Direction) { 
      Direction[Direction["Up"] = 0] = "Up";
      Direction[Direction["Down"] = 1] = "Down"; 
      Direction[Direction["Left"] = 2] = "Left";
      Direction[Direction["Right"] = 3] = "Right"; 
    })(Direction || (Direction = {}));
    

    常量枚举(加const)

    const enum Direction { 
      Up = 'up', 
      Down = 'down' 
    } 
    const value = 'up' 
    console.log(value === Direction.Up) // true
    

    编译后:

    // js 
    var value = "up"; 
    console.log(value === "up" /* Up */);
    

    常量枚举成员在使用的地方会被内联进来,
    之所以可以这么做是因为,常量枚举不允许包含计算成员;
    如上,编译时,并没有 Direction 变量的,因此常量枚举会对性能有一定提升。

    泛型 (一)

    如下,自定义一个泛型T,函数入参类型T,出参同样T(使入参出参保持一样的类型)
    当入参为string,出参同样是string;入参为number,出参同样number

    function echo<T>(arg: T): T {
      return arg;
    } 
    const res = echo("str"); 
    
    function swap<T, U>(tuple: [T, U]): [U, T] { 
      return [tuple[1], tuple[0]]; 
    } 
    const res2 = swap(["str", 123]);
    
    泛型(二):约束泛型
    interface IwithLength { length: number; } // 入参必须包含 length属性
    function echoWithLength<T extends IwithLength>(arg: T): T {
      console.log(arg.length); 
      return arg; 
    } 
    const arr = echoWithLength([1, 2]); 
    const obj = echoWithLength({ x: 1, length: 1 }); 
    const str = echoWithLength('hhh')
    
    泛型(三):类和接口
    class Queue<T> { 
      private data = []; 
      push(item: T) { 
        return this.data.push(item);
      } 
      pop(): T { 
        return this.data.shift(); 
      } 
    } 
    
    const queue = new Queue<number>(); 
    queue.push(1); 
    console.log(queue.pop().toFixed()); 
    
    const queue2 =new Queue<string>() 
    queue2.push('str') 
    console.log(queue2.pop())
    
    interface Iplus<T> { 
      (a: T, b: T): T; // 函数,入参一和入参二为T,出参为T 
    } 
    function plus(a: number, b: number): number { 
      return a + b; 
    } 
    function connect(a: string, b: string): string { 
      return a + b; 
    } 
    const num: Iplus<number> = plus; 
    const str: Iplus<string> = connect;
    

    当我新建另一个ts文件:

    let isDone: boolean = false 
    //报错,提示 'isDone' was also declared here.
    

    在默认状态下,typescript 将 DOM typings 作为全局的运行环境,
    当我声明 isDone 时, 与 DOM 中的全局 window 对象下的isDone属性出现了重名。

    解决方法:在脚本文件最后一行,添加 export {}; 将文件声明为模块
    (在 Typescript 中,只要文件存在 import 或 export 关键字,都被视为 module)


    类型别名

    使用关键字type,多用于联合

    type PlusType = (x: number, y: number) => number; 
    function sum(x: number, y: number): number { 
      return x + y; 
    } 
    const sum2: PlusType = sum; // 代替 const sum2: (x: number, y: number) => number = sum
    
    类型断言

    通过类型断言这种方式告诉编译器类型,只在编译阶段起作用

    let someVal: any = 'str' 
    let strLength: number = (<string>someVal).length // 尖括号 
    let strLength2: number = (someVal as string).length // JSX 只可使用as语法断言
    
    声明文件

    https://www.runoob.com/typescript/ts-ambient.html

    目的:为了借用 TypeScript 的各种特性来使用第三方库文件
    (declare 定义的类型只会用于编译时的检查,编译结果中会被删除。)

    如,

    declare var jQuery:(selector:string)=>any
    

    把这些声明单独放在一个文件,称为声明文件,以 .d.ts 为后缀,如 jQuery.d.ts
    一般而言,所有ts文件都可获得这些类型定义,若无法获取,可在根路径的tsconfig.json中配置tsc编译器

    { "include":["**/*"] }
    

    DefinitelyTyped (http://definitelytyped.org/
    该组织提供了各类声明文件,安装即可,无需自己创建声明文件

    npm install --save-dev @types/jquery
    

    相关文章

      网友评论

          本文标题:TS初学笔记

          本文链接:https://www.haomeiwen.com/subject/zjccvltx.html