Введите для `этого’ аргумента в совместно используемой функции между классами

#typescript

Вопрос:

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

В настоящее время я внедряю библиотеку в TypeScript для своей компании. Чтобы не раскрывать слишком много информации, эта библиотека в основном отображает пользовательский интерфейс на основе файла конфигурации.

Поскольку интерфейс будет отображаться на разных платформах (мобильных, настольных и т. Д.), Каждая платформа является a Class в коде.

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

Я хотел бы знать:

  • Как сообщить TypeScript type о responsibleClass .
  • Есть ли какое-либо лучшее соглашение об именовании для responsibleClass ?
 export function performAction(action: Action, responsibleClass: any) {
  switch (action) {
...
    default:
      responsibleClass.someMethod();
      break;
...
 

Заранее большое вам спасибо!

Джерард

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

1. Используйте экземпляры «ответственного класса» вместо классов со статическими методами.

2. Просто хотел спросить, вы хотите передать ссылку на конструктор класса или экземпляр класса?

Ответ №1:

Если вы хотите передать какой-либо объект с someMethod помощью метода, вы можете использовать это ограничение:

 type Action = {
  tag: 'action'
}

export function performAction<
  Instance extends { someMethod: () => void }
>(action: Action, responsibleClass: Instance) {
  switch (action) {

    default:
      responsibleClass.someMethod();
      break;
  }
}
 

Instance — относится к любому объекту с someMethod помощью . Теперь ts позволит вам использовать экземпляр только с someMethod методом.

Вы даже можете передать класс с помощью статического метода someMethyod :

 type Action = {
  tag: 'action'
}

class Foo {
  static someMethod: () => {}
}

export function performAction<
  Obj extends { someMethod: () => void }
>(action: Action, responsibleClass: Obj) {
  switch (action) {

    default:
      responsibleClass.someMethod();
      break;
  }
}
performAction({ tag: 'action' }, Foo)
 

потому что TS имеет структурный тип system

Ответ №2:

Я рассмотрел 2 возможных решения для этого.

1- Вы можете создать новый тип, который переносит все нужные вам экземпляры

 type TResponsibleClass = MobileClass | DesktopClass | OtherClass
 

И используйте этот тип в аргументе responsibleClass:

 export function performAction(action: Action, responsibleClass: TResponsibleClass) {
   ...
}
 

2- Вы могли бы использовать общие типы TS: https://www.typescriptlang.org/docs/handbook/2/generics.html

В принципе, таким образом, вы можете создать тип типа аргумента функции, поэтому, когда вы используете его, вы также можете передать тип:

 export function performAction<FutureType>(action: Action, responsibleClass: FutureType){
   ...
}
 

А затем вызов функции таким образом

 performAction<DesktopClass>(action, DesktopClass);
 

Это означает, что аргумент responsibleClass будет иметь тип DesktopClass , так что вы можете передать нужный тип.

 performAction<CustomType>(action, anyClass);