Parameter Properties
Parameter Properties — синтаксический сахар TypeScript в конструкторах классов: модификаторы
public,private,protected,readonlyперед параметром конструктора автоматически создают одноимённое свойство класса и присваивают ему переданное значение.
Зачем нужно
Убирают бойлерплейт: без parameter properties нужно объявить поле, принять его параметром, присвоить в теле. С ними — всё в одну строку. Особенно полезно в dependency injection, DTO и value objects.
Где используется
- Простые сервисы и классы-обёртки
- DTO и value objects
- Dependency injection (NestJS, InversifyJS)
- Классы с несколькими readonly-полями
Основной контент
До и после Parameter Properties
// Без parameter properties — 9 строк
class UserService {
private readonly userRepo: UserRepository;
private readonly logger: Logger;
constructor(userRepo: UserRepository, logger: Logger) {
this.userRepo = userRepo;
this.logger = logger;
}
}
// С parameter properties — 4 строки
class UserService {
constructor(
private readonly userRepo: UserRepository,
private readonly logger: Logger,
) {}
}
Доступные модификаторы
class Example {
constructor(
public publicProp: string, // доступно снаружи
private privateProp: number, // только внутри класса
protected protectedProp: boolean, // класс + наследники
readonly readonlyProp: Date, // публичный + только чтение
public readonly id: string, // явно публичный + readonly
) {}
}
const e = new Example("a", 1, true, new Date, "u-1");
console.log(e.publicProp); // OK
console.log(e.readonlyProp); // OK
// e.privateProp; // Error
// e.readonlyProp = new Date(); // Error — readonly
Комбинирование с обычными параметрами
class Parser {
constructor(
public readonly format: string,
rawInput: string, // обычный параметр — НЕ становится свойством
) {
console.log(rawInput.trim()); // доступен в конструкторе
}
}
const p = new Parser("json", " data ");
// p.format — OK
// p.rawInput — Error (свойства нет)
Parameter properties с наследованием
class Animal {
constructor(public name: string) {}
}
class Dog extends Animal {
constructor(
name: string,
public breed: string,
) {
super(name); // super обязателен
}
}
const dog = new Dog("Rex", "Labrador");
console.log(dog.name); // "Rex"
console.log(dog.breed); // "Labrador"
Dependency Injection (NestJS-стиль)
class OrderService {
constructor(
private readonly orderRepo: OrderRepository,
private readonly emailService: EmailService,
private readonly logger: Logger,
) {}
async createOrder(data: CreateOrderDto): Promise<Order> {
const order = await this.orderRepo.save(data);
await this.emailService.sendConfirmation(order);
this.logger.log(`Order ${order.id} created`);
return order;
}
}
Частые ошибки
- Забыть
superпри наследовании — конструктор подкласса обязан вызватьsuper(...)до использованияthis. - Обычный параметр без модификатора как свойство — параметр без
public/private/protected/readonlyне создаёт свойство. - Изменить
readonly-поле в методе — компилятор выдаст ошибку; используйтеprivateесли нужна мутация. - Использовать в не-конструкторах — parameter properties работают только в
constructor, не в обычных методах.
Связанные темы
- abstract классы
- implements -- реализация интерфейсов
- Readonly свойства
- interface -- объявление и использование
- _MOC TypeScript