function evaluateNodeProperty(value, type, node, msg, callback) {
    var result = value;
    if (type === 'str') {
        result = ""+value;
    } else if (type === 'num') {
        result = Number(value);
    } else if (type === 'json') {
        result = JSON.parse(value);
    } else if (type === 're') {
        result = new RegExp(value);
    } else if (type === 'date') {
        if (!value) {
            result = Date.now();
        } else if (value === 'object') {
            result = new Date()
        } else if (value === 'iso') {
            result = (new Date()).toISOString()
        } else {
            result = moment().format(value)
        }
    } else if (type === 'bin') {
        var data = JSON.parse(value);
        if (Array.isArray(data) || (typeof(data) === "string")) {
            result = Buffer.from(data);
        }
        else {
            throw createError("INVALID_BUFFER_DATA", "Not string or array");
        }
    } else if (type === 'msg' && msg) {
        try {
            result = getMessageProperty(msg,value);
        } catch(err) {
            if (callback) {
                callback(err);
            } else {
                throw err;
            }
            return;
        }
    } else if ((type === 'flow' || type === 'global') && node) {
        var contextKey = parseContextStore(value);
        if (/\[msg/.test(contextKey.key)) {
            // The key has a nest msg. reference to evaluate first
            contextKey.key = normalisePropertyExpression(contextKey.key, msg, true)
        }
        result = node.context()[type].get(contextKey.key,contextKey.store,callback);
        if (callback) {
            return;
        }
    } else if (type === 'bool') {
        result = /^true$/i.test(value);
    } else if (type === 'jsonata') {
        var expr = prepareJSONataExpression(value, node);
        result = evaluateJSONataExpression(expr, msg, callback);
        if (callback) {
            return
        }
    } else if (type === 'env') {
        result = evaluateEnvProperty(value, node);
    }
    if (callback) {
        callback(null,result);
    } else {
        return result;
    }
}
Evaluates a property value according to its type.

@param  {String}   value    - the raw value
@param  {String}   type     - the type of the value
@param  {Node}     node     - the node evaluating the property
@param  {Object}   msg      - the message object to evaluate against
@param  {Function} callback - (optional) called when the property is evaluated
@return {any} The evaluted property, if no `callback` is provided
@memberof @node-red/util_util