TypeScript快速入门

TS的基本数据类型

  1. null和undefined只有本身

  2. function:

    • 声明的函数在调用的时候,参数个数要和声名的时候的参数个数保持一致,并且要保持类型的相同

    • //没有返回值的函数可以用void声明
      const fn1 = (param1:string,param2:number): void => {
        console.log("我是没有返回值的箭头函数");
      };
      
      function f2(param1:string,param2:number):void{
        console.log("我是没有返回值的普通函数");
      }
      
      //有返回值的箭头函数声明是这样的
      const fn3 = (): string => {
        return "马冬梅=>"
      };
      
      //有返回值的普通函数声明是这样的
      
      function f4():string{
         return "马冬梅fn"
      }
      
      
      //函数表达式的双向限定
      //上述fn1其实只对=右侧做了限制,对左侧并没有
      //完善一点,可以这样 => 用来表示函数的定义,左输入类型,需要用括号括起来,右输出类型
      
      const fn1:(param1:string,param2:number)=>void = (param1:string,param2:number): void => {
        console.log("我是没有返回值的箭头函数");
      };
      
      // 函数的可选参数
      // 注意可选参数要在确定参数后
      function f5(name:string,age?:number):string{    //带问号表示可选参数
         return "马冬梅fn"
      }
      
      //函数参数默认值
      function f6(name:string,age:number=18):string{
         return `${name}--${age}`
      }
      //此时可选参数不必一定在确定参数后,但是调用有问题
      function f7(name:string,desc?:string,age:number=18):string{
         return `${name}--${age}--${desc}`
      }
      
      //剩余参数,不确定参数有多少个的时候就会用到剩余参数
      function f8(...args:number[]):number[]{
        return args
      }
      console.log(f8(1,2,3,4,5))//[1,2,3,4,5]
      
      // 函数重载
      重载是方法名字相同,而参数不同,返回类型可以相同也可以不同。
      
      每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
      
      参数类型不同:
      
      function disp(string):void; 
      function disp(number):void;
      参数数量不同:
      
      function disp(n1:number):void; 
      function disp(x:number,y:number):void;
      参数类型顺序不同:
      
      function disp(n1:number,s1:string):void; 
      function disp(s:string,n:number):void;
      
  3. void声名变量

  4. void也可以用来声名变量,但是只能用在undefined身上,null也不行,除非做了配置

  5. symbol

  6. bigint (兼容性不是特别的好)

  7. 任意值(any/unknown)用来表示允许赋值为任意类型

  8. 数组

    //像java中的集合+泛型,List<String> arr=new ArrayList();
    const arr1: Array<string> = ["马","冬","梅"] 
    //类型后+[],java中也是如此:String [] arr = {"马","冬","梅"};
    const arr2: string[] = ["马","冬","梅"]
    
    //数组的项中不允许出现其他的类型
    const arr3: string[] = ["马","冬","梅",1024]//报错 1024非字符串
    
    // any[] 类型的数组可以不同
    const anyArray: any[] = [1, 'hh', false]
    
    // 联合类型数组
    const arr: number[]|string[]
    arr = [1, 2, 3]  // 数字数组
    arr = ['1', '2', '3']   //字符串数组
    //解构数组
    const array: number[] = [1, 2];
    const [x, y] = array;   // x = 2, y = 2
    // 等价于
    const x = array[0];
    const y = array[1];
    
  9. 元组:TS中的元组与JS的数组很像,可以存储不同类型的值

    ts允许向元组中使用数组的push方法插入新元素(但不允许访问),不然就是越界了

  10. 枚举:枚举相当于可以由值得到它的名字,这种感觉像对象的键值对

    • 枚举类型也确实属于对象类型

    • ts只支持基于数字和字符串的枚举

    • 对于基于数字的枚举类型支持键值对的反向映射 key<=>value

    • 基于字符串的不可以反向映射?当然不可以,就是纯js对象

    • 数组枚举–默认增长

    enum Language{
      java,
      node,
      php,
      python
    }
    
    //可以按值访问
    console.log(Language[0])//java
    //也可以按键访问
    console.log(Language["java"])//0
    
    //打印结构如下
    console.log(Language);
    
    {
      '0': 'java',
      '1': 'node',
      '2': 'php',
      '3': 'python',
      java: 0,
      node: 1,
      php: 2,
      python: 3
    }
    
    //编译后代码如下 IIFE传参的形式
    "use strict";
    var Language;
    (function (Language) {
        Language[Language["java"] = 0] = "java";
        Language[Language["node"] = 1] = "node";
        Language[Language["php"] = 2] = "php";
        Language[Language["python"] = 3] = "python";
    })(Language || (Language = {}));
    console.log(Language);
    //# sourceMappingURL=index.js.map
    
    //可以看到内层赋值生成的是
    {
      java: 0,
      node: 1,
      php: 2,
      python: 3
    }
    //外层赋值生成的是
    {
      '0': 'java',
      '1': 'node',
      '2': 'php',
      '3': 'python',
    }
    
    
    1. 数字枚举–自定义增长,我们可以手动的设置相关的值来进行增长,当然,未设置的值会根据上下文增长

      enum Language{
        java=5,
        node,
        php,
        python
      }
      
      //打印一下
      console.log(Language)
      
      {
        '5': 'java',
        '6': 'node',
        '7': 'php',
        '8': 'python',
        java: 5,
        node: 6,
        php: 7,
        python: 8
      }
      
      //当然你也可以全部手动指定每个值,不连续也可以
      
      enum Language{
        java=100,
        node=101,
        php=103,
        python=104
      }
      
      enum Language{
        java=5,
        node,
        php,
        python
      }
      
      //打印一下
      console.log(Language)
      
      {
        '5': 'java',
        '6': 'node',
        '7': 'php',
        '8': 'python',
        java: 5,
        node: 6,
        php: 7,
        python: 8
      }
      
      //当然你也可以全部手动指定每个值,不连续也可以
      
      enum Language{
        java=100,
        node=101,
        php=103,
        python=104
      }
      
    2. 字符串枚举:其实就是把上述数字枚举的值换成字符串,但结构有些不同,枚举属于对象类型

  11. 对象:TS在对象的使用上存在着一些限制,必须是特定类型的实例,常常配合interface使用

    1. 基本使用:

      
      //创建一个空对象
      const obj:object={};
      
      //也许你想这样给对象增加属性
      //但是不行,会报错,因为最初是一个空对象,自然没有这个name属性
      obj.name="tom"
      
      //这就需要好用的interface出场了
      //如果你用过java,那应该清楚接口是一套待实现的规范
      //和元组规范类似,实例属性与声明类型的属性数量和名称严格一致,不可多不可少
      interface User{
        name:string
      }
      
      const u1:User={
        name:"马东梅"
      }
      //报错,多属性
      const u2:User={
        name:"马东梅",
        age:24
      }
      //报错,少属性
      const u3:User={}
      
      //若属性值为函数,也需要在接口中声明
      interface Person{
        name:string,
        say: (something: string) => string
      }
      
      const p:Person={
        name:"jack",
        say: (something: string) => something
      }
      
      console.log(p.say("hello"))//hello
      
    2. 可选属性,有些时候我们希望某些属性是可选的,这时候我们可以使用?进行修饰

      interface Stu{
        name:string,
        desc?:string
      }
      
      //此时缺少desc属性也是可以的,因为它是可选属性
      const s:Stu={
        name:"tom"
      }
      
    3. 任意属性:有时候我们允许任意属性的添加

      interface Stu {
          name: string;
          sno?: number;
          [prop: string]: any;
      }
      
      //这样写ok
      const s1: Stu = {
          name: 'Tom',
          sex: '男'
      };
      //这样写也ok,可选属性没什么影响
      const s2: Stu = {
          name: 'Jack',
          sex: '男',
          sno:10010
      };
      
    4. 接口继承:

      1. 接口继承就是说接口可以通过其他接口来扩展自己。

        Typescript 允许接口继承多个接口。

        继承使用关键字 extends

        单接口继承语法格式:

        Child_interface_name extends super_interface_name
        

        多接口继承语法格式:

        Child_interface_name extends super_interface1_name, super_interface2_name,…,super_interfaceN_name
        

        继承的各个接口使用逗号 , 分隔。

      2. 单继承实例:

        interface Person { 
           age:number 
        } 
         
        interface Musician extends Person { 
           instrument:string 
        } 
         
        var drummer = <Musician>{}; 
        drummer.age = 27 
        drummer.instrument = "Drums" 
        console.log("年龄:  "+drummer.age)
        console.log("喜欢的乐器:  "+drummer.instrument)
        
      3. 多继承实例

        interface IParent1 { 
            v1:number 
        } 
         
        interface IParent2 { 
            v2:number 
        } 
         
        interface Child extends IParent1, IParent2 { } 
        var Iobj:Child = { v1:12, v2:23} 
        console.log("value 1: "+Iobj.v1+" value 2: "+Iobj.v2)
        
    5. map对象:Map 对象保存键值对,并且能够记住键的原始插入顺序。

      Map 相关的函数与属性:

      • map.clear() – 移除 Map 对象的所有键/值对 。
      • map.set() – 设置键值对,返回该 Map 对象。
      • map.get() – 返回键对应的值,如果不存在,则返回 undefined。
      • map.has() – 返回一个布尔值,用于判断 Map 中是否包含键对应的值。
      • map.delete() – 删除 Map 中的元素,删除成功返回 true,失败返回 false。
      • map.size – 返回 Map 对象键/值对的数量。
      • map.keys() - 返回一个 Iterator 对象, 包含了 Map 对象中每个元素的键 。
      • map.values() – 返回一个新的Iterator对象,包含了Map对象中每个元素的值 。

      迭代map

      Map 对象中的元素是按顺序插入的,我们可以迭代 Map 对象,每一次迭代返回 [key, value] 数组。

      TypeScript使用 for…of 来实现迭代:

