Функция утверждения типа в JSDoc

Я пытаюсь придумать вариант JavaScript + JSDoc следующей функции подтверждения типа TypeScript:

function typeCheck<T>(value: unknown, type: new () => T) {
    if (value instanceof type) {
        return value;
    }

    throw new Error('Invalid type');
}

const maybeButton: unknown = document.createElement('button');
const button = typeCheck(maybeButton, HTMLButtonElement);

Я придумал это, но я получаю сообщение об ошибке:

/** @template T */
/** @returns {T} */
export default function check(/** @type {unknown} */ object, /** @type {new () => T} */ type) {
  if (object instanceof type) {
    /** @type {any} */
    const any = object;

    /** @type {T} */
    const t = any;

    return t;
  }

  throw new Error(`Object ${object} does not have the right type '${type}'!`)
}

Ошибка в месте вызова: const button = check(event.currentTarget, HTMLButtonElement);. HTMLButtonElement подчеркнуто, и в сообщении об ошибке говорится:

Argument of type '{ new (): HTMLButtonElement; prototype: HTMLButtonElement; }' is not assignable to parameter of type 'new () => T'.
  Type 'HTMLButtonElement' is not assignable to type 'T'.
    'T' could be instantiated with an arbitrary type which could be unrelated to 'HTMLButtonElement'.ts(2345)

Можно ли разработать подобную функцию JSDoc, которая при передаче unknown будет использовать исключительно интерференцию типа TypeScript и избежать анализа, чтобы проверить и вернуть неизвестный объект, типизированный как предоставленный тип?

Меня не интересует JSDoc в целом, но конкретно JSDoc, используемый в коде Visual Studio с языковой службой TypeScript, работающей над проектом JavaScript с использованием JSDoc для подсказок типов.


person Tomáš Hübelbauer    schedule 17.03.2021    source источник


Ответы (1)


Кто-то из TypeScript Discord помог мне найти ответ:

/**
 * @template T
 * @returns {T}
 * @param {unknown} obj
 * @param {new () => T} type
 */
export default function assertInstance(obj, type) {
  if (obj instanceof type) {
    /** @type {any} */
    const any = obj;

    /** @type {T} */
    const t = any;

    return t;
  }

  throw new Error(`Object ${obj} does not have the right type '${type}'!`)
}
person Tomáš Hübelbauer    schedule 21.03.2021