{"record":{"id":"1bf3e31c87bb0b85","repo":"wailsapp/wails","slug":"has-no-tsname-method","errorCode":null,"errorMessage":" has no TSName method","messagePattern":" has no TSName method","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v2/internal/typescriptify/typescriptify.go","lineNumber":371,"sourceCode":"\t\tvar el enumElement\n\t\tif item.Kind() == reflect.Struct {\n\t\t\tr := reflector.New(item.Interface())\n\t\t\tval, err := r.Field(\"Value\").Get()\n\t\t\tif err != nil {\n\t\t\t\tpanic(fmt.Sprint(\"missing Type field in \", item.Type().String()))\n\t\t\t}\n\t\t\tname, err := r.Field(\"TSName\").Get()\n\t\t\tif err != nil {\n\t\t\t\tpanic(fmt.Sprint(\"missing TSName field in \", item.Type().String()))\n\t\t\t}\n\t\t\tel.value = val\n\t\t\tel.name = name.(string)\n\t\t} else {\n\t\t\tel.value = item.Interface()\n\t\t\tif tsNamer, is := item.Interface().(TSNamer); is {\n\t\t\t\tel.name = tsNamer.TSName()\n\t\t\t} else {\n\t\t\t\tpanic(fmt.Sprint(item.Type().String(), \" has no TSName method\"))\n\t\t\t}\n\t\t}\n\n\t\telements = append(elements, el)\n\t}\n\tslices.SortFunc(elements, func(a, b enumElement) int {\n\t\treturn cmp.Compare(a.name, b.name)\n\t})\n\tty := reflect.TypeOf(elements[0].value)\n\tt.enums[ty] = elements\n\tt.enumTypes = append(t.enumTypes, EnumType{Type: ty})\n\n\treturn t\n}\n\n// AddEnumValues is deprecated, use `AddEnum()`\nfunc (t *TypeScriptify) AddEnumValues(typeOf reflect.Type, values interface{}) *TypeScriptify {\n\tt.AddEnum(values)","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/wailsapp/wails/blob/0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3/v2/internal/typescriptify/typescriptify.go#L353-L389","documentation":"For non-struct enum elements, AddEnum requires each element to implement the TSNamer interface (method TSName() string) to know its TypeScript member name; otherwise it panics with '<Type> has no TSName method'. This is the alternate path when enum values are plain named types rather than structs with Value/TSName fields.","triggerScenarios":"Calling AddEnum([]MyEnum{...}) where MyEnum is a plain int/string type (or its elements) without a TSName() string method.","commonSituations":"Passing a slice of ordinary Go named-type constants expecting the generator to derive names from identifiers; reflection cannot see identifier names, so an explicit TSName method is mandatory.","solutions":["Implement func (e MyEnum) TSName() string on the enum type returning the TypeScript name","Or switch to struct elements with exported Value and TSName fields"],"exampleFix":"// before\ntype Mode int\nconst (Read Mode = 0; Write Mode = 1)\nts.AddEnum([]Mode{Read, Write}) // panics\n\n// after\nfunc (m Mode) TSName() string { return [...]string{\"Read\",\"Write\"}[m] }\nts.AddEnum([]Mode{Read, Write})","handlingStrategy":"type-guard","validationCode":"if _, ok := any(MyEnum(0)).(typescriptify.TSNamer); !ok {\n    return fmt.Errorf(\"type %T must implement TSName() string\", MyEnum(0))\n}\nts.AddEnum([]MyEnum{...})","typeGuard":"func addNamedEnums[T typescriptify.TSNamer](t *typescriptify.TypeScriptify, vals ...T) {\n    t.AddEnum(vals) // TSNamer constraint makes missing method a compile error\n}","tryCatchPattern":null,"preventionTips":["Implement TSName() string on non-struct enum types","Use a generic helper constrained to the TSNamer interface so the compiler checks it"],"tags":["typescript","bindings","reflection","api-misuse","panic"],"backgroundTag":null,"analyzedSha":"0e754b1b40ba9044c2a1460e23b7c3de20fc5cf3","analyzedAt":"2026-08-15T14:17:36.034Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}