рдкреНрд░рддреНрдпреЗрдХ рдХреЛрдгреАрдп рдбреЗрд╡рд▓рдкрд░ рдиреЗ рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рдХреЛ рдЯрд╛рдЗрдордХреЛрдб рдХреЛрдб рдореЗрдВ рджреЗрдЦрд╛ред рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ, рдирд┐рд░реНрднрд░рддрд╛ рдЗрдВрдЬреЗрдХреНрд╢рди рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдпрд╛ рдХрд┐рд╕реА рдШрдЯрдХ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдпрд╛ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлреНрд░реЗрдорд╡рд░реНрдХ рдпрд╛ рдХрдВрдкрд╛рдЗрд▓рд░ (рдХреЛрдгреАрдп рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ) рдХреЗ рд▓рд┐рдПред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреЛрдгреАрдп рдХреЗрд╡рд▓ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдХрдИ рдЕрдиреНрдп рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИрдВ рдЬреЛ рдШреЛрд╖рдгрд╛ рдХреА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдб рдХреА рд╕рд╛рджрдЧреА рдФрд░ рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЕрддреАрдд рдореЗрдВ .NET рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ, рдореБрдЭреЗ рдЯреАрдПрд╕ рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕ рдФрд░ .NET рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рдмреАрдЪ рдмрд╣реБрдд рд╕реА рд╕рдорд╛рдирддрд╛рдПрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИрдВред рдЕрдВрдд рдореЗрдВ, рдмрдврд╝рддреЗ NestJS рдмреИрдХрдПрдВрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлреНрд░реЗрдорд╡рд░реНрдХ (рдиреЛрдб рдкрд░ рдПрдХ рдЕрдореВрд░реНрдд) рднреА рд╕рдЬреНрдЬрд╛рдХрд╛рд░реЛрдВ рдХреЗ рднрд╛рд░реА рдЙрдкрдпреЛрдЧ рдФрд░ рдПрдХ рдШреЛрд╖рдгрд╛рддреНрдордХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рд╕рдм рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ,рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рдкрдардиреАрдп рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП? рд╣рдо рд╕рднреА рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рдЯреАрдПрд╕ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдорд┐рд▓рддрд╛ рд╣реИред рдЬрд┐рд╕рдореЗрдВ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреА рдХреЛрдИ рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд╣реАрдВ рд╣реИ, рдЬреИрд╕реЗ рдХрдИ рдЕрдиреНрдп рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реБрд╡рд┐рдзрд╛рдПрдБред рдЗрд╕рд▓рд┐рдП, рдореЗрд░реЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рд╕рдВрдХрд▓рди рдХреЗ рдмрд╛рдж рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рддреЗ рд╣реБрдП, рдореИрдВрдиреЗ рдорд┐рдиреНрд╕реНрдХ рдореЗрдВ рдмреИрдардХ рдореЗрдВ рднрд╛рд╖рдг рджрд┐рдпрд╛ рдФрд░ рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

