ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

React知识点

2021-02-28 11:57:39  阅读:108  来源: 互联网

标签:function 知识点 string number React let 类型 name


一、基本数据类型

  1. boolean

    let test1: boolean = true;
    let test2: boolean = new Boolean(); //报错,因为Boolean不是布尔值
    let test3: boolean = Boolean(1);  //正确,直接调用Boolean,可以返回一个boolean类型。
    
  2. number

    let hex: number = 10;
    
  3. string

    let myAge: string = 'woshi';
    
  4. void,没有空值,可以修饰没有任何返回值的函数

    function handle(): void { }
    
  5. null、undefined,是所有类型的子类型,可以复制给其他类型的变量

    let u: undefined = undefined;
    let n: null = null;
    
  6. any 任意值

    • 是所有类型的子类型,允许被赋值为任意类型。

    • 在任意值上访问任何属性都是允许的,也允许调用任何方法。

    • 变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型。

    • 类型推断:没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。

      //报错,声明指定类型后,不能赋值其他类型
      let myFavoriteNumber: string = 'seven';
      myFavoriteNumber = 7;
      //正确
      let myFavoriteNumber: any = 'seven';
      myFavoriteNumber = 7;
      
      //调用任何方法、属性
      let anyThing: any = 'Tom';
      console.log(anyThing.myName);
      anyThing.setName('Jerry');
      
      //声明的时候,未指定其类型,被识别为任意值类型
      let newdata;                    
      
  7. 类型推断:没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。

    let myFavoriteNumber = 'seven';
    myFavoriteNumber: string = 'seven';
    myFavoriteNumber = 7;  //报错,类型推论将myFavoriteNumber定义成一个字符串,不能赋值number类型
    

二、对象类型—接口

  • 定义对象的类型
  • 约束函数:传递参数对象具体类型,格式、返回值要以什么类型返回
  • 限制变量对象:类型、格式
  1. 接口修饰的对象,对象得跟接口一样的数据格式、类型。

    interface LabelledValue {
        label: string;
        label2: number;
      }
    
      function printLabel(labelledObj: LabelledValue) {
        console.log(labelledObj.label);
        console.log(labelledObj.size);   //编译报错,因为接口中没有size。
      }
      
      let myObj = {size: 10, label: "Size 10 Object", label2: 233}; //编译报错,因为接口中没有size。
      printLabel(myObj);
    
  2. 可选属性

    • 接口修饰的对象,对象可以只有部分接口中的属性,不一样要全写

    • 对象中仍然不允许添加接口中未定义的属性

      interface Person {
          name: string;
          age?: number;
      }
      let tom: Person = {
          name: 'Tom'  //可以不写age,因为age是可选的。
      };
      
      interface Person {
          name: string;
          age?: number;
      }
      let tom: Person = {
          name: 'Tom',
          age: 25,
          gender: 'male' //接口中没该属性,因此不能写。
      };
      
  3. 接口中使用可索引类型去描述(约束)对象。(可以对比接口方式去声明数组用到的可索引类型)

    • 可索引类型:[propName: string]: any ,具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型

      //例:接口约束:接口可以通过索引访问,索引的类型是字符串,值的类型也必须是any,且必须有name这个属性
      interface Person {
          name: string;
          age?: number;
          [propName: string]: any;
      }
      
      let tom: Person = {
          name: 'Tom',
          gender: 'male'
      };
      
  4. 只读属性

    • 只读: 对象变量声明时给只读属性赋值,而不是第一次给只读属性赋值的时候

      interface Person {
              readonly id: number; 
              name: string;
              age?: number;
              [propName: string]: any;
          }
          
          let tom: Person = { //报错 因为接口中的id是只读,声明时必须给其赋值
              name: 'Tom',  
              gender: 'male'
          };  
          tom.id = 89757; //报错 id,只能读,不能重新赋值
      
    • 有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性

      interface Person {
          readonly id: number;
          name: string;
          age?: number;
          [propName: string]: any;
      }
      let tom: Person = {
          id: 89757,
          name: 'Tom',
          gender: 'male'
      };
      tom.id = 9527;   //报错 id,只能读,不能重新赋值
      

三、数组的类型

