TypeScript 高级语法

简介: TypeScript 高级语法

类的装饰器

初始化项目

npm init -y

tsc --init

npm install ts-node -D

npm install typescript

image.png

类的装饰器

装饰器本身是一个函数

装饰器通过@符号来使用

打开支持

支持装饰器语法

装饰器会在类定义好,就立即执行。并不是实例化的时候进行装饰。

类装饰器接受的参数是构造函数

image.png

多个装饰器的执行顺序

image.png

image.png

函数包装开关

image.png

image.png

image.png

覆盖类的属性

image.png

添加类属性

image.png

image.png

function testDecorator() {
  return function<T extends new (...args: any[]) => any>(constructor: T) {
    return class extends constructor {
      name = 'lee';
      getName() {
        return this.name;
      }
    };
  };
}
const Test = testDecorator()(
  class {
    name: string;
    constructor(name: string) {
      this.name = name;
    }
  }
);
const test = new Test('dell');
console.log(test.getName());

方法装饰器

// 普通方法,target 对应的是类的 prototype
// 静态方法,target 对应的是类的构造函数
function getNameDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
  // console.log(target, key);
  // descriptor.writable = true;
  descriptor.value = function() {
    return 'decorator';
  };
}
class Test {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  @getNameDecorator
  getName() {
    return this.name;
  }
}
const test = new Test('dell');
console.log(test.getName());

image.png

image.png

为函数添加描述符

image.png

image.png

image.png

变更函数

image.png

访问器的装饰器

function visitDecorator(target: any, key: string, descriptor: PropertyDescriptor) {
  // descriptor.writable = false;
}
class Test {
  private _name: string;
  constructor(name: string) {
    this._name = name;
  }
  get name() {
    return this._name;
  }
  @visitDecorator
  set name(name: string) {
    this._name = name;
  }
}
const test = new Test('dell');
test.name = 'dell lee';
console.log(test.name);

属性的装饰器

// function nameDecorator(target: any, key: string): any {
//   const descriptor: PropertyDescriptor = {
//     writable: false
//   };
//   return descriptor;
// }
// test.name = 'dell lee';
// 修改的并不是实例上的 name, 而是原型上的 name
function nameDecorator(target: any, key: string): any {
  target[key] = 'lee';
}
// name 放在实例上
class Test {
  @nameDecorator
  name = 'Dell';
}
const test = new Test();
console.log((test as any).__proto__.name);

手写属性描述器

image.png

修改的并不是实例上的 name, 而是原型上的 name

image.png

image.png

参数装饰器

// 原型,方法名,参数所在的位置
function paramDecorator(target: any, method: string, paramIndex: number) {
  console.log(target, method, paramIndex); // 原型,方法名,参数所在的位置
}
class Test {
  getInfo(name: string, @paramDecorator age: number) {
    console.log(name, age);
  }
}
const test = new Test();
test.getInfo('Dell', 30);

装饰器实际使用的小例子

const userInfo: any = undefined;
function catchError(msg: string) {
  return function(target: any, key: string, descriptor: PropertyDescriptor) {
    const fn = descriptor.value;
    descriptor.value = function() {
      try {
        fn();
      } catch (e) {
        console.log(msg);
      }
    };
  };
}
class Test {
  @catchError('userInfo.name 不存在')
  getName() {
    return userInfo.name;
  }
  @catchError('userInfo.age 不存在')
  getAge() {
    return userInfo.age;
  }
  @catchError('userInfo.gender 不存在')
  getGender() {
    return userInfo.gender;
  }
}
const test = new Test();
test.getName();
test.getAge();

reflect-metadata

import 'reflect-metadata';
class User {
  @Reflect.metadata('data', 'test')
  @Reflect.metadata('data1', 'test')
  getName() {}
}
class Teacher extends User {}
console.log(Reflect.getOwnMetadataKeys(User.prototype, 'getName'));
console.log(Reflect.getOwnMetadataKeys(Teacher.prototype, 'getName'));

装饰器的执行顺序

import 'reflect-metadata';
function showData(target: typeof User) {
  for (let key in target.prototype) {
    const data = Reflect.getMetadata('data', target.prototype, key);
    console.log(data);
  }
}
function setData(dataKey: string, msg: string) {
  return function(target: User, key: string) {
    Reflect.defineMetadata(dataKey, msg, target, key);
  };
}
@showData
class User {
  @setData('data', 'age')
  getName() {}
  @setData('data', 'age')
  getAge() {}
}


目录
相关文章
|
5月前
|
XML JavaScript 前端开发
TypeScript 中的“as”语法是什么?
TypeScript 中的“as”语法是什么?
|
5月前
|
JavaScript 前端开发 开发者
深入理解ArkTS:Harmony OS 应用开发语言 TypeScript 的基础语法和关键特性
深入理解ArkTS:Harmony OS 应用开发语言 TypeScript 的基础语法和关键特性
555 0
|
3月前
|
存储 JavaScript 开发者
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(四)
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(四)
37 0
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(四)
|
3月前
|
JavaScript API 网络架构
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(三)
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(三)
35 0
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(三)
|
3月前
|
JavaScript API
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(二)
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(二)
28 0
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(二)
|
3月前
|
JavaScript API UED
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(五)
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(五)
39 0
|
3月前
|
JavaScript 前端开发 API
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(一)
【Vue3+TypeScript】CRM系统项目搭建之 — 关于 VUE3 语法新变化(一)
43 0
|
5月前
|
JavaScript 编译器 开发者
TypeScript中的“as”语法是什么?
TypeScript中的“as”语法是什么?
34 0
|
5月前
|
JavaScript 前端开发 编译器
TypeScript中的高级类型:联合类型、交叉类型与条件类型深入解析
【4月更文挑战第23天】探索TypeScript的高级类型。这些特性增强类型系统的灵活性,提升代码质量和维护性。
|
5月前
|
JavaScript 前端开发 编译器
TypeScript中的“as”语法是什么?
TypeScript中的“as”语法是什么?
68 0
下一篇
无影云桌面