Передача прототипа через типовый параметр

Описание

Есть у меня некие классы Elemental и Factory. Что они делают - не важно, поэтому не задержимся на них. Проблема в том что у Factory есть функция getCase, которая в качестве аргумента должен принимать прототип какого-то класса, который наследуется от Elemental. Если я грубо беру и как тип параметра задаю typeof Elemental...

class Factory {
    /**
     * 
     * @param {typeof Elemental} value 
     * @returns 
     */
    getCase(value) {
        ...
    }
    ...
}

...то все хорошо, но если я пытаюсь задать гибкости с помощью типового параметра, который наследуется от Elemental...

/** 
 * @template {Elemental} Type
 */
class Factory {
    /**
     * 
     * @param {typeof Type} value 
     * @returns 
     */
    getCase(value) {
        ...
    }
    ...
}

...то выскакивает ошибка:

"Type" относится только к типу, но используется здесь как значение.

Вопрос

Ошибка вроде логичная, но у меня вообще идей нет, а класс нуждается в типовом параметре. Какие идеи, решения могут быть для данной проблемы?


Дополнение

Я не знаю для чего, но если вдруг будут нужны исходники - вот.


Ответы (1 шт):

Автор решения: SwaD

В jsDoc typeof предназначен для создания типа на основе возвращаемых данных или данных переменной.

/**
 * @type {{a: number, b: string}}
 */
const bigObj = {
  a: 4,
  b: '45'
}

/**
 * @param {string} name
 * @return {string}
 */
function func(name) {
  return `Привет ${name}`;
}

/**
 * @type {typeof bigObj}
 */
let c;

/**
 * @type {typeof func}
 */
let d;

Однако взять тип данных из типа не получится. На что и указывает ошибка.

На примере ниже, есть 4 класса - Easy, Medium, VeryHigh, High. Medium наследуется от Easy. Hard и VertHard не наследуются ни от кого. На основе классов Medium и VeryHigh создадим @typedef тип данных с названием SomeType и укажем в методе showHard класса Hard тип данных SomeType для параметра val

class Easy {
  constructor() {
    this.prop = 'dataProp';
  }
  /** @return {number} */
  showEasy() {
    return  1;
  }
}

class Medium extends Easy {
  showMedium() {
    return '2';
  }
}

class VeryHigh {
  showVery() {
    return [];
  }
}

/**
 * @typedef {Medium | VeryHigh} SomeType
 */

class Hard {
  /** @param {SomeType} val */
  showHard(val) {
    return {a: '1', b: 2}
  }
}

введите сюда описание изображения

→ Ссылка