# Interfaces

## Interface Declaration Syntax

```fsharp
interface <InterfaceName>[Generics] {
    [export] <methodName>(Arguments): <MethodReturnType> // Syntax of methods
    <EmbeddedInterface> // Syntax of embedded interfaces
    <EmbeddedStructs> // Syntax of embedded structs
    <| Type1 | Type2 | etc> // Syntax of type sets
    // NOTE: Type sets MUST start with `|` 
}
```

For syntax of `Generics` and `Arguments` - [#common-placeholders-throughout-documentation](../read-before-proceeding#common-placeholders-throughout-documentation "mention")

## Working Example

{% hint style="info" %}
The `def` syntax creates a method. It is covered in a later section. In this context, it is used to implement the interface.&#x20;
{% endhint %}

{% tabs %}
{% tab title="Gauntlet" %}
```fsharp
package main

import "fmt" as fmt
import "strings" as strings

interface AcceptableAgeType {
  | Int16 | Int32 | 
}

struct Person {
  export FirstName: String
  export LastName: String 
  export Age: Int16
}

interface Greeter {
  Person
  greet(punctuation: String): String  
}

interface LoudGreeter {
   Greeter
   shout(): String
}

def greet(name: Person, punctuation: String): Unit {
  fmt.println("Greetings " + name.FirstName + " " + name.LastName + punctuation)
}

def shout(name: Person): Unit {
  let uppercaseFirstName = strings.toUpper(name.FirstName)
  let uppercaseLastName = strings.toUpper(name.LastName)
  fmt.println("GREETINGS " + uppercaseFirstName + " " + uppercaseLastName + "!!!!!!!")
}

fun addOneToAge[T: AcceptableAgeType](inputAge: T): T {
  return inputAge + 1 
}

fun greetBothWays(name: Person): Unit {
  fmt.println("Normal greeting:")
  name.greet(".")
  fmt.println("Shouting greeting:")
  name.shout()
}

fun main(): Unit {
  let person = Person{FirstName = "John", LastName = "Doe", Age = 35}
  greetBothWays(person)
  fmt.println("Next year, you'll be:")
  fmt.println(addOneToAge(person.Age))

}
```
{% endtab %}

{% tab title="Transpiled" %}
```go
package main

import fmt "fmt"
import strings "strings"

type acceptableAgeType interface {
	int16 | int32
}

type person struct {
	Age       int16
	LastName  string
	FirstName string
}
type greeter interface {
	greet(punctuation string) string

	person
}
type loudGreeter interface {
	shout() string
	greeter
}

func (name person) greet(punctuation string) {
	fmt.Println("Greetings " + name.FirstName + " " + name.LastName + punctuation)
}
func (name person) shout() {
	uppercaseFirstName := strings.ToUpper(name.FirstName)
	uppercaseLastName := strings.ToUpper(name.LastName)
	fmt.Println("GREETINGS " + uppercaseFirstName + " " + uppercaseLastName + "!!!!!!!")
	// Eliminates any 'unused variable' errors
	_, _ = uppercaseFirstName, uppercaseLastName
}

func addOneToAge[T acceptableAgeType](inputAge T) T {

	return inputAge + 1

}

func greetBothWays(name person) {
	fmt.Println("Normal greeting:")
	name.greet(".")
	fmt.Println("Shouting greeting:")
	name.shout()

}

func main() {
	person := person{FirstName: "John", LastName: "Doe", Age: 35}
	greetBothWays(person)
	fmt.Println("Next year, you'll be:")
	fmt.Println(addOneToAge(person.Age))
	// Eliminates any 'unused variable' errors
	_ = person

}

```
{% endtab %}

{% tab title="Output" %}
```
Normal greeting:
Greetings John Doe.
Shouting greeting:
GREETINGS JOHN DOE!!!!!!!
Next year, you'll be:
36
```
{% endtab %}
{% endtabs %}
