object-args
a function taking positional arguments where no external contract dictates the shape
Agent checkadvisory by defaultbasecode
The argument
Syntax & Style
- Use arrow functions (unless the codebase uses a different convention)
- If the function has arguments — exported or private — pass an object and destructure:
- Exported functions: declare an interface called
Paramsfor the object argument - Private helpers: use an inline object type (a file with multiple helpers cannot declare multiple
Paramsinterfaces) - Why objects: positional signatures decay under growth — params get appended out of order, middle params can never be removed, and same-typed slots transpose silently (
copyFile(dest, src)compiles). Object args self-document at every call site.
- Exported functions: declare an interface called
- No arguments → no argument object, no
Paramsinterface. - Sole exception — externally imposed signatures: a shape dictated by another contract is written as that contract demands, never re-declared locally. Two directions: callback-shaped (callbacks to
map/reduce/sort, event handlers, framework hooks — the caller dictates) and pass-through forwarders (a wrapper forwarding one params object unchanged to a single callee — the callee dictates; type itParameters<typeof callee>[0], since a hand-copiedParamswould be a shadow contract that drifts). - If callers need to name the argument type (e.g., to pre-build a typed args object), it has become public contract — promote it to a named exported type in
types/in place ofParams. - Export the function as a named export on the line it is defined.
The proof
failsrc/files/copyFile.ts
// Two same-typed slots in a row: `copyFile(dest, src)` compiles just as happily
// as the intended order, and no call site says which is which.
export const copyFile = (sourcePath: string, destPath: string, overwrite = false): string =>
`${sourcePath} -> ${destPath}${overwrite ? ' (overwrite)' : ''}`;
passsrc/files/copyFile.ts
interface Params {
sourcePath: string;
destPath: string;
overwrite?: boolean;
}
// The same call, self-documenting at every site, and safe to grow.
export const copyFile = ({ sourcePath, destPath, overwrite = false }: Params): string =>
`${sourcePath} -> ${destPath}${overwrite ? ' (overwrite)' : ''}`;
Turn it down
Both lines go in your lightsout.config.json.
"standards-checks": { "object-args": "advisory" }"standards-checks": { "object-args": "off" }