function validateTypedProperty(propertyValue, propertyType, opt) {
        if (propertyValue && /^\${[^}]+}$/.test(propertyValue)) {
            // Allow ${ENV_VAR} value
            return true
        }
        let error;
        if (propertyType === 'json') {
            try {
                JSON.parse(propertyValue);
            } catch(err) {
                error = RED._("validator.errors.invalid-json", {
                    error: err.message
                });
            }
        } else if (propertyType === 'msg' || propertyType === 'flow' || propertyType === 'global' ) {
            // To avoid double label
            const valid = RED.utils.validatePropertyExpression(propertyValue, opt ? {} : null);
            if (valid !== true) {
                error = opt ? valid : RED._("validator.errors.invalid-prop");
            }
        } else if (propertyType === 'num') {
            if (!/^NaN$|^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$|^[+-]?(0b|0B)[01]+$|^[+-]?(0o|0O)[0-7]+$|^[+-]?(0x|0X)[0-9a-fA-F]+$/.test(propertyValue)) {
                error = RED._("validator.errors.invalid-num");
            }
        } else if (propertyType === 'jsonata') {
            try { 
                jsonata(propertyValue)
            } catch(err) {
                error = RED._("validator.errors.invalid-expr", {
                    error: err.message
                });
            }
        }
        if (error) {
            if (opt && opt.label) {
                return opt.label + ': ' + error;
            }
            return error;
        }
        return true;
    }
Checks a typed property is valid according to the type.
Returns true if valid.
Return String error message if invalid
@param {*} propertyType 
@param {*} propertyValue 
@returns true if valid, String if invalid