Улучшения в поддержании глобального объекта конфигурации всего приложения

#javascript #typescript #single-page-application

#javascript #typescript #одностраничное приложение

Вопрос:

Приложение, над которым я работаю, имеет несколько products . Конфигурация, зависящая от продукта, поможет избежать if-else . Кроме того, я хочу убедиться, что ключи конфигурации поддерживаются в конфигурации для конкретного продукта. Это достигается за счет использования interface , чтобы разработчик не пропустил key при добавлении его в продукт.

То, что я ищу, — это некоторые предложения по следующим пунктам —

  1. Хотя этот объект может увеличиться и стать большим по размеру, я также хочу убедиться, что этот класс будет dynamically импортировать объект на основе current product-name ( product1 | product2 ) и т. Д. (Так что общая производительность может быть улучшена.)
  2. Лучший способ написать ProductConfigService класс, если таковой имеется.
  3. ИЛИ другой подход, который можно сделать эффективно (используя TS)

Пожалуйста, предложите.

 interface PRODUCT_CONFIG {
    API_KEY: string,
    AGE: number,
    TEXT: string

}

const product1: PRODUCT_CONFIG = {
    API_KEY: "SOME_VALUE",
    AGE: 10,
    TEXT: "SOME_VALUE"
}


const product2: PRODUCT_CONFIG = {
    API_KEY: "SOME_VALUE"
    AGE: 12,
    TEXT: "SOME_VALUE"
}


class ProductConfigService {

    private product: PRODUCT_CONFIG;
    

    constructor(private accessKey:string) {
      this.product = product2; // should be dynamic based on the current selected application. This is hard-coded to product2.
    }

    getConfig(): string {
      //@ts-ignore
      return this.product[this.accessKey];
    }

}

// consumer.

let product = new ProductConfigService('AGE');

console.log(product.getConfig());

 

Комментарии:

1. Почему он product2 хранится в this.product , а не product1 в другом объекте? Вы ищете непустое AGE свойство из-за ProductConfigService('AGE') ?

2. мой плохой. По сути, продукт назначается динамически. Объект содержит соответствующую информацию, если это применимо к продукту, если нет, он будет пустым. Но, тем не менее, ключ существует в виде общего кода.

Ответ №1:

Я бы создал абстрактный класс, который будет наследоваться в соответствии с потребностями каждого приложения.


По умолчанию было бы PRODUCT_CONFIG значение по умолчанию, которое также можно было бы расширить.

В следующем коде getConfig() возвращает правильный тип значения в зависимости от настроенного ключа.


предупреждение: раздражает то, что пользователь ProductConfigService должен указать имя key , используемое для конфигурации. Я не знаю, как извлечь его из самого параметра.


игровая площадка


 // ---------- ABSTRACT CLASS DECLARATION

interface PRODUCT_CONFIG {
    API_KEY: string;
    AGE: number;
    TEXT: string;
}

abstract class AProductConfigService<T extends PRODUCT_CONFIG, U extends keyof T> {
    protected product: T;

    protected accessKey: keyof T;
    
    constructor(accessKey: keyof T, product: T) {
      this.accessKey = accessKey
      this.product = product;
    }

    public getConfig(): T[U] {
      return this.product[this.accessKey] as T[U];
    }
}

// ---------- CLASS IMPLEMENTATION

interface EXTENDED_PRODUCT_CONFIG extends PRODUCT_CONFIG {
    // additionnal keys ...
    ANIMAL: string;
}

class ProductConfigService<U extends keyof EXTENDED_PRODUCT_CONFIG> extends AProductConfigService<EXTENDED_PRODUCT_CONFIG, U> {
    constructor(accessKey: U) {
      super(accessKey, product2);
    }

    // ... new methods
}

// ---------- PRODUCTS DEFINITION

const product1: PRODUCT_CONFIG = {
    API_KEY: 'SOME_VALUE',
    AGE: 10,
    TEXT: 'SOME_VALUE',
}

const product2: EXTENDED_PRODUCT_CONFIG = {
    API_KEY: 'SOME_VALUE',
    AGE: 12,
    TEXT: 'SOME_VALUE',
    ANIMAL: 'fox',
}

// -------------- PRODUCT USE

const productA = new ProductConfigService<'AGE'>('AGE');

const valA = productA.getConfig();

console.log(valA);

const productB = new ProductConfigService<'API_KEY'>('API_KEY');

const valB = productB.getConfig();

console.log(valB);

const productC = new ProductConfigService<'ANIMAL'>('ANIMAL');

const valC = productC.getConfig();

console.log(valC);

// ----------------