Недавно придумал очень классный трюк, который позволяет декларировать конвертацию типов для GCC.
Заведём функцию ковертор:
/**
* Вернуть заданный объект с указанием произвольного типа
* (для приведения типа в GCC)
*
* @param {?} val - исходное значение
* @return {?}
*/
function Any(val) {
return val;
}
Теперь допустим у нас есть функция:
/**
* @param {(string|!Array)} idOrParams
*/
function get(idOrParams) {
if (Array.isArray(idOrParams)) {
return idOrParams.map(...); // Тут GCC начнёт варнить, мол тип может быть строкой и данный код не безопасен
}
}
Решение номер 1
Сделаем явную конвертацию данных:
/**
* @param {(string|!Array)} idOrParams
*/
function get(idOrParams) {
if (Array.isArray(idOrParams)) {
return [].concat(idOrParams).map(...);
}
}
Работает, но выглядит как кривой хак (а вот для конвертаций в примитивы можно спокойно юзать Boolean, String и Number).
Решение номер 2
Использование конвертора Any
/**
* @param {(string|!Array)} idOrParams
*/
function get(idOrParams) {
if (Array.isArray(idOrParams)) {
/** @type {!Array} */
var myArray = Any(idOrParams);
return myArray .map(...);
}
}
Функцию Any GCC грохнет при компиляции и никаких оверхедов не будет, данный трюк можно использовать для любой кновертации данных, также можно наплодить на основе Any ряд функций, навроде: isArray и т.д.