docs: def _get_typed_value(self, key, target_type, type_convert, optional=False):
          """
          Returns value converted to a particular target_type and raises a ConfigTypeError if we can't cast the value to
          the expected type. Also propagates the error to the caller function 'get_<type>'. If optional was set, just
          returns None if the variable is not found.
          :param key: The variable to search for in the possible list of configs
          :param target_type: The type we expect the variable or key to be in.
          :param type_convert: A lambda expression that converts the key to the desired type.
          :param optional: If we should raise a ConfigKeyNotFoundError when the key is not found at all.
          :return: type_convert(value)
          """
          try:
              value = self._get(key)
          except ConfigKeyNotFoundError:
              if not optional:
                  # Propagate the ConfigKeyNotFoundError which was caught
                  raise
              return None
  
          if isinstance(value, basestring):
              try:
                  return type_convert(value)
              except ValueError:
                  raise ConfigTypeCastError(key, value, target_type)
  
          if isinstance(value, target_type):
              return value
          raise ConfigTypeError(key, value, target_type)