# \[TYPESCRIPT]  A practical guide to TypeScript decorators  exmaple (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);
```

![](/files/-MM49jFhTEWU4GEaPtFA)

### 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"
  }
}

```

![](/files/-MM5_GNJFMbCVvH1PT_j)

### 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
  }
}

```

![](/files/-MM5dnu05rvlCiNqyhN1)

### 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();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://javascriptuse.gitbook.io/advanced/a-practical-guide-to-typescript-decorators-ok.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
