Reputation: 10509
When using TypeScript to check JavaScript code, how do you cast to a different type than is inferred? Typescript has the <Type>
and as Type
syntax but these aren't valid in JavaScript.
/**
* @param {{id: string, value: number}} details - object with required properties
*/
function stringifyObject(details) {
return `${details.id}: ${details.value}`;
}
const testValue = {id: 'no-value'};
stringifyObject(testValue); // want to cast testValue to ignore missing property
stringifyObject(/** @type {any} */ testValue); // this doesn't work
Upvotes: 35
Views: 11926
Reputation: 1349
The Answer is already given in another post.
But to add more on the usage:
if you want to let the type cast be available in all the code lines below, use this
node_curr = /** @type {Element} */ (node_curr); // working for this line & all the lines below
node_curr.outerHTML;
vv
// #>>> an example usage
const elt_main = $('<div></div>')[0];
const treeWalker = document.createTreeWalker(elt_main, NodeFilter.SHOW_ALL);
const arr_html_EltMain = [];
let html_curr;
let node_curr;
while ((node_curr = treeWalker.nextNode())) {
const nt = node_curr.nodeType;
if (nt === Node.TEXT_NODE) {
html_curr = /** @type {Text} */ (node_curr).textContent;
arr_html_EltMain.push(html_curr);
} else if (nt === Node.ELEMENT_NODE) {
html_curr = /** @type {Element} */ (node_curr).outerHTML; // << the Type cast / autocompletion will only apply to this particular line,
// // any reference below this line will fall back to original Type
// // also, if you hover to the variable, it appears to be still the old Type (though autocompletion works)
arr_html_EltMain.push(html_curr);
}
}
// #>>>
// @note: about the paranthesis -- only enclose it for the variable, not need to include the @type
(/** @type {Element} */ (node_curr)).outerHTML; // works, but unnecessary
/** @type {Element} */ (node_curr).outerHTML; // use this
// #>>>
// compare & the correct way to use
/** @type {Element} */ node_curr = node_curr; // not_working
node_curr; // not_working
(/** @type {Element} */ node_curr) = node_curr; // not_working
node_curr; // not_working
/** @type {Element} */ (node_curr) = node_curr; // working only for this line
node_curr; // not_working
node_curr = /** @type {Element} */ node_curr; // not_working
node_curr; // not_working
node_curr = (/** @type {Element} */ node_curr); // not_working
node_curr; // not_working
node_curr = /** @type {Element} */ (node_curr); // working for this line & all the lines below
node_curr; // working
node_curr; // working
node_curr; // working
// #>>>
// @note: if you want to let the type cast be available in all the code lines below, use this
node_curr = /** @type {Element} */ (node_curr); // working for this line & all the lines below
node_curr.outerHTML;
Upvotes: 5
Reputation: 10509
The /** @type */
comment is close. According to the TypeScript Handbook it just needs parenthesis around the value being cast.
TypeScript borrows cast syntax from Google Closure. This lets you cast types to other types by adding a
@type
tag before any parenthesized expression.
So in the original example you would write the following:
// Wrap value being cast in parenthesis
stringifyObject(/** @type {any} */ (testValue));
Upvotes: 68