[TYPESCRIPT] A practical guide to TypeScript decorators exmaple (ok)

https://app.gitbook.com/@javascriptuse/s/advanced/typescript-mot-so-scripts-hay-duoc-su-dung-trong-typescripts-ok

Ví dụ 1: sử dụng decorators

function delay() {
	console.log("delay(): evaluated");
	return function(target,propertyKey: string, description: PropertyDescription) {
		console.log("delay(): called");
	}
}
function other() {
	console.log("other(): evaluated");
	return function(target,propertyKey: string, description: PropertyDescription) {
		console.log("other(): called");
	}
}
class TimeOut {
	count: number = 1;
	@delay();
	@other();
	callMe() {
		this.count ++;
		console.log('callMe is been called with', this.count);
	}
}
let timeout = new TimeOut();
console.log('going to call this method callMe');
timeout.callMe();
console.log('after callMe is been called', timeout.count);

Ví dụ 2: sử dụng decorators

C:\Users\Administrator\Desktop\typescript-ru6t7p\index.ts

import { id } from './id.decorator';
export class Component {
  @id() instanceId: string;
  log() {
    console.log('ids', this.instanceId);
  }
}
const component = new Component();
component.log();

C:\Users\Administrator\Desktop\typescript-ru6t7p\id.decorator.ts

export function id() {
  return (protoOrDescriptor: {} | any, name ?: PropertyKey): any => {
    const descriptor = {
      get(this: any) {
        const propertyName = name !== undefined ? `__${String(name)}` : `__${protoOrDescriptor.key}`;
        if (!this[propertyName]) {
          // if the id is used for a CSS selector prefix _ as selectors cannot start with numbers
          this[propertyName] = `_${createId()}`; 
        }
        return this[propertyName];
      },
      enumerable: true,
      configurable: true,
    };
    return name !== undefined ? legacyId(descriptor, protoOrDescriptor as {}, name) : standardId(descriptor, protoOrDescriptor as any);
  };
}
export function createId() {
  return Math.random().toString(36).substr(2, 9);
}
const legacyId = (descriptor: PropertyDescriptor, proto: {}, name: PropertyKey) => {
  Object.defineProperty(proto, name, descriptor);
};
const standardId = (descriptor: PropertyDescriptor, element: any) => ({
  kind: 'property',
  placement: 'prototype',
  key: element.key,
  descriptor,
});

C:\Users\Administrator\Desktop\typescript-ru6t7p\package.json

{
  "name": "typescript",
  "version": "0.0.0",
  "private": true,
  "dependencies": {
    "typescript": "^4.0.5"
  }
}

Ví dụ 3: sử dụng decorators

C:\Users\Administrator\Desktop\typescript-decorators\calculate-time.ts

import { performance } from "perf_hooks";
const measure = (target: Object, propertyKey: string, descriptor: PropertyDescriptor) => {
  const originalMethod = descriptor.value;
  descriptor.value = function (...args) {
    const start = performance.now();
    const result = originalMethod.apply(this, args);
    const finish = performance.now();
    console.log(`Execution time: ${finish - start} milliseconds`);
    return result;
  };
  return descriptor;
};
class Rocket {
  @measure
  launch() {
    console.log("Launching in 3... 2... 1...");
  }
}
const rocket = new Rocket();
rocket.launch();

C:\Users\Administrator\Desktop\typescript-decorators\package.json

{
  "name": "learn-decorator",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "tsc",
    "start": "ts-node calculate-time.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^13.13.5",
    "ts-node": "^8.10.1",
    "typescript": "^3.9.2"
  },
  "dependencies": {
    "reflect-metadata": "^0.1.13"
  }
}

C:\Users\Administrator\Desktop\typescript-decorators\tsconfig.json

{
  "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true
  }
}

Ví dụ 4: sử dụng decorators

C:\Users\Administrator\Desktop\typescript-decorators\error-guard.ts

const minimumFuel = (fuel: number) => (
  target: Object,
  propertyKey: string,
  descriptor: PropertyDescriptor
) => {
  const originalMethod = descriptor.value;
  descriptor.value = function (...args) {
    if (this.fuel > fuel) {
      originalMethod.apply(this, args);
    } else {
      console.log("Not enough fuel!");
    }
  };
  return descriptor;
};
class Rocket {
  fuel = 50;
  @minimumFuel(100)
  launchToMars() {
    console.log("Launching to Mars in 3... 2... 1...");
  }
  @minimumFuel(25)
  launchToMoon() {
    console.log("Launching to Moon in 3... 2... 1...");
  }
}
const rocket = new Rocket();
rocket.launchToMars();
rocket.launchToMoon();

Last updated

Navigation

Lionel

@Copyright 2023