| name | golang-type-safety |
| description | Prefer typed constants and named types over magic strings/numbers in Go. Use when writing function signatures, struct fields, switch statements, or passing enum-like values. |
Go Type Safety
Use typed constants and named types instead of magic strings and numbers. This catches misuse at compile time and makes intent explicit.
Named String Types for Enums
When a value comes from a defined set (e.g. ent-generated enums, config enums), use the named type:
publishStageStatus(ctx, pub, sid, stgID, name, idx, "investigation", status)
publishStageStatus(ctx, pub, sid, stgID, name, idx, stage.StageTypeInvestigation, status)
Function Signatures
Accept the named type, not string, when the parameter is always one of a known set:
func publishStageStatus(ctx context.Context, ..., stageType string, status string)
func publishStageStatus(ctx context.Context, ..., stageType stage.StageType, status string)
Convert to string at serialization boundaries (JSON payloads, DB queries, log messages):
payload.StageType = string(stageType)
Warning: Direct Casting Does Not Validate
stage.StageType(s) compiles but does not check whether s is a known value.
Always use a parse helper at API/deserialize boundaries where the input is untrusted:
stageType := stage.StageType(req.StageType)
stageType, err := parseStageType(req.StageType)
if err != nil {
return nil, err
}
parseStageType Helper
Define this once near the package entry point (e.g., handler or service layer):
func parseStageType(s string) (stage.StageType, error) {
switch stage.StageType(s) {
case stage.StageTypeInvestigation,
stage.StageTypeSynthesis,
stage.StageTypeChat,
stage.StageTypeExecSummary,
stage.StageTypeScoring:
return stage.StageType(s), nil
default:
return "", fmt.Errorf("unknown stage type %q", s)
}
}
This is the only place where an unvalidated cast is acceptable — all call sites receive an already-validated stage.StageType.
Struct Fields
Use string for DTOs/payloads that cross API boundaries (JSON serialization).
Use the named type for internal structs where type safety helps:
type StageStatusPayload struct {
StageType string `json:"stage_type"`
}
type stageInput struct {
stageType stage.StageType
}
Struct Literals
When constructing structs with string fields that accept enum values, use string(constant):
req := CreateStageRequest{StageType: "synthesis"}
req := CreateStageRequest{StageType: string(stage.StageTypeSynthesis)}
When NOT to Use Named Types
- One-off values that aren't from a defined set (free-form names, user input)
- Test data where the literal is the point (e.g.
"bogus" for invalid input tests)
- String comparisons in tests asserting wire-format output