typescript学习 4.0

类型别名 (type)


示例:
  // ts 别名, 说白就是取一个别的名字
  type numType = number | string;

  let num:numType  = 20;

  console.log(num);

  num = '1904B';

  console.log(num);

  // ts 别名, 说白就是取一个别的名字
  type numType = { num: number | string };

  let obj:numType  = { num: 10 };

  console.log(obj.num);

  // num = '1904B';
  // console.log(num);

交叉类型:交叉类型是将多个类型合并为一个类型。

示例:
  // 交叉类型 & 则必须都要有
  interface NameType{
    obj: {
      name: string
    }
  }

  interface AgeType{
    obj: {
      age: number
    }
  }

  type NameAgeType = AgeType & NameType;

  const obj:NameAgeType = {
    obj: {
      name: '1904B',
      age: 15
    }
  }

  console.log(obj);

联合类型:联合类型与交叉类型很有关联,但是使用上却完全不同。


// 示例: 
  // 联合类型, 取其一即可
  let num: number | string = 20;

  console.log(num);

  num = '1904B';

  console.log(num);

类型推断:数据没有指定明确的类型,那么ts会按照类型推论的规则推断出一个类型

  // 类型推断
  let num = 10;
  console.log(num);

  num = '1904B';
  console.log(num);

Unknown

  • 顶级类型,它可以接收任何类型,但是无法赋值给其他类型(除 any 和 unknown 本身之外),因此在需要接收所有类型的场景下,优先考虑用 unknown 代替 any。

typeof

  • typeof 操作符可以用来获取一个变量的声明类型。
      const jack = {
        name: 'jack Ma',
        age: 18,
      };
      type Person = typeof jack;
      // { name: string, age: number }
    
      const hello:string = 'hello world';
      type Hello = typeof hello;
      // string
    

keyof

  • keyof 操作符用来获取一个类型所有的键值,与 Object.keys 类似,前者获取 interface 的键,后者获取对象的键。
      interface Person {
        name: 'jack Ma',
        age: 17,
      }
      type T1 = keyof Person;
      // 'name' | 'age'
    
    
  • 通常 keyof 会配合着 typeof 使用:
      interface Person {
        name: string,
        age: number
      }
    
      function getPersonValue(obj:Person, key: keyof typeof obj): string|number {
        return obj[key];
      }
    
      # 上面的 key 参数的类型  keyof typeof obj  值为  'name' | 'age',这样可以对 key 值进行约束,避免使用时 key 值拼写错误导致的错误。
    

in

  • in 操作符通常用来实现枚举类型遍历
      type Keys = 'name' | 'age';
      type Person = {
        [K in Keys]: any;
      }
      // { name: any, age: any }
    

装饰器(调用的关键字 @)

  • 装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。

    1. 类装饰器
      示例:
    
      function sealed(target) {
        target.prototype.msg = '1904B';
    
        target.prototype.getMsg = function() {
          console.log(this.msg);
        }
      }
    
      @sealed
      class Greeter {
          // greeting: string;
          constructor(message: string) {
              // this.greeting = message;
          }
          // greet() {
          //     return "Hello, " + this.greeting;
          // }
      }
    
      const g:any = new Greeter('1904B');
      // console.log(g);
      g.getMsg();
    
    1. 装饰器工厂
      示例:
    
      // 装饰器
      // 这就是装饰器工程
      function sealed(msg: string) {// 这是一个装饰器工厂
        return function(target) { // 这就是一个装饰器
          target.prototype.msg = msg;
    
          target.prototype.getMsg = function() {
            console.log(this.msg);
          }
        }
      }
    
      // 类装饰器
      // 调用 @getTarget
    
      // 当前的这个装饰器加上() 代表的是装饰器工厂
      @sealed('1904B-你们是最棒的')
      class Greeter {
          // greeting: string;
          constructor(message: string) {
              // this.greeting = message;
          }
          // greet() {
          //     return "Hello, " + this.greeting;
          // }
      }
    
      const g:any = new Greeter('1904B');
      // console.log(g);
      g.getMsg();
    
    1. 装饰器组合(多个装饰器可以同时应用到一个声明上,)
      示例:
    
      // 书写在同一行上
      @f @g x
    
      // 书写在多行上
      @f
      @g
      x
    
      同样的,在TypeScript里,当多个装饰器应用在一个声明上时会进行如下步骤的操作:
    
      - 由上至下依次对装饰器表达式求值。
      - 求值的结果会被当作函数,由下至上依次调用。
    
      function f() {
        console.log("f(): evaluated"); // 1
        return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
            console.log("f(): called"); // 4
        }
      }
    
      function g() {
        console.log("g(): evaluated"); // 2
        return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
            console.log("g(): called"); // 3
        }
      }
    
      class C {
        @f()
        @g()
        method() {}
      }
    
      **输出结果**
      f(): evaluated
      g(): evaluated
      g(): called
      f(): called
    
      # 注: 会先执行装饰器工厂,依次执行完所有的装饰器工厂之后,再从最内层的装饰器进行依次执行
    
    1. 方法装饰器(方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。)
    
      方法装饰会在运行时传入下列3个参数:
      1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
      2、成员的名字。
      3、成员的属性描述符{value: any, writable: boolean, enumerable: boolean, configurable: boolean}function method(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        console.log(target);
        console.log("prop " + propertyKey);
        console.log("desc " + JSON.stringify(descriptor) + "\n\n");
      };class Hello{
        name: string;
        age: number;
        constructor() {
          console.log('hello');
          this.name = 'yugo';
        }
      ​
        @method
        hello(){
          return 'instance method';
        }
    
        @method
        static shello(){
          return 'static method';
        }
      }
    
    1. 访问器装饰器(访问器装饰器声明在一个访问器的声明之前(紧靠着访问器声明)。)
      示例:
    
      访问器装饰器表达式会在运行时当作函数被调用,传入下列3个参数:
    
      - 1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
      - 2. 成员的名字。
      - 3. 成员的属性描述符。
    
      function configurable(value: boolean) {
          return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
              descriptor.configurable = value;
          };
      }
    
    
      class Point {
          private _x: number;
          private _y: number;
          constructor(x: number, y: number) {
              this._x = x;
              this._y = y;
          }
    
          @configurable(false)
          get x() { return this._x; }
    
          @configurable(false)
          get y() { return this._y; }
      }
    
    1. 属性装饰器(属性装饰器声明在一个属性声明之前(紧靠着属性声明)。)
    1. 参数装饰器(参数装饰器声明在一个参数声明之前(紧靠着参数声明)。)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值