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.
Prose stays prose.
--- Returns true when… shows up in hover; the @param
lines do not.Supported tags
Type expressions
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:
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:
Or annotate nothing
Parameters with no annotation are typed from the methods called on them.1
Collect the methods
Every
: call on that parameter inside the function body.2
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.3
Prefer the common ancestor
When several match, the one the others inherit from wins — as long as it
accounts for most of them.
4
Otherwise, stay quiet
An unrecognisable method set leaves the parameter as
any rather than
guessing.---@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