emit_types.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package main
  2. import (
  3. "fmt"
  4. "io"
  5. "sort"
  6. )
  7. func emitTypes(w io.Writer, schemas []Schema, aliases []Alias) error {
  8. if _, err := fmt.Fprintln(w, typesHeader); err != nil {
  9. return err
  10. }
  11. for _, a := range sortAliases(aliases) {
  12. if _, err := fmt.Fprintf(w, "export type %s = %s;\n", a.Name, tsTypeExpr(a.Underlying)); err != nil {
  13. return err
  14. }
  15. }
  16. if len(aliases) > 0 {
  17. if _, err := fmt.Fprintln(w); err != nil {
  18. return err
  19. }
  20. }
  21. for _, s := range sortSchemas(schemas) {
  22. if _, err := fmt.Fprintf(w, "export interface %s {\n", s.Name); err != nil {
  23. return err
  24. }
  25. fields := append([]Field(nil), s.Fields...)
  26. sort.SliceStable(fields, func(i, j int) bool { return fields[i].JSONName < fields[j].JSONName })
  27. for _, f := range fields {
  28. optional := ""
  29. if f.Optional {
  30. optional = "?"
  31. }
  32. line := fmt.Sprintf(" %s%s: %s;\n", quoteIfNeeded(f.JSONName), optional, tsTypeExpr(f.Type))
  33. if _, err := fmt.Fprint(w, line); err != nil {
  34. return err
  35. }
  36. }
  37. if _, err := fmt.Fprintln(w, "}"); err != nil {
  38. return err
  39. }
  40. if _, err := fmt.Fprintln(w); err != nil {
  41. return err
  42. }
  43. }
  44. return nil
  45. }
  46. func tsTypeExpr(t TypeRef) string {
  47. switch t.Kind {
  48. case KindString:
  49. return "string"
  50. case KindBool:
  51. return "boolean"
  52. case KindInt, KindNumber:
  53. return "number"
  54. case KindAny, KindUnknown, KindRaw:
  55. return "unknown"
  56. case KindArray:
  57. return tsTypeExpr(*t.Element) + "[]"
  58. case KindMap:
  59. return "Record<" + tsTypeExpr(*t.Key) + ", " + tsTypeExpr(*t.Value) + ">"
  60. case KindRef:
  61. if t.Name == "nullable" {
  62. return tsTypeExpr(*t.Inner) + " | null"
  63. }
  64. return t.Name
  65. }
  66. return "unknown"
  67. }
  68. const typesHeader = `// Code generated by tools/openapigen. DO NOT EDIT.`