Issue
I am attempting to come up with a JavaScript+JSDoc variant of the following TypeScript type asserting function:
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);
I’ve come up with this but I’m getting an error:
/** @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}'!`)
}
The error is in the call site: const button = check(event.currentTarget, HTMLButtonElement);
. HTMLButtonElement
is underlined and the error message says:
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)
Is it possible to develop a JSDoc function like this which when passed an unknown
would solely using TypeScript type interference and escape analysis validate and return the unknown object typed as the provided type?
I am not interested in JSDoc in general, but specifically JSDoc as used in Visual Studio Code with the TypeScript language service working on a JavaScript project using JSDoc for type hints.
Solution
Assertion Functions introduced in TS 3.7 can assert the type of a value in their calling scope.
/**
* @param {*} maybeString
* @returns {asserts maybeString is string}
*/
function assertString(maybeString) {
if (typeof maybeString !== 'string') throw Error('not a string');
}
/**
* @param {unknown} something
*/
function demo(something) {
something.concat; // type error
assertString(something);
something.concat; // valid
}
Answered By – Turadg
Answer Checked By – Willingham (BugsFixing Volunteer)