类型推断

  1. ts更严格(定义并且赋值的情况)

    ​ 虽然ts是js的超集,但是ts有自动的类型推断,所以定义好数据值时候就相当于已经定义好了这个变量的类型

    1. 定义但是不赋值

    ​ 如果变量定义的时候没有赋值,不管之后有没有赋值,都会被推断为any类型二完全不被类型检查,但是这不是一个好习惯哦

    
    //这不是什么好习惯,像极了脱缰的野马
    //当你试图削弱ts静态类型检查优势的时候,说明你依旧过度依赖js写法
    let str;
    str="lengyuexin"
    str=1024;
    str=[]
    str=false;
    str={}
    

类型断言

类型断言可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。

用法:

1. <类型>值
2. 值 `as` 类型

联合类型

  1. 联合类型标识取值可以为多种类型中的一种,不同类型使用管道符|进行分割,类似于或
  2. 使用联合类型的属性和方法,一定要记住只有公共的属性和方法才可以被访问,如果不是两个类型共有的属性和方法就会报错,例如stringnumber两个类型的变量就不能使用.length这个属性、

类与接口

  1. 类实现接口

    //定义动物类 若有实例属性外部初始化,需要构造函数
    class Animal {
      color: string;
      constructor(color: string) {
        this.color = color;
      }
      //也可以声明实例方法
      yell(str:string):string{
        return str
      }
    }
    
    
    //*******************//
    
    // 以下示例基于最原始的 class Animal {}
    
    
    //将叫声这一行为抽象成接口
    interface AnimalYell{
        yell():void
    }
    
    
    //定义动物类
    class Animal {
    }
    
    
    // 定义Mammal类,继承Animal类,实现AnimalYell接口
    
    class Mammal extends Animal implements AnimalYell {
        yell() {
            console.log('动物发出叫声');
        }
    }
    
    //Dog,Cat类继承父类Mammal,重写yell方法
    // 这里也可以直接让Dog,Cat实现AnimalYell接口
    //之所以继承,是更大程度的复用父类Mammal的特点(属性和方法)
    
    class Dog extends Mammal {
        yell(){
             console.log('汪汪...');
        }
    }
    
    class Cat extends Mammal {
        yell(){
             console.log('喵喵...');
        }
    }
    
    
    
    // 一个类可以实现多个接口
    interface AnimalWalk{
        walk():void
    }
    
    //Snake实现AnimalWalk,AnimalYell两个接口\
    //实现接口要实现每个接口中的方法
    //若以下代码缺少yell或walk的实现就会报错
    class Snake implements AnimalWalk,AnimalYell{
        yell(){
            console.log("嘶嘶...")
        }
    
        walk(){
            console.log("爬行...")
        }
    }
    
    new Mammal().yell()//动物发出叫声
    new Dog().yell()//汪汪...
    new Cat().yell()//喵喵...
    new Snake().yell()//嘶嘶...
    new Snake().walk()//爬行...
    
    1. 接口继承接口

    类可以继承,接口也可以。实际上,ts中接口还能继承类,不过一般不用哈

    
    //将手机功能抽象为一个接口
    interface BasePhoneFunction {
      call(): string; //打电话
      send(message: string): string[]; //群发短信
    }
    
    // 在基础功能上,还有其他功能
    interface PhoneFunction extends BasePhoneFunction {
      game(): void; //打游戏
      listen(): void; //听音学
      watchTV(...tvName:string[]): void; //看电视
      note(): string[]; //便签
    }
    
    class Phone implements PhoneFunction {
      call() {
        return "hi, tom,when are we going to coding?";
      }
    
      send(message: string) {
        console.log(message);
        return ["tom", "jack", "july"];
      }
    
      game(){
        console.log("打游戏")
      }
      listen(){
        console.log("听音乐")
      }
      //注意这里的rest参数用法,形参名不必和接口定义的形参名一致 tvName
      watchTV(...args:string[]){
        console.log(`${args.toString()} `)
      }
    
      note(...args:string[]){
        return [...args]
      }
    
    }
    
    
    const p=new Phone()
    console.log(p.call())//hi, tom,when are we going to coding?
    p.send("新年快乐") //新年快乐
    console.log(p.send("新年快乐"))// 新年快乐 ["tom", "jack", "july"]
    p.game()//打游戏
    p.listen()//听音乐
    p.watchTV("琅琊榜","将夜")//看琅琊榜,将夜
    console.log(p.note("吃饭","睡觉","打豆豆"))//[ '吃饭', '睡觉', '打豆豆' ]
    

访问修饰符

  1. public:public权限最高的,默认就是public,可自由的访问程序里定义的成员
  2. peivate:子类中访问不到,只能在class中才能被访问,实例访问不到
  3. protected:子类中可以访问得到,实例访问不到

TS一文弄懂泛型

泛型

国外大佬的泛型+动图

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值