xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

TypeScript Decorator Metadata All In One

TypeScript Decorator Metadata All In One

@Decorator

With the introduction of Classes in TypeScript and ES6, there now exist certain scenarios that require additional features to support annotating or modifying classes and class members.
Decorators provide a way to add both annotations and a meta-programming syntax for class declarations and members.
Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript.

随着 TypeScript 和 ES6 中类的引入,现在存在某些需要附加功能来支持注释或修改类和类成员的场景。
装饰器提供了一种为类声明和成员添加注释和元编程语法的方法。
装饰器是 JavaScript 的第 2 阶段提案,可作为 TypeScript 的实验性功能使用。

https://www.typescriptlang.org/docs/handbook/decorators.html

reflect-metadata

$ npm i -S reflect-metadata

@Reflect.metadata('inClass', 'A')
class Test {
  @Reflect.metadata('inMethod', 'B')
  public hello(): string {
    return 'hello world';
  }
}

console.log(Reflect.getMetadata('inClass', Test)); 
// 'A'
console.log(Reflect.getMetadata('inMethod', new Test(), 'hello')); 
// 'B'


demo

function logged(value, { kind, name }) {
  if (kind === "method" || kind === "getter" || kind === "setter") {
    return function (...args) {
      console.log(`starting ${name} with arguments ${args.join(", ")}`);
      const ret = value.call(this, ...args);
      console.log(`ending ${name}`);
      return ret;
    };
  }
}

class C {
  @logged
  set x(arg) {}
}

new C().x = 1;

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    console.log('decorators, target, key, desc =', decorators, target, key, desc);
    var c = arguments.length, 
        r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
        r = Reflect.decorate(decorators, target, key, desc);
    } else {
        for (var i = decorators.length - 1; i >= 0; i--) {
            if (d = decorators[i]) {
                r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
            }
        }
    return c > 3 && r && Object.defineProperty(target, key, r), r;
    }
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
function logged(value, { kind, name }) {
    console.log('value, kind, name =', value, kind, name);
    if (kind === "method" || kind === "getter" || kind === "setter") {
        return function (...args) {
            console.log(`starting ${name} with arguments ${args.join(", ")}`);
            const ret = value.call(this, ...args);
            console.log(`ending ${name}`);
            return ret;
        };
    }
}
class C {
    set x(arg) { }
}
__decorate([
    logged,
    __metadata("design:type", Object),
    __metadata("design:paramtypes", [Object])
], C.prototype, "x", null);
new C().x = 1;

// decorators, target, key, desc = (3) [ƒ, undefined, undefined] {constructor: ƒ} x null
// value, kind, name = {constructor: ƒ} undefined undefined
// 1

https://github.com/tc39/proposal-decorators#class-accessors

https://www.typescriptlang.org/play?

Record

Record<Keys, Type>

interface CatType {
  age: number;
  breed: string;
}

type CatName = "miffy" | "boris" | "mordred";

const cats: Record<CatName, CatType> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

cats.boris;
// ^? const cats: Record<CatName, CatInfo>

"use strict";
const cats = {
    miffy: { age: 10, breed: "Persian" },
    boris: { age: 5, breed: "Maine Coon" },
    mordred: { age: 16, breed: "British Shorthair" },
};
cats.boris;
// ^? 

https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type

https://www.typescriptlang.org/play

https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type

custom scheme


export type SchemaArr = {
  type: 'array'
  required?: boolean
  items: Schema
}

export type SchemaObject = {
  type: 'object'
  required?: boolean
  // Record ✅
  properties: Record<string, Schema>
}

type SchemaBoolean = {
  type: 'boolean'
  required?: boolean
}
type SchemaString = {
  type: 'string'
  required?: boolean
}
type SchemaNumber = {
  type: 'number'
  required?: boolean
}

export type Schema = SchemaArr | SchemaObject | SchemaString | SchemaNumber | SchemaBoolean;

https://dev.to/svehla/why-reflect-metadata-suc-s-5fal

refs

https://www.typescriptlang.org/docs/handbook/decorators.html#metadata

https://jkchao.github.io/typescript-book-chinese/tips/metadata.html#基础



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2022-04-13 16:20  xgqfrms  阅读(50)  评论(4编辑  收藏  举报