#javascript #reactjs #typescript #oop #singleton
#javascript #reactjs #typescript #ооп #одноэлементный
Вопрос:
У меня есть два класса :
useService.ts
import { useMemo } from 'react';
/**
* Hook will take the singletone service instance later keeping it memoized
* @param service
*/
export function useService<T> ( service: { new (): T; getInstance (): T } ): T {
return useMemo<T>(() => service.getInstance(), []);
}
/**
* Hook will take instance of the given class memoized
* @param Class
* @param args
*/
export function useClass<S, A extends []> ( Class: { new ( ...args: A ): S }, ...args: A ): S {
return useMemo<S>(() => new Class(...args), []);
}
CartService.ts
var CART_ITEMS_KEY = 'SOME_KEY';
export class CartService {
private static __SELF__: CartService;
private __items: CartItem[] = [];
private auth: AuthService;
private api: APIService;
private endpoint: AxiosInstance;
constructor (cartItemsKey) {
CART_ITEMS_KEY = cartItemsKey;
this.auth = AuthService.getInstance();
this.api = APIService.getInstance();
this.endpoint = this.api.createEndpoint('cart');
this.init();
}
/**
* Get singletone service instance
*/
public static getInstance (): CartService {
if ( !CartService.__SELF__ ) {
CartService.__SELF__ = new CartService();
}
return CartService.__SELF__;
}
}
Я хочу инициализировать объект CartService и передать его в UserService следующим образом.
useService(CartService(«SOME_NEW_KEY»))
Я пробовал много подходов, но получал ошибки.
Комментарии:
1.
userService
здесь не определено. Вы имеете в видуuseService
?2. Вы хотите инициализировать без ключевого слова new? попробуйте, если нет ограничений с новым ключевым словом UserService(new CartService(«SOME_NEW_KEY»)) или
3. @RajaJaganathan Да, я хочу внедрить его без нового ключевого слова.
4. @gqstav Да, это опечатка. Его useService
Ответ №1:
userService(CartService("SOME_NEW_KEY"))
Это недопустимый синтаксис в typescript, вы можете получить ошибку типа Value of type 'typeof CartService' is not callable.
При создании экземпляра CartService нам нужно передать cartItemsKey конструктору.
/**
* Get singleton service instance
*/
public static getInstance(cartItemsKey): CartService {
if (!CartService.__SELF__) {
CartService.__SELF__ = new CartService(cartItemsKey);
}
return CartService.__SELF__;
}
Вызовите, как показано ниже
userService(CartService.getInstance("SOME_NEW_KEY"))
Комментарии:
1. Аргумент типа ‘CartService’ не может быть присвоен параметру типа ‘{new (): неизвестно; getInstance(): неизвестно; }’. Свойство ‘getInstance’ отсутствует в типе ‘CartService’, но требуется в типе ‘{new (): неизвестно; getInstance(): неизвестно; }’. Получение этой ошибки
2. Воспроизводимая ошибка была бы полезна здесь, stackblitz.com/edit/typescript-playground-ea1fbj?file=index.ts . Обратите внимание, что я не видел здесь никаких проблем
3. Вам не хватает еще одного класса. useService я должен передать объект в нем.
4. stackblitz.com/edit/typescript-playground-zceawm?file=index.ts
5. попробуйте так stackblitz.com/edit/typescript-playground-yj8a2t?file=index.ts
Ответ №2:
Попробуйте это:
useService.ts
import { useMemo } from 'react';
/**
* Hook will take the singleton service instance later keeping it memoized
* @param service
*/
export function useService<T>(
service: {
new (): T;
getInstance(...args: String[]): T;
},
args: String[]
): T {
return useMemo<T>(() => service.getInstance(...args), []);
}
/**
* Hook will take instance of the given class memoized
* @param Class
* @param args
*/
export function useClass<S, A extends []>(
Class: { new (...args: A): S },
...args: A
): S {
return useMemo<S>(() => new Class(...args), []);
}
CartService.ts
export class CartService {
private static __SELF__: CartService;
private cartItemsKey: String;
private cartId: String;
constructor(cartItemsKey: String = 'default', cartId: String = 'default') {
this.cartItemsKey = cartItemsKey;
this.cartId = cartId;
}
log() {
console.log('cartId: ' this.cartId);
console.log('cartItemsKey: ' this.cartItemsKey);
}
/**
* Get singletone service instance
*/
public static getInstance(...args: String[]): CartService {
if (!CartService.__SELF__) {
CartService.__SELF__ = new CartService(...args);
}
return CartService.__SELF__;
}
}
А затем используйте его следующим образом:
let cartService = useService(CartService, [
'SOME_KEY_FROM_TEST',
'SOME_ID_FROM_TEST'
]);
cartService.log()