​ 数组声明(定义)方式:

  • 类型 + 方括号: number[]
  • 数组泛型:Array
  • 用接口表示数组
  • 类数组:如arguments
  • any在数组中的应用
  1. 类型 + 方括号:

    let fibonacci: number[] = [1, '1', 2, 3, 5];  //报错,因为不能出场除了number之外的类型
    
  2. 数组泛型:

    let fibonacci: Array<number> = [1,2,3,4,5];
    
  3. 接口中使用可索引的类型去描述 (约束) 数组:

    interface NumberArray {
        [index: number]: number
    }
    let fibonacci: NumberArray = [1,2,3,4,5];
    
  4. 类数组: 不是数组类型, 比如:arguments,不能用普通的方式描述。

    function sun() {
        let args: number[] = arguments; //报错,arguments是类数组,不能用普通的方式描述。
    }
    
    //例子1:可以通过接口的方式声明变量接收arguments。
    //在这个例子中,我们除了约束当索引的类型是数字时,值的类型必须是数字之外,也约束了它还有 length 和 callee 两个属性。
    function sum() {
        let args: {
            [index: number]: number;
            length: number;
            callee: Function;
        } = arguments;
    }
    
    //例子二:IArguments 是 TypeScript 中定义好了的类型,用来声明类数组
    function sum() {
        let args: IArguments = arguments;  
    }
    
  5. any在数组中的应用: 表示数组中允许出现任意类。

    let list: any[] = ['xcatliu', 25, { website: 'http://xcatliu.com' }];
    

四、函数的类型

  • 定义函数方式:函数声明、函数表达式
  1. 函数声明:

    • 输入多余(或者少于要求)的参数,是不被允许。

    • 函数输入和输出都要考虑typeScript约束

      function sum(x: number, y: number): number {
          return x + y;
      }
      sum(1, 2, 3);  //不允许多于约束参数个数
      
  2. 函数表达式:

    • 方式一:

      let mySum = function (x: number, y: number): number {
          return x + y;
      };
      
    • 方式二:用 => 来定义函数,左边是参数类型,右边是返回值类型(区别es6中的箭头函数)。

      //1.定义变量 add,指定类型为 (x: number, y: number)=> number
      let add:(x: number, y: number)=> number
      
      //2.给变量赋值函数,其符合上面定义的函数类型
      add = (arg1: number, arg2: number) => arg1 + arg2
      
      //结合1.2,实现函数的定义
      let add(X: number, y: number)=> number = (x: number, y:number) => {
          return x + y;
      } 
      
      
  3. 默认参数、可选参数

    //设置参数age可以穿也可以不传
    function getInfo(name: string,age?: number): string {
      return `${name}----${age}`
    }
    getInfo("jiangjiang");
    
    //设置参数age,当不传的时候默认赋值20
    function getPerson(name: String,age: number=20): string  {
       return `${name}----${age}`
    }
    
  4. 函数重载

    • 重载允许一个函数接受不同数量或者类型的参数时i,作出不同的处理。

      ###//例:对比联合类型传承、函数重载优缺点
      
      //联合类型传承:有一个缺点,就是不能够精确的表达,输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串。
      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('');
          }
      }
      
      //函数重载
      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('');
          }
      }
      

五、联合类型

  • 约束变量的类型不局限一种类型,可以是多种类型。

  • 使用 | 分隔每个类型。

    let myFavoriteNumber: string | number;
    myFavoriteNumber = 'seven';
    myFavoriteNumber = 7;
    //允许 myFavoriteNumber 的类型是 string 或者 number,但是不能是其他类型。
    
  1. 访问联合类型的属性或方法。

    • TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法

      //案例1
      function getLength(something: string | number): number {
          return something.length; //报错,因为length不是string跟number的共有属性
      }
      
      //案例2
      function getString(something: string | number): string {
          return something.toString();//正确,toString是他们的共有方法
      }
      
      //案例3
      interface Cat {
          name: string;
          run(): void;
      }
      interface Fish {
          name: string;
          swim(): void;
      }
      function getName(animal: Cat | Fish) {
          return animal.name; //正确,name是Cat跟Fish共有属性
      }
      
    • 联合类型的变量在赋值的时候,会根据类型推论规则推断出一个类型。

      let myFavoriteNumber: string | number;
      myFavoriteNumber = 'seven';
      console.log(myFavoriteNumber.length); //正确,因为赋值“seven”时,变量被推断为string类型,string具有length属性。
      myFavoriteNumber = 7;
      console.log(myFavoriteNumber.length); //报错,因为赋值7时,变量被推断为number类型,number不具有length属性
      