. , .
@NgModule({
imports: [
CommonModule,
],
exports: [
],
})
export class NbThemeModule {}
- for component declaration
@Component({
selector: 'nb-card-header',
template: `<ng-content></ng-content>`,
})
export class NbCardHeaderComponent {}
, , , .
, tsconfig.json
, emitDecoratorMetadata
experimentalDecorators
, .
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es2017",
},
}
, тАФ , , , get , . @expression
, @
. expression
. , , .
, тАФ , , . - .
, тАФ . , -, ( ). , , .
тАФ . Typescript :
declare type MethodDecorator =
<T>(
target: Object,
propertyKey: string | symbol,
descriptor: TypedPropertyDescriptor<T>)
=> TypedPropertyDescriptor<T> | void;
, . :
:
interface TypedPropertyDescriptor<T> {
enumerable?: boolean;
configurable?: boolean;
writable?: boolean;
value?: T;
get?: () => T;
set?: (value: T) => void;
}
, , .
, - , . Javascript .
, - . тАФ .
class TestServiceDeco {
@LogTime()
testLogging() {
...
}
}
, . Typescript , . , - , .
:
function LogTime() {
return (target: Object, propertyName: string, descriptor: TypedPropertyDescriptor<Function>) => {
const method = descriptor.value;
descriptor.value = function(...args) {
console.time(propertyName || 'LogTime');
const result = method.apply(this, args);
console.timeEnd(propertyName || 'LogTime');
return result;
};
};
}
, тАФ , . тАФ target, propertyName . .
тАФ , . , , . .
Javascript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function LogTime() {
return (target, propertyName, descriptor) => {
const method = descriptor.value;
descriptor.value = function (...args) {
console.time(propertyName || 'LogTime');
const result = method.apply(this, args);
console.timeEnd(propertyName || 'LogTime');
return result;
};
};
}
exports.LogTime = LogTime;
, Typescript . :
Object.defineProperty(exports, "__esModule", { value: true });
const log_time_decorator_1 = require("../src/samples/log-time.decorator");
class TestServiceDeco {
testLogging() {
... }
}
__decorate([
log_time_decorator_1.LogTime(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], TestServiceDeco.prototype, "testLogging", null);
__decorate
, .
, target
prototype
, .
, __decorate
, , . , . .
, . тАФ . тАФ . тАФ Dependency Injection. . , :
@CustomBehavior({
singleton: false,
})
class TestServiceDeco {
constructor() {
console.log('TestServiceDeco ctor');
}
}
, Typescript:
declare type ClassDecorator =
<TFunction extends Function>(target: TFunction)
=> TFunction | void;
:
import 'reflect-metadata';
interface Metadata {
singleton?: boolean;
}
function CustomBehavior(metadata: Metadata) {
return function(ctor: Function) {
Reflect.defineMetadata('metadataKey', metadata, ctor);
}
}
. тАФ singelton- . .
:
Reflect-metadata Typescript. , тАФ . , , .
import 'reflect-metadata';
const instancesMap: Map<Object, Object> = new Map<Object, Object>();
function getInstance<T>(tType: new () => T): T {
let metadata = Reflect.getMetadata('metadataKey', tType) as Metadata;
if (metadata.singleton) {
if (!instancesMap.has(tType)) {
instancesMap.set(tType, new tType());
}
return instancesMap.get(tType) as T;
} else {
return new tType() as T;
}
}
getInstance
, , ,Reflect.getMetadata
, . any
, as Metadata
- , .
tType: new () => T
- - , Map
, , .
getInstance
, .
, . , Javascript .
. , , , . , Person
Age
, 18 60. :
class Person {
@Age(18, 60)
age: number;
}
:
declare type PropertyDecorator =
(target: Object, propertyKey: string | symbol) => void;
:
import 'reflect-metadata';
function Age(from: number, to: number) {
return function (object: Object, propertyName: string) {
const metadata = {
propertyName: propertyName,
range: { from, to },
};
Reflect.defineMetadata(`validationMetadata_${propertyName}`, metadata, object.constructor);
};
}
, . . , , , . , .
:
class Person {
...
}
__decorate([
age_decorator_1.Age(18, 60),
__metadata("design:type", Number)
], Person.prototype, "age", void 0);
, __decorate
, .
, тАФ , . тАФ , , .
, :
function validate<T>(object: T) {
const properties = Object.getOwnPropertyNames(object);
properties.forEach(propertyName => {
let metadata = Reflect.getMetadata(metaKey + propertyName, object.constructor);
if (metadata && metadata.range) {
const value = object[metadata.propertyName];
if (value < metadata.range.from || value > metadata.range.to) {
throw new Error('Validation failed');
}
}
});
}
, , . .
:
const person = new Person();
person.age = 40;
validate(person);
person.age = 16;
validate(person);
, , , .
, :
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
Class-Validator
Class-Validator, . .
export class Post {
@Length(10, 20)
title: string;
@IsInt()
@Min(0)
@Max(10)
rating: number;
@IsEmail()
email: string;
}
...
validate(object).then(errors => {
if (errors.length > 0) {
console.log("validation failed. errors: ", errors);
} else {
console.log("validation succeed");
}
});
, . .
, NestJS @UsePipes(new ValidationPipe())
http .
Typescript , . , -. , , , , , , , тАж Angular NestJS. ( ).
, , , , , !
ps рд▓рд┐рдЦрддреЗ рд╕рдордп (рдпрд╛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд▓реЗрдЦ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рддреЗ рд╣реБрдП), рдореИрдВрдиреЗ рд╣рдм рдкрд░ рдПрдХ рдФрд░ рд╡рд╣реАрдВ рдкрд╛рдпрд╛, рдЬреЛ рд╕рдЬреНрдЬрд╛рдХрд╛рд░реЛрдВ рдХреЗ рд╡рд┐рд╖рдп рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдкреНрд░рдХрдЯ рдХрд░рддрд╛ рд╣реИред рдореИрдВ рдПрдХ рд▓рд┐рдВрдХ рджреЗрддрд╛ рд╣реВрдВ