code: func GoTypeName(t design.DataType, required []string, tabs int, private bool) string {
  	switch actual := t.(type) {
  	case design.Primitive:
  		return GoNativeType(t)
  	case *design.Array:
  		return "[]" + GoTypeRef(actual.ElemType.Type, actual.ElemType.AllRequired(), tabs+1, private)
  	case design.Object:
  		att := &design.AttributeDefinition{Type: actual}
  		if len(required) > 0 {
  			requiredVal := &dslengine.ValidationDefinition{Required: required}
  			att.Validation.Merge(requiredVal)
  		}
  		return GoTypeDef(att, tabs, false, private)
  	case *design.Hash:
  		return fmt.Sprintf(
  			"map[%s]%s",
  			GoTypeRef(actual.KeyType.Type, actual.KeyType.AllRequired(), tabs+1, private),
  			GoTypeRef(actual.ElemType.Type, actual.ElemType.AllRequired(), tabs+1, private),
  		)
  	case *design.UserTypeDefinition:
  		return Goify(actual.TypeName, !private)
  	case *design.MediaTypeDefinition:
  		if actual.IsError() {
  			return "error"
  		}
  		return Goify(actual.TypeName, !private)
  	default:
  		panic(fmt.Sprintf("goa bug: unknown type %#v", actual))
  	}
  }
docs: // GoTypeName returns the Go type name for a data type.
  // tabs is used to properly tabulate the object struct fields and only applies to this case.
  // This function assumes the type is in the same package as the code accessing it.
  // required only applies when referring to a user type that is an object defined inline. In this
  // case the type (Object) does not carry the required field information defined in the parent
  // (anonymous) attribute.