> ## Documentation Index
> Fetch the complete documentation index at: https://glua.bluejutzu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Typing your own code

> Lua has no type syntax. Two ways to give your own functions types anyway.

The API dataset covers everything Garry's Mod ships. Your own functions are the
gap: `function MyAddon.CanPlace(ply)` gives the editor nothing to work with.

There are two ways to close it, and you can mix them freely.

## Annotations

The same `---@param` dialect the Lua Language Server uses, so annotations you
already have work here, and anything you write keeps working there.

```lua theme={"system"}
--- Returns true when the player may place a turret.
---@param ply Player
---@param count? number how many they already have
---@return boolean
function MyAddon.CanPlace(ply, count)
  return ply:IsAdmin()
end
```

<Note>
  Prose stays prose. `--- Returns true when…` shows up in hover; the `@param`
  lines do not.
</Note>

### Supported tags

| Tag           | Example                                    |
| ------------- | ------------------------------------------ |
| `@param`      | `---@param ply Player`                     |
| `@return`     | `---@return boolean ok`                    |
| `@type`       | `---@type Player`                          |
| `@class`      | `---@class MyThing : Base`                 |
| `@field`      | `---@field name string`                    |
| `@deprecated` | `---@deprecated use MyAddon.Other instead` |

### Type expressions

| Form                    | Meaning                                 |
| ----------------------- | --------------------------------------- |
| `Player`                | A class, struct or primitive            |
| `Entity\|nil`           | A union                                 |
| `Player?`               | Shorthand for `Player\|nil`             |
| `Entity[]`              | An array                                |
| `table<string, Player>` | A map; the value type is what gets used |
| `fun(a: number)`        | A function                              |

<Tip>
  A `@param` with no type is treated as documentation, not a type. Writing
  `--- @param ply the player who did it` will not create a type called `the`.
</Tip>

## Casting with `---@type`

Inference can only work with what a value looks like at the point it's
created. Sometimes that's nothing at all:

```lua theme={"system"}
---@type Player
local target = nil
```

Without the annotation, `target` would infer as `nil` for its whole scope —
there's nothing in `= nil` to pull a class from. `---@type` overrides that:
whatever type you write becomes the type of `target` from here on, regardless
of what the initialiser looked like.

The same escape hatch narrows a value that came out too broad, like something
pulled out of an untyped table:

```lua theme={"system"}
local raw = someTable[key]

---@type Weapon
local weapon = raw
```

<Warning>
  `---@type` only takes effect on a `local` declaration, and only for the
  first name when a statement declares several (`local a, b = ...`). It does
  nothing on a plain assignment (`x = value`) or a table field
  (`self.target = value`) — give those a type where they're first declared
  with `local` instead.
</Warning>

## Or annotate nothing

Parameters with no annotation are typed from the methods called on them.

```lua theme={"system"}
local function canPlace(ply)
  return ply:IsAdmin()       -- IsAdmin exists only on Player -> Player
end

local function move(ent)
  ent:SetPos(ent:GetPos())   -- shared by many classes -> Entity
end
```

How the guess is made:

<Steps>
  <Step title="Collect the methods">
    Every `:` call on that parameter inside the function body.
  </Step>

  <Step title="Find the classes that have all of them">
    Searching the types people actually pass around first, so the ninety-odd
    panel classes cannot outvote `Entity` on a method they happen to share.
  </Step>

  <Step title="Prefer the common ancestor">
    When several match, the one the others inherit from wins — as long as it
    accounts for most of them.
  </Step>

  <Step title="Otherwise, stay quiet">
    An unrecognisable method set leaves the parameter as `any` rather than
    guessing.
  </Step>
</Steps>

An explicit `---@param` always beats inference.

## Which to use

Inference is free and covers most helper functions. Reach for annotations when:

* the parameter is only passed through, never called on
* the function is part of an API other people use
* inference picked a base class and you want the specific one
* you want the parameter documented in hover anyway


## Related topics

- [IntelliSense and Type Tracking for GLua](/features/intellisense.md)
- [Get Started with GLua](/quickstart.md)
- [Hook Intelligence and Callback Typing](/features/hooks.md)
- [GLua Performance](/reference/performance.md)
