Проверка properties в приложениях | Вопросы для собеседования | Skilio
Проверка properties в приложениях
Вопрос:

Как бы вы реализовали проверку типа свойств с обеспечением безопасности для наследования классов? Покажите, как гарантировать проверку типов во время выполнения для унаследованных свойств, сохраняя при этом статические гарантии типов TypeScript.

Подсказки:

  1. Рассмотрите использование декораторов для проверки свойств
  2. Подумайте об имплементации абстрактного класса
  3. Помните о модификаторах доступа к свойствам private/protected

Выше ожиданий:

  • Понимание API рефлексии метаданных TypeScript
  • Знание паттернов фабрик декораторов
  • Продвинутое понимание дескрипторов свойств
  • Реализация пользовательских декораторов валидации
Ответ:

План ответа:

  1. Базовые концепции валидации типобезопасности в TypeScript
  2. Реализация с использованием декораторов классов и валидаторов свойств
  3. Использование рефлексии метаданных для проверки типов во время выполнения
  4. Создание декораторов валидации с поддержкой наследования
  5. Реализация описателей свойств для контроля доступа
  6. Интеграция с абстрактными классами для типобезопасности
  7. Обработка валидации в дочерних классах
  8. Обработка ошибок и гарантии типов

Реализуйте типобезопасную валидацию свойств в TypeScript с помощью комбинации декораторов и рефлексии метаданных. Шаги:

  1. Установка необходимых зависимостей:
import 'reflect-metadata';
  1. Создание фабрики базового декоратора валидации:
function validate<T>(validationFn: (value: T) => boolean) {
    return function(target: any, propertyKey: string) {
        const metadata = {
            validator: validationFn,
            propertyKey
        };
        
        const validators = Reflect.getMetadata('validators', target) || [];
        Reflect.defineMetadata('validators', [...validators, metadata], target);
    };
}
  1. Определение абстрактного базового класса с поддержкой валидации:
abstract class ValidatedBase {
    private validateProperty<T>(propertyKey: string, value: T): boolean {
        const validators = Reflect.getMetadata('validators', this) || [];
        const validator = validators.find(v => v.propertyKey === propertyKey);
        
        return validator ? validator.validator(value) : true;
    }

    protected setValidatedProperty<T>(propertyKey: string, value: T): void {
        if (!this.validateProperty(propertyKey, value)) {
            throw new Error(`Ошибка валидации для свойства ${propertyKey}`);
        }
    }
}
  1. Реализация валидации свойств с использованием декораторов:

Создайте пользовательские валидаторы свойств:

  • Используйте property descriptors, чтобы перехватывать операции get/set
  • Реализуйте логику валидации в методе set
  • Обеспечьте типобезопасность с помощью общих ограничений
  • Поддерживайте валидацию цепочки наследования

Пример реализации:

class User extends ValidatedBase {
    @validate<string>(value => value.length >= 3)
    name: string;

    @validate<number>(value => value >= 0 && value <= 120)
    age: number;

    constructor(name: string, age: number) {
        super();
        this.setValidatedProperty('name', name);
        this.setValidatedProperty('age', age);
    }
}

class Employee extends User {
    @validate<string>(value => value.match(/^[A-Z0-9]+$/))
    employeeId: string;

    constructor(name: string, age: number, employeeId: string) {
        super(name, age);
        this.setValidatedProperty('employeeId', employeeId);
    }
}
  1. Добавление проверки типов во время выполнения с помощью рефлексии метаданных:
function validateType<T>(target: any, propertyKey: string) {
    const type = Reflect.getMetadata('design:type', target, propertyKey);
    
    return function(value: T): boolean {
        return value instanceof type;
    };
}
  1. Реализация контроля доступа к свойствам:

Используйте модификаторы доступа TypeScript (private/protected), чтобы обеспечить надлежащую инкапсуляцию:

  • Сделайте методы валидации protected
  • Используйте приватное хранилище для валидированных значений
  • Предоставьте публичные геттеры/сеттеры с валидацией
  1. Обработка валидации в цепочке наследования:
  • Соберите валидаторы из всей цепочки прототипов
  • Объедините правила валидации из родительских классов
  • Обеспечьте типобезопасность в производных классах
  1. Добавление обработки ошибок и гарантий типов:
  • Создайте собственные типы ошибок валидации
  • Реализуйте стратегии восстановления после ошибок
  • Сохраняйте информацию о типах через цепочку валидации

Пример использования:

function validateDecorator<T>(options: ValidationOptions<T>) {
    return function(target: any, propertyKey: string) {
        const baseValidators = Reflect.getMetadata('validators', target) || [];
        
        const typeValidator = validateType(target, propertyKey);
        const customValidator = options.validator || (() => true);
        
        const combinedValidator = (value: T) => 
            typeValidator(value) && customValidator(value);
            
        Reflect.defineMetadata('validators', [
            ...baseValidators,
            { propertyKey, validator: combinedValidator }
        ], target);
    };
}

Эта реализация обеспечивает:

  • Типобезопасную валидацию свойств
  • Проверку типов во время выполнения
  • Поддержку наследования
  • Пользовательские правила валидации
  • Контроль доступа через модификаторы TypeScript

Решение использует рефлексию метаданных, чтобы хранить и извлекать правила валидации, обеспечивая типобезопасность как на этапе компиляции, так и во время выполнения. Шаблон декораторов позволяет использовать логику валидации, сохраняя при этом надлежащую инкапсуляцию с помощью модификаторов доступа.

0
TypeScript Средний Опубликовано
© Skilio, 2025
Условия использования
Политика конфиденциальности
Мы используем файлы cookie, для персонализации сервисов и повышения удобства пользования сайтом. Если вы не согласны на их использование, поменяйте настройки браузера.