code: func DefaultTypeInfoFieldDef(schema *Schema, parentType Type, fieldAST *ast.Field) *FieldDefinition {
  	name := ""
  	if fieldAST.Name != nil {
  		name = fieldAST.Name.Value
  	}
  	if name == SchemaMetaFieldDef.Name &&
  		schema.QueryType() == parentType {
  		return SchemaMetaFieldDef
  	}
  	if name == TypeMetaFieldDef.Name &&
  		schema.QueryType() == parentType {
  		return TypeMetaFieldDef
  	}
  	if name == TypeNameMetaFieldDef.Name && parentType != nil {
  		if t, ok := parentType.(*Object); ok && t != nil {
  			return TypeNameMetaFieldDef
  		}
  		if t, ok := parentType.(*Interface); ok && t != nil {
  			return TypeNameMetaFieldDef
  		}
  		if t, ok := parentType.(*Union); ok && t != nil {
  			return TypeNameMetaFieldDef
  		}
  	}
  
  	if parentType, ok := parentType.(*Object); ok && parentType != nil {
  		field, _ := parentType.Fields()[name]
  		return field
  	}
  	if parentType, ok := parentType.(*Interface); ok && parentType != nil {
  		field, _ := parentType.Fields()[name]
  		return field
  	}
  	return nil
  }
docs: // DefaultTypeInfoFieldDef Not exactly the same as the executor's definition of FieldDef, in this
  // statically evaluated environment we do not always have an Object type,
  // and need to handle Interface and Union types.