Показать сообщение отдельно
  #7 (permalink)  
Старый 11.12.2014, 10:46
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Недавно придумал очень классный трюк, который позволяет декларировать конвертацию типов для 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 и т.д.
__________________
kobezzza
code monkey
Ответить с цитированием