function field_type (type, field_name) {
  // TODO: union handling
  var output_type;
  if (type instanceof IRCompoundType) {
    output_type = type.get_key_type(field_name);
    if (output_type instanceof IRVoidType) {
      throw new CoralTypeError(field_name + " is not an available field, available fields are: " + type.get_keys());
    }
  } else if (type instanceof IRExactValueType) {
    var value = type.get_value();
    if (typeof value !== 'object' || value === null) {
      return new IRVoidType();
    }

    output_type = new IRExactValueType(value[field_name]);
  } else if (type instanceof IRTupleType) {
    if (typeof parseInt(field_name, 10) !== 'number') {
      output_type = new IRVoidType();
    } else {
      output_type = type.get_entry_type(parseInt(field_name, 10));
    }
  } else if (type instanceof IRDOMPlacementType) {
    output_type = new IRVoidType();
  }

  // TODO: this should not be necessary
  if (!output_type) {
    return new IRAnyType();
  }

  return output_type;
}
/**
 * @param {IRType} type The type to determine the field value type of
 * @param {string} field_name The field name to determine the type of on the given type
 * @returns {IRType} The IRType determined for the given field name on the given type
 */
@param {IRType} type The type to determine the field value type of
@param {string} field_name The field name to determine the type of on the given type
@returns {IRType} The IRType determined for the given field name on the given type
@param { IRType } type The type to determine the field value type of @param { string } field_name The field name to determine the type of on the given type @returns { IRType } The IRType determined for the given field name on the given type
function field_type (type, field_name) {
  var output_type;
  if (type instanceof IRCompoundType) {
    output_type = type.get_key_type(field_name);
    if (output_type instanceof IRVoidType) {
      throw new CoralTypeError(field_name + " is not an available field, available fields are: " + type.get_keys());
    }
  } else if (type instanceof IRExactValueType) {
    var value = type.get_value();
    if (typeof value !== 'object' || value === null) {
      return new IRVoidType();
    }
    output_type = new IRExactValueType(value[field_name]);
  } else if (type instanceof IRTupleType) {
    if (typeof parseInt(field_name, 10) !== 'number') {
      output_type = new IRVoidType();
    } else {
      output_type = type.get_entry_type(parseInt(field_name, 10));
    }
  } else if (type instanceof IRDOMPlacementType) {
    output_type = new IRVoidType();
  }
  if (!output_type) {
    return new IRAnyType();
  }
  return output_type;
}
function field_type ( type , field_name ) { var output_type ; if ( type instanceof IRCompoundType ) { output_type = type . get_key_type ( field_name ) ; if ( output_type instanceof IRVoidType ) { throw new CoralTypeError ( field_name + " is not an available field, available fields are: " + type . get_keys ( ) ) ; } } else if ( type instanceof IRExactValueType ) { var value = type . get_value ( ) ; if ( typeof value !== 'object' || value === null ) { return new IRVoidType ( ) ; } output_type = new IRExactValueType ( value [ field_name ] ) ; } else if ( type instanceof IRTupleType ) { if ( typeof parseInt ( field_name , 10 ) !== 'number' ) { output_type = new IRVoidType ( ) ; } else { output_type = type . get_entry_type ( parseInt ( field_name , 10 ) ) ; } } else if ( type instanceof IRDOMPlacementType ) { output_type = new IRVoidType ( ) ; } if ( ! output_type ) { return new IRAnyType ( ) ; } return output_type ; }
@param {IRType} type The type to determine the field value type of
 @param {string} field_name The field name to determine the type of on the given type
 @returns {IRType} The IRType determined for the given field name on the given type
@param { IRType } type The type to determine the field value type of @param { string } field_name The field name to determine the type of on the given type @returns { IRType } The IRType determined for the given field name on the given type
// TODO: union handling // TODO: this should not be necessary