package builtin import ( "fmt" "reflect" "strings" ) func getFieldName(field reflect.StructField) string { jsonTag := field.Tag.Get("json") if jsonTag != "" && jsonTag != "-" { name, _, _ := strings.Cut(jsonTag, ",") return name } return field.Name } func generateTypeScriptDefinition(name string, argsType reflect.Type, fnType reflect.Type, isPromise bool, paramTypes map[string]bool) string { if argsType.Kind() != reflect.Struct { return "" } var params []string for i := 0; i < argsType.NumField(); i++ { field := argsType.Field(i) fieldName := getFieldName(field) goType := field.Type var tsType string var isOptional bool isPointer := goType.Kind() == reflect.Pointer if isPointer { isOptional = true tsType = goTypeToTSType(goType, true) if !strings.Contains(tsType, " | null") { tsType += " | null" } } else { isOptional = strings.Contains(field.Tag.Get("json"), ",omitempty") tsType = goTypeToTSType(goType, false) if isOptional && paramTypes[tsType+" | null"] { tsType += " | null" } } if isOptional { fieldName += "?" } params = append(params, fmt.Sprintf("%s: %s", fieldName, tsType)) } returnSignature := "any" if fnType.Kind() == reflect.Func && fnType.NumOut() > 0 { lastIndex := fnType.NumOut() - 1 lastType := fnType.Out(lastIndex) if lastType.Implements(reflect.TypeOf((*error)(nil)).Elem()) { if fnType.NumOut() > 1 { returnType := fnType.Out(0) returnSignature = goTypeToTSType(returnType, returnType.Kind() == reflect.Pointer) } } else { returnSignature = goTypeToTSType(lastType, lastType.Kind() == reflect.Pointer) } } if isPromise { returnSignature = fmt.Sprintf("Promise<%s>", returnSignature) } return fmt.Sprintf("declare function %s(%s): %s;", name, strings.Join(params, ", "), returnSignature) }