六、类型断言

  1. 作用、语法

    • 作用:可以用来手动指定一个值的类型。

    • 语法:

      //写法一:
      值 as 类型
      //写法二:
      <类型>值
      
  2. 应用场景:

    • 联合类型可以被断言为其中一个类型

    • 父类可以被断言为子类

    • 任何类型都可以被断言为 any

    • any 可以被断言为任何类型

    1. 将一个联合类型断言为其中一个类型

      • 优点:联合类型只能访问其共有的方法、属性,断言具体类型后,即使不是共有属性、方法也可以使用。
      • 缺点:类型断言只能「欺骗」Typescript编译器(即使编译通过),但是运行时可能会报错。
      //案例一:断言优点
      interface Cat {
          name: string;
          run(): void;
      }
      interface Fish {
          name: string;
          swim(): void;
      }
      function isFish(animal: Cat | Fish) {
          //即使swin不是联合类型Cat、Fish共有方法,通过断言成Fish,就可以骗过编译器
          if (typeof (animal as Fish).swim === 'function') {
              return true;
          }
          return false;
      }
      
      //案例二:缺点
      interface Cat {
          name: string;
          run(): void;
      }
      interface Fish {
          name: string;
          swim(): void;
      }
      function swim(animal: Cat | Fish) {
          //编译通过,但是运行时报错,因为参数tom: Cat并不存在swim方法。
          (animal as Fish).swim();
      }
      const tom: Cat = {
          name: 'Tom',
          run() { console.log('run') }
      };
      swim(tom);
      
    2. 将一个父类断言为更加具体的子类

      子类也可以断言成相应的父类

      • 使用类型断言:判断传入函数的类型是不是Child1

        class Child1 extends Error {
          code: number = 0;
        }
        class Child2 extends Error {
          statusCode: number = 200;
        }
        function isChild1(error: Error) {
          //可以将父类Error断言具体子类Child1:这样就可以访问到Child1的code属性,若不断言则报错,因为Error不存在code属性。
          if(typeof(error as Child1).code == 'number') {
            return true;
          }else {
            return false;
          }
        

      }

      
      + 使用instanceof:判断传入函数的类型是不是Child1
      
      ```typescript
      class Child1 extends Error {
        code: number = 0;
      }
      class Child2 extends Error {
        statusCode: number = 200;
      }
      function isChild1(error: Error) {
        if(error instanceof child1) {
          return true;
        }else {
          return false;
        }
      }
      
      • 断言类型跟instanceof区别:instanceof只能用于判断继承的父子关系,不能用来判断接口。

        interface Child1 extends Error {
            code: number;
        }
        interface Chilid2 extends Error {
            statusCode: number;
        }
        function isChild1(error: Error) {
          //报错,因为Child1是一个接口,无法使用instaceof,这边应该使用断言类型。
          if(error instanceof child1) {
            return true;
          }else {
            return false;
          }
        
    3. 将任何一个类型断言为any:as any

      • 此用法可能会掩盖真正的类型错误,如果不是非常确定,就不要用它。
      //编译报错,因为window对象不存在foo;
      window.foo = 1;
      
      //any类型,访问任何属性都是允许的。
      (window as any).foo = 1;
      
    4. 将any断言为一个具体的类型

      function getCacheData(key: string): any {
          return (window as any).cache[key];
      }
      
      interface Cat {
          name: string;
          run(): void;
      }
      
      //getCacheData,它的返回值是 any,此时可以将其断言成具体的Cat类型方便后续操作。
      const tom = getCacheData('tom') as Cat;
      tom.run();
      
  3. 区别:类型断言、类型转换

    • 类型转换:会真的影响到变量的类型。

    • 类型断言:只会影响 TypeScript 编译时的类型,类型断言语句在编译结果中会被删除。

      function toBoolean(something: any): boolean {
          return Boolean(something);
      }
      //类型转换:将number类型转成boolean类型
      toBoolean(1);
      
  4. 区别:类型断言、类型约束

    • 类型断言:父子关系可以互相断言,即:父类型 as 子类型子类型 as 父类型

      interface Animal {
          name: string;
      }
      interface Cat {
          name: string;
          run(): void;
      }
      const animal: Animal = {
          name: 'tom'
      };
      let tom = animal as Cat; //正确,因为他们存在父子关系
      
    • 类型约束:可以父类型: 子类型,不可以子类型:父类型

      interface Animal {
          name: string;
      }
      interface Cat {
          name: string;
          run(): void;
      }
      const animal: Animal = {
          name: 'tom'
      };
      let tom: Cat = animal; //报错,Animal 可以看作是 Cat 的父类,当然不能将父类的实例赋值给类型为子类的变量。
      
  5. 区别:类型断言、泛型

    interface Cat {
        name: string;
        run(): void;
    }
    //类型断言
    function getCacheData(key: string): any {
        return (window as any).cache[key];
    }
    const tom = getCacheData('tom') as Cat;
    tom.run();
    
    //泛型,通过给 getCacheData 函数添加了一个泛型 <T>,我们可以更加规范的实现对 getCacheData 返回值的约束,这也同时去除掉了代码中的 any,是最优的一个解决方案。
    function getCacheData<T>(key: string): T {
        return (window as any).cache[key];
    }
    const tom = getCacheData<Cat>('tom');
    tom.run();
    `
    

标签:function,知识点,string,number,React,let,类型,name
来源: https://blog.csdn.net/jiangyoufu123456789/article/details/114214905

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有