===========================================
Opaque
===========================================

type t
type \"type"

---

(source_file
 (type_declaration (type_identifier))
 (type_declaration (type_identifier)))

===========================================
Export
===========================================

export type t

---

(source_file
 (type_declaration (type_identifier)))


===========================================
Alias
===========================================

type t = Foo.Bar.qux

---

(source_file
  (type_declaration
    (type_identifier)
    (type_identifier_path
      (module_identifier) (module_identifier) (type_identifier))))

===========================================
Private
===========================================

type t = private string

---

(source_file (type_declaration (type_identifier) (type_identifier)))

===========================================
Tuple type
===========================================

type t = (int, string, float)

---

(source_file
  (type_declaration
    (type_identifier)
    (tuple_type (type_identifier) (type_identifier) (type_identifier))))

===========================================
Record type
===========================================

type t = {
  a: int,
  b: myType,

  @as("type")
  type_: string,

  mutable x: int,

  opt?: string
}

---

(source_file
  (type_declaration
    (type_identifier)
    (record_type
      (record_type_field
        (property_identifier) (type_annotation (type_identifier)))
      (record_type_field
        (property_identifier) (type_annotation (type_identifier)))
      (record_type_field
        (decorator
          (decorator_identifier)
          (decorator_arguments (string (string_fragment))))
        (property_identifier)
        (type_annotation (type_identifier)))
      (record_type_field
        (property_identifier) (type_annotation (type_identifier)))
      (record_type_field
        (property_identifier) (type_annotation (type_identifier))))))

===========================================
Extensible Variant
===========================================

type t = ..

type t += Other

type t +=
  | Point
  | Line

---

(source_file
  (type_declaration
    (type_identifier))
  (type_declaration
    (type_identifier)
    (variant_type
      (variant_declaration
        (variant_identifier))))
  (type_declaration
    (type_identifier)
    (variant_type
      (variant_declaration
        (variant_identifier))
      (variant_declaration
        (variant_identifier)))))

===========================================
Variant
===========================================

type t =
  | A
  | @live("t.D") D
  | B(anotherType)
  | C({foo: int, bar: string})
  | D(module(Foo))
  | D(module(Bar.t))

---

(source_file
  (type_declaration
    (type_identifier)
    (variant_type
      (variant_declaration (variant_identifier))
      (variant_declaration
        (decorator (decorator_identifier) (decorator_arguments (string (string_fragment))))
        (variant_identifier))
      (variant_declaration
        (variant_identifier) (variant_parameters (type_identifier)))
      (variant_declaration
        (variant_identifier)
        (variant_parameters
          (record_type
            (record_type_field
              (property_identifier) (type_annotation (type_identifier)))
            (record_type_field
              (property_identifier) (type_annotation (type_identifier))))))
      (variant_declaration
        (variant_identifier)
        (variant_parameters
          (module_pack_type (module_identifier))))
      (variant_declaration
        (variant_identifier)
        (variant_parameters
          (module_pack_type
            (type_identifier_path (module_identifier) (type_identifier))))))))

===========================================
Annotated variant
===========================================

type rec t = Any('a): t

---

(source_file
  (type_declaration
    (type_identifier)
    (variant_type
      (variant_declaration
        (variant_identifier)
        (variant_parameters (type_identifier))
        (type_annotation (type_identifier))))))

===========================================
Polyvar
===========================================

type t = [>
  | #AAA
  | #bbb(anotherType)
  | #"cc-cc"
  | #\"cc-cc"
  | #42
  | @as("42") #FortyTwo
  | anotherType
  ]


type foo<'a> = [> #Blue | #DeepBlue | #LightBlue ] as 'a

---

(source_file
  (type_declaration
    (type_identifier)
    (polyvar_type
      (polyvar_declaration (polyvar_identifier))
      (polyvar_declaration
        (polyvar_identifier) (polyvar_parameters (type_identifier)))
      (polyvar_declaration (polyvar_identifier (polyvar_string (string_fragment))))
      (polyvar_declaration (polyvar_identifier (polyvar_string (string_fragment))))
      (polyvar_declaration (polyvar_identifier))
      (polyvar_declaration (decorator (decorator_identifier) (decorator_arguments (string (string_fragment)))) (polyvar_identifier))
      (polyvar_declaration (type_identifier))))

  (type_declaration
    (type_identifier)
    (type_parameters (type_identifier))
    (polyvar_type
      (polyvar_declaration (polyvar_identifier))
      (polyvar_declaration (polyvar_identifier))
      (polyvar_declaration (polyvar_identifier))
      (type_identifier))))

===========================================
Function
===========================================

type fooA = t => float
type fooB = (t) => float
type fooC = (t1, t2) => float
type fooD = (~arg1: t1, ~arg2: t2=?, unit) => float

---

(source_file
  (type_declaration
    (type_identifier)
    (function_type
      (function_type_parameters (type_identifier))
      (type_identifier)))
  (type_declaration
    (type_identifier)
    (function_type
      (function_type_parameters (parameter (type_identifier)))
      (type_identifier)))
  (type_declaration
    (type_identifier)
    (function_type
      (function_type_parameters
        (parameter (type_identifier))
        (parameter (type_identifier)))
      (type_identifier)))
  (type_declaration
    (type_identifier)
    (function_type
      (function_type_parameters
        (parameter (labeled_parameter
          (value_identifier)
          (type_annotation (type_identifier))))
        (parameter (labeled_parameter
          (value_identifier)
          (type_annotation (type_identifier))))
        (parameter (unit_type)))
      (type_identifier))))

===========================================
Object
===========================================

type t = {..}
type t = {.}
type t = {.. "my-field": int }
type t = {
  "my-field": int,
  "my-field-two": string,
  ...rest
}

---

(source_file
  (type_declaration
    (type_identifier)
    (object_type))
  (type_declaration
    (type_identifier)
    (object_type))
  (type_declaration
    (type_identifier)
    (object_type
      (field (property_identifier (string_fragment)) (type_identifier))))
  (type_declaration
    (type_identifier)
    (object_type
      (field (property_identifier (string_fragment)) (type_identifier))
      (field (property_identifier (string_fragment)) (type_identifier))
      (field (type_identifier)))))

===========================================
Generic
===========================================

type t<'a, 'b> = (array<'a>, array<'b>)

---

(source_file
  (type_declaration
    (type_identifier)
    (type_parameters (type_identifier) (type_identifier))
    (tuple_type
      (generic_type (type_identifier) (type_arguments (type_identifier)))
      (generic_type (type_identifier) (type_arguments (type_identifier))))))

===========================================
Recursive
===========================================

type rec t = t

---

(source_file
  (type_declaration (type_identifier) (type_identifier)))

===========================================
Decorated
===========================================

@deriving(abstract)
type transitionCreateArgs = {
  easing: string,
}

type person = {@meth "say": (string, string) => unit}

---

(source_file
  (decorated
    (decorator (decorator_identifier) (decorator_arguments (value_identifier)))
    (type_declaration
      (type_identifier)
      (record_type
        (record_type_field
          (property_identifier)
          (type_annotation (type_identifier))))))

  (type_declaration
    (type_identifier)
    (object_type
      (field
        (decorator (decorator_identifier))
        (property_identifier (string_fragment))
        (function_type
          (function_type_parameters
            (parameter (type_identifier))
            (parameter (type_identifier)))
          (unit_type))))))

===========================================
Mutually Recursive
===========================================

type rec student = {
  teacher: teacher
}
and teacher = {
  students: array<student>
}

---

(source_file
  (type_declaration
    (type_identifier)
    (record_type
      (record_type_field
        (property_identifier)
        (type_annotation
          (type_identifier))))
    (type_declaration
      (type_identifier)
      (record_type
        (record_type_field
          (property_identifier)
          (type_annotation
            (generic_type
              (type_identifier)
              (type_arguments
                (type_identifier)))))))))


===========================================
Labled function with uncurried
===========================================

type test = (. ~attr: string) => unit

---

(source_file
  (type_declaration
    (type_identifier)
    (function_type
      (function_type_parameters
        (parameter
          (uncurry)
          (labeled_parameter
            (value_identifier)
            (type_annotation
              (type_identifier)))))
      (unit_type))))

===========================================
Variance annotations
===========================================

type t<+'a>
type t<-'a>

---

(source_file
  (type_declaration
    (type_identifier)
    (type_parameters (type_identifier)))
  (type_declaration
    (type_identifier)
    (type_parameters (type_identifier))))
