goscript 0.0.22 → 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/compiler/type.go CHANGED
@@ -4,17 +4,34 @@ import (
4
4
  "fmt"
5
5
  "go/ast"
6
6
  "go/types"
7
- "sort"
8
7
  "strings"
9
8
  )
10
9
 
10
+ // GoTypeContext specifies the context in which a Go type is being translated to TypeScript.
11
+ // This affects how certain types (especially pointers) are handled.
12
+ type GoTypeContext int
13
+
14
+ const (
15
+ // GoTypeContextGeneral is used for general type translation
16
+ GoTypeContextGeneral GoTypeContext = iota
17
+ // GoTypeContextFunctionReturn is used when translating types for function return values.
18
+ // In this context, pointer-to-struct types become `ClassName | null` instead of
19
+ // `$.Box<ClassName> | null` because function return values cannot be addressed.
20
+ GoTypeContextFunctionReturn
21
+ )
22
+
11
23
  // WriteGoType is the main dispatcher for translating Go types to their TypeScript
12
24
  // equivalents. It examines the type and delegates to more specialized type writer
13
25
  // functions based on the specific Go type encountered.
14
26
  //
27
+ // The context parameter controls how certain types (especially pointers) are handled:
28
+ // - GoTypeContextGeneral: Standard type translation
29
+ // - GoTypeContextFunctionReturn: Special handling for function return types where
30
+ // pointer-to-struct types become `ClassName | null` instead of `$.Box<ClassName> | null`
31
+ //
15
32
  // It handles nil types as 'any' with a comment, and dispatches to appropriate
16
33
  // type-specific writers for all other recognized Go types.
17
- func (c *GoToTSCompiler) WriteGoType(typ types.Type) {
34
+ func (c *GoToTSCompiler) WriteGoType(typ types.Type, context GoTypeContext) {
18
35
  if typ == nil {
19
36
  c.tsw.WriteLiterally("any")
20
37
  c.tsw.WriteCommentInline("nil type")
@@ -27,7 +44,11 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type) {
27
44
  case *types.Named:
28
45
  c.WriteNamedType(t)
29
46
  case *types.Pointer:
30
- c.WritePointerType(t)
47
+ if context == GoTypeContextFunctionReturn {
48
+ c.writePointerTypeForFunctionReturn(t)
49
+ } else {
50
+ c.WritePointerType(t)
51
+ }
31
52
  case *types.Slice:
32
53
  c.WriteSliceType(t)
33
54
  case *types.Array:
@@ -43,7 +64,10 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type) {
43
64
  case *types.Struct:
44
65
  c.WriteStructType(t)
45
66
  case *types.Alias:
46
- c.WriteGoType(t.Underlying())
67
+ c.WriteGoType(t.Underlying(), context)
68
+ case *types.TypeParam:
69
+ // For type parameters, write the type parameter name (e.g., "T", "K", etc.)
70
+ c.tsw.WriteLiterally(t.Obj().Name())
47
71
  default:
48
72
  // For other types, just write "any" and add a comment
49
73
  c.tsw.WriteLiterally("any")
@@ -51,12 +75,38 @@ func (c *GoToTSCompiler) WriteGoType(typ types.Type) {
51
75
  }
52
76
  }
53
77
 
78
+ // writePointerTypeForFunctionReturn translates a Go pointer type (*T) to its TypeScript
79
+ // equivalent for function return types. Unlike WritePointerType, this function
80
+ // handles pointer-to-struct types specially: they become `ClassName | null` instead
81
+ // of `$.Box<ClassName> | null` because function return values cannot be addressed.
82
+ func (c *GoToTSCompiler) writePointerTypeForFunctionReturn(t *types.Pointer) {
83
+ elemType := t.Elem()
84
+
85
+ // Check if the element type is a struct (directly or via a named type)
86
+ isStructType := false
87
+ if _, ok := elemType.Underlying().(*types.Struct); ok {
88
+ isStructType = true
89
+ }
90
+
91
+ if isStructType {
92
+ // For pointer-to-struct in function returns, generate ClassName | null
93
+ c.WriteGoType(elemType, GoTypeContextFunctionReturn)
94
+ c.tsw.WriteLiterally(" | null")
95
+ } else {
96
+ // For pointer-to-primitive in function returns, still use boxing
97
+ c.tsw.WriteLiterally("$.Box<")
98
+ c.WriteGoType(elemType, GoTypeContextFunctionReturn)
99
+ c.tsw.WriteLiterally("> | null")
100
+ }
101
+ }
102
+
54
103
  // WriteZeroValueForType writes the TypeScript representation of the zero value
55
104
  // for a given Go type.
56
105
  // It handles `types.Array` by recursively writing zero values for each element
57
106
  // to form a TypeScript array literal (e.g., `[0, 0, 0]`).
58
107
  // For `types.Basic` (like `bool`, `string`, numeric types), it writes the
59
108
  // corresponding TypeScript zero value (`false`, `""`, `0`).
109
+ // For `[]byte`, it writes `new Uint8Array(0)`.
60
110
  // Other types default to `null`. This function is primarily used for initializing
61
111
  // arrays and variables where an explicit initializer is absent.
62
112
  func (c *GoToTSCompiler) WriteZeroValueForType(typ any) {
@@ -97,9 +147,21 @@ func (c *GoToTSCompiler) WriteZeroValueForType(typ any) {
97
147
  }
98
148
  // For other named types, use the zero value of the underlying type
99
149
  c.WriteZeroValueForType(t.Underlying())
150
+ case *types.Slice:
151
+ // Check if it's a []byte slice
152
+ if elem, ok := t.Elem().(*types.Basic); ok && elem.Kind() == types.Uint8 {
153
+ c.tsw.WriteLiterally("new Uint8Array(0)")
154
+ return
155
+ }
156
+ // For other slice types, default to null
157
+ c.tsw.WriteLiterally("null")
100
158
  case *types.Struct:
101
159
  // For anonymous struct types, initialize with {}
102
160
  c.tsw.WriteLiterally("{}")
161
+ case *types.TypeParam:
162
+ // For type parameters, use null! (non-null assertion) to avoid TypeScript
163
+ // casting errors with union types like string | Uint8Array
164
+ c.tsw.WriteLiterally("null!")
103
165
  default:
104
166
  c.tsw.WriteLiterally("null")
105
167
  }
@@ -140,14 +202,27 @@ func (c *GoToTSCompiler) WriteBasicType(t *types.Basic) {
140
202
 
141
203
  // WriteNamedType translates a Go named type to its TypeScript equivalent.
142
204
  // It specially handles the error interface as $.GoError, and uses the original
143
- // type name for other named types.
205
+ // type name for other named types. For generic types, it includes type arguments.
144
206
  func (c *GoToTSCompiler) WriteNamedType(t *types.Named) {
145
207
  // Check if the named type is the error interface
146
208
  if iface, ok := t.Underlying().(*types.Interface); ok && iface.String() == "interface{Error() string}" {
147
209
  c.tsw.WriteLiterally("$.GoError")
148
- } else {
149
- // Use Obj().Name() for the original defined name
150
- c.tsw.WriteLiterally(t.Obj().Name())
210
+ return
211
+ }
212
+
213
+ // Use Obj().Name() for the original defined name
214
+ c.tsw.WriteLiterally(t.Obj().Name())
215
+
216
+ // For generic types, include type arguments
217
+ if t.TypeArgs() != nil && t.TypeArgs().Len() > 0 {
218
+ c.tsw.WriteLiterally("<")
219
+ for i := 0; i < t.TypeArgs().Len(); i++ {
220
+ if i > 0 {
221
+ c.tsw.WriteLiterally(", ")
222
+ }
223
+ c.WriteGoType(t.TypeArgs().At(i), GoTypeContextGeneral)
224
+ }
225
+ c.tsw.WriteLiterally(">")
151
226
  }
152
227
  }
153
228
 
@@ -155,22 +230,28 @@ func (c *GoToTSCompiler) WriteNamedType(t *types.Named) {
155
230
  // It generates $.Box<T_ts> | null, where T_ts is the translated element type.
156
231
  func (c *GoToTSCompiler) WritePointerType(t *types.Pointer) {
157
232
  c.tsw.WriteLiterally("$.Box<")
158
- c.WriteGoType(t.Elem())
233
+ c.WriteGoType(t.Elem(), GoTypeContextGeneral)
159
234
  c.tsw.WriteLiterally("> | null") // Pointers are always nullable
160
235
  }
161
236
 
162
237
  // WriteSliceType translates a Go slice type ([]T) to its TypeScript equivalent.
163
238
  // It generates $.Slice<T_ts>, where T_ts is the translated element type.
239
+ // For []byte, it generates Uint8Array.
164
240
  func (c *GoToTSCompiler) WriteSliceType(t *types.Slice) {
241
+ // Check if it's a []byte slice
242
+ if elem, ok := t.Elem().(*types.Basic); ok && elem.Kind() == types.Uint8 {
243
+ c.tsw.WriteLiterally("Uint8Array")
244
+ return
245
+ }
165
246
  c.tsw.WriteLiterally("$.Slice<")
166
- c.WriteGoType(t.Elem())
247
+ c.WriteGoType(t.Elem(), GoTypeContextGeneral)
167
248
  c.tsw.WriteLiterally(">")
168
249
  }
169
250
 
170
251
  // WriteArrayType translates a Go array type ([N]T) to its TypeScript equivalent.
171
252
  // It generates T_ts[], where T_ts is the translated element type.
172
253
  func (c *GoToTSCompiler) WriteArrayType(t *types.Array) {
173
- c.WriteGoType(t.Elem())
254
+ c.WriteGoType(t.Elem(), GoTypeContextGeneral)
174
255
  c.tsw.WriteLiterally("[]") // Arrays cannot be nil
175
256
  }
176
257
 
@@ -179,18 +260,19 @@ func (c *GoToTSCompiler) WriteArrayType(t *types.Array) {
179
260
  // and element types respectively.
180
261
  func (c *GoToTSCompiler) WriteMapType(t *types.Map) {
181
262
  c.tsw.WriteLiterally("Map<")
182
- c.WriteGoType(t.Key())
263
+ c.WriteGoType(t.Key(), GoTypeContextGeneral)
183
264
  c.tsw.WriteLiterally(", ")
184
- c.WriteGoType(t.Elem())
265
+ c.WriteGoType(t.Elem(), GoTypeContextGeneral)
185
266
  c.tsw.WriteLiterally(">")
186
267
  }
187
268
 
188
269
  // WriteChannelType translates a Go channel type (chan T) to its TypeScript equivalent.
189
- // It generates $.Channel<T_ts>, where T_ts is the translated element type.
270
+ // It generates $.Channel<T_ts> | null, where T_ts is the translated element type.
271
+ // Channels are nilable in Go, so they are represented as nullable types in TypeScript.
190
272
  func (c *GoToTSCompiler) WriteChannelType(t *types.Chan) {
191
273
  c.tsw.WriteLiterally("$.Channel<")
192
- c.WriteGoType(t.Elem())
193
- c.tsw.WriteLiterally(">")
274
+ c.WriteGoType(t.Elem(), GoTypeContextGeneral)
275
+ c.tsw.WriteLiterally("> | null")
194
276
  }
195
277
 
196
278
  // WriteFuncType translates a Go function type (`ast.FuncType`) into a TypeScript
@@ -217,7 +299,7 @@ func (c *GoToTSCompiler) WriteFuncType(exp *ast.FuncType, isAsync bool) {
217
299
  if len(exp.Results.List) == 1 && len(exp.Results.List[0].Names) == 0 {
218
300
  // Single unnamed return type
219
301
  typ := c.pkg.TypesInfo.TypeOf(exp.Results.List[0].Type)
220
- c.WriteGoType(typ)
302
+ c.WriteGoType(typ, GoTypeContextFunctionReturn)
221
303
  } else {
222
304
  // Multiple or named return types -> tuple
223
305
  c.tsw.WriteLiterally("[")
@@ -226,7 +308,7 @@ func (c *GoToTSCompiler) WriteFuncType(exp *ast.FuncType, isAsync bool) {
226
308
  c.tsw.WriteLiterally(", ")
227
309
  }
228
310
  typ := c.pkg.TypesInfo.TypeOf(field.Type)
229
- c.WriteGoType(typ)
311
+ c.WriteGoType(typ, GoTypeContextFunctionReturn)
230
312
  }
231
313
  c.tsw.WriteLiterally("]")
232
314
  }
@@ -288,10 +370,10 @@ func (c *GoToTSCompiler) WriteSignatureType(t *types.Signature) {
288
370
  c.tsw.WriteLiterally(": ")
289
371
 
290
372
  if paramVariadic && paramIsSlice {
291
- c.WriteGoType(paramSlice.Elem())
373
+ c.WriteGoType(paramSlice.Elem(), GoTypeContextGeneral)
292
374
  c.tsw.WriteLiterally("[]")
293
375
  } else {
294
- c.WriteGoType(param.Type())
376
+ c.WriteGoType(param.Type(), GoTypeContextGeneral)
295
377
  }
296
378
  }
297
379
  c.tsw.WriteLiterally(")")
@@ -302,7 +384,7 @@ func (c *GoToTSCompiler) WriteSignatureType(t *types.Signature) {
302
384
  if results.Len() == 0 {
303
385
  c.tsw.WriteLiterally("void")
304
386
  } else if results.Len() == 1 {
305
- c.WriteGoType(results.At(0).Type())
387
+ c.WriteGoType(results.At(0).Type(), GoTypeContextFunctionReturn)
306
388
  } else {
307
389
  // Multiple return values -> tuple
308
390
  c.tsw.WriteLiterally("[")
@@ -310,7 +392,7 @@ func (c *GoToTSCompiler) WriteSignatureType(t *types.Signature) {
310
392
  if i > 0 {
311
393
  c.tsw.WriteLiterally(", ")
312
394
  }
313
- c.WriteGoType(results.At(i).Type())
395
+ c.WriteGoType(results.At(i).Type(), GoTypeContextFunctionReturn)
314
396
  }
315
397
  c.tsw.WriteLiterally("]")
316
398
  }
@@ -378,7 +460,7 @@ func (c *GoToTSCompiler) writeInterfaceStructure(iface *types.Interface, astNode
378
460
  }
379
461
  c.tsw.WriteLiterally(paramName)
380
462
  c.tsw.WriteLiterally(": ")
381
- c.WriteGoType(paramVar.Type()) // Recursive call for param type
463
+ c.WriteGoType(paramVar.Type(), GoTypeContextGeneral) // Recursive call for param type
382
464
  }
383
465
  c.tsw.WriteLiterally(")") // End params
384
466
 
@@ -388,14 +470,14 @@ func (c *GoToTSCompiler) writeInterfaceStructure(iface *types.Interface, astNode
388
470
  if results.Len() == 0 {
389
471
  c.tsw.WriteLiterally("void")
390
472
  } else if results.Len() == 1 {
391
- c.WriteGoType(results.At(0).Type()) // Recursive call for result type
473
+ c.WriteGoType(results.At(0).Type(), GoTypeContextFunctionReturn) // Recursive call for result type
392
474
  } else {
393
475
  c.tsw.WriteLiterally("[")
394
476
  for j := 0; j < results.Len(); j++ {
395
477
  if j > 0 {
396
478
  c.tsw.WriteLiterally(", ")
397
479
  }
398
- c.WriteGoType(results.At(j).Type()) // Recursive call for result type
480
+ c.WriteGoType(results.At(j).Type(), GoTypeContextFunctionReturn) // Recursive call for result type
399
481
  }
400
482
  c.tsw.WriteLiterally("]")
401
483
  }
@@ -419,7 +501,7 @@ func (c *GoToTSCompiler) writeInterfaceStructure(iface *types.Interface, astNode
419
501
  // When WriteGoType encounters an interface, it will call WriteInterfaceType
420
502
  // which will pass nil for astNode, so comments for deeply embedded interface literals
421
503
  // might not be available unless they are named types.
422
- c.WriteGoType(embeddedType)
504
+ c.WriteGoType(embeddedType, GoTypeContextGeneral)
423
505
  }
424
506
  }
425
507
  }
@@ -433,107 +515,10 @@ func (c *GoToTSCompiler) getTypeString(goType types.Type) string {
433
515
  var typeStr strings.Builder
434
516
  writer := NewTSCodeWriter(&typeStr)
435
517
  tempCompiler := NewGoToTSCompiler(writer, c.pkg, c.analysis)
436
- tempCompiler.WriteGoType(goType)
518
+ tempCompiler.WriteGoType(goType, GoTypeContextGeneral)
437
519
  return typeStr.String()
438
520
  }
439
521
 
440
- // generateFlattenedInitTypeString generates a TypeScript type string for the
441
- // initialization object passed to a Go struct's constructor (`_init` method in TypeScript).
442
- // The generated type is a `Partial`-like structure, `"{ Field1?: Type1, Field2?: Type2, ... }"`,
443
- // including all direct and promoted fields of the `structType`.
444
- // - It iterates through the direct fields of the `structType`. Exported fields
445
- // are included with their TypeScript types (obtained via `WriteGoType`).
446
- // - For anonymous (embedded) fields, it generates a type like `EmbeddedName?: ConstructorParameters<typeof EmbeddedName>[0]`,
447
- // allowing initialization of the embedded struct's fields directly within the outer struct's initializer.
448
- // - It then uses `types.NewMethodSet` and checks for `types.Var` objects that are fields
449
- // to find promoted fields from embedded structs, adding them to the type string if not already present.
450
- //
451
- // The resulting string is sorted by field name for deterministic output and represents
452
- // the shape of the object expected by the struct's TypeScript constructor.
453
- func (c *GoToTSCompiler) generateFlattenedInitTypeString(structType *types.Named) string {
454
- if structType == nil {
455
- return "{}"
456
- }
457
-
458
- // Use a map to collect unique field names and their types
459
- fieldMap := make(map[string]string)
460
- embeddedTypeMap := make(map[string]string) // Stores TS type string for embedded struct initializers
461
-
462
- underlying, ok := structType.Underlying().(*types.Struct)
463
- if !ok {
464
- return "{}"
465
- }
466
-
467
- // First add the direct fields and track embedded types
468
- for i := 0; i < underlying.NumFields(); i++ {
469
- field := underlying.Field(i)
470
- fieldName := field.Name()
471
-
472
- if !field.Exported() && field.Pkg() != c.pkg.Types {
473
- continue
474
- }
475
-
476
- if field.Anonymous() {
477
- fieldType := field.Type()
478
- isPtr := false
479
- if ptr, ok := fieldType.(*types.Pointer); ok {
480
- fieldType = ptr.Elem()
481
- isPtr = true
482
- }
483
-
484
- if named, ok := fieldType.(*types.Named); ok {
485
- embeddedName := named.Obj().Name()
486
- // For embedded structs, the init type should allow providing fields of the embedded struct,
487
- // or the embedded struct itself.
488
- // We generate Partial<EmbeddedStructFields> | EmbeddedStructType
489
- // This is complex. For now, let's use ConstructorParameters as before for simplicity,
490
- // or allow the embedded struct type itself.
491
- // The example `Person?: ConstructorParameters<typeof Person>[0]` is for the fields.
492
- // Let's try to generate a type that allows either the embedded struct instance or its fields.
493
- // This might be: `Partial<FlattenedInitType<EmbeddedName>> | EmbeddedName`
494
- // For now, stick to the simpler `ConstructorParameters<typeof %s>[0]` which implies field-based init.
495
- // Or, more simply, the type of the embedded struct itself if it's a pointer.
496
- if isPtr {
497
- embeddedTypeMap[c.getEmbeddedFieldKeyName(field.Type())] = c.getTypeString(field.Type()) // MyEmbeddedType | null
498
- } else {
499
- // For value-type embedded structs, allow initializing with its fields.
500
- // This requires getting the flattened init type for the embedded struct.
501
- // This could lead to recursion if not handled carefully.
502
- // A simpler approach for now: use the embedded struct's own type.
503
- // embeddedTypeMap[c.getEmbeddedFieldKeyName(field.Type())] = c.getTypeString(field.Type())
504
- // Or, using ConstructorParameters to allow field-based initialization:
505
- embeddedTypeMap[c.getEmbeddedFieldKeyName(field.Type())] = fmt.Sprintf("Partial<ConstructorParameters<typeof %s>[0]>", embeddedName)
506
- }
507
- }
508
- continue
509
- }
510
- fieldMap[fieldName] = c.getTypeString(field.Type())
511
- }
512
-
513
- // Promoted fields (handled by Go's embedding, init should use direct/embedded names)
514
- // The current logic for `generateFlattenedInitTypeString` seems to focus on top-level
515
- // settable properties in the constructor. Promoted fields are accessed via `this.promotedField`,
516
- // not typically set directly in `init?` unless the embedded struct itself is named in `init?`.
517
-
518
- // Add embedded types to the field map (these are the names of the embedded structs themselves)
519
- for embeddedName, embeddedTSType := range embeddedTypeMap {
520
- fieldMap[embeddedName] = embeddedTSType
521
- }
522
-
523
- var fieldNames []string
524
- for name := range fieldMap {
525
- fieldNames = append(fieldNames, name)
526
- }
527
- sort.Strings(fieldNames)
528
-
529
- var fieldDefs []string
530
- for _, fieldName := range fieldNames {
531
- fieldDefs = append(fieldDefs, fmt.Sprintf("%s?: %s", fieldName, fieldMap[fieldName]))
532
- }
533
-
534
- return "{" + strings.Join(fieldDefs, ", ") + "}"
535
- }
536
-
537
522
  // WriteStructType translates a Go struct type definition (`ast.StructType`)
538
523
  // into a TypeScript anonymous object type (e.g., `{ Field1: Type1; Field2: Type2 }`).
539
524
  // If the struct has no fields, it writes `{}`. Otherwise, it delegates to
@@ -550,7 +535,84 @@ func (c *GoToTSCompiler) WriteStructType(t *types.Struct) {
550
535
  c.tsw.WriteLiterally("; ")
551
536
  }
552
537
  c.tsw.WriteLiterally(field.Name() + "?: ")
553
- c.WriteGoType(field.Type())
538
+ c.WriteGoType(field.Type(), GoTypeContextGeneral)
554
539
  }
555
540
  c.tsw.WriteLiterally(" }")
556
541
  }
542
+
543
+ // WriteTypeParameters translates Go type parameters to TypeScript generic parameters.
544
+ // It handles the TypeParams field of ast.FuncDecl and ast.TypeSpec to generate
545
+ // TypeScript generic parameter lists like <T extends SomeConstraint, U extends OtherConstraint>.
546
+ func (c *GoToTSCompiler) WriteTypeParameters(typeParams *ast.FieldList) {
547
+ if typeParams == nil || len(typeParams.List) == 0 {
548
+ return
549
+ }
550
+
551
+ c.tsw.WriteLiterally("<")
552
+ for i, field := range typeParams.List {
553
+ if i > 0 {
554
+ c.tsw.WriteLiterally(", ")
555
+ }
556
+ // Write each type parameter name and constraint
557
+ for j, name := range field.Names {
558
+ if j > 0 {
559
+ c.tsw.WriteLiterally(", ")
560
+ }
561
+ c.tsw.WriteLiterally(name.Name)
562
+
563
+ // Write constraint if present
564
+ if field.Type != nil {
565
+ c.tsw.WriteLiterally(" extends ")
566
+ c.WriteTypeConstraint(field.Type)
567
+ }
568
+ }
569
+ }
570
+ c.tsw.WriteLiterally(">")
571
+ }
572
+
573
+ // WriteTypeConstraint translates Go type constraints to TypeScript constraint expressions.
574
+ // It handles different constraint types including:
575
+ // - Union types: []byte | string -> string | Uint8Array
576
+ // - Interface types: interface{Method()} -> {Method(): void}
577
+ // - Basic types: any -> any, comparable -> $.Comparable
578
+ func (c *GoToTSCompiler) WriteTypeConstraint(constraint ast.Expr) {
579
+ switch t := constraint.(type) {
580
+ case *ast.Ident:
581
+ // Handle predeclared constraints
582
+ switch t.Name {
583
+ case "any":
584
+ c.tsw.WriteLiterally("any")
585
+ case "comparable":
586
+ c.tsw.WriteLiterally("$.Comparable")
587
+ default:
588
+ // Use the type directly
589
+ c.WriteTypeExpr(t)
590
+ }
591
+ case *ast.BinaryExpr:
592
+ // Handle union types like []byte | string
593
+ if t.Op.String() == "|" {
594
+ c.WriteTypeConstraint(t.X)
595
+ c.tsw.WriteLiterally(" | ")
596
+ c.WriteTypeConstraint(t.Y)
597
+ } else {
598
+ // Fallback for other binary expressions
599
+ c.WriteTypeExpr(constraint)
600
+ }
601
+ case *ast.InterfaceType:
602
+ // Handle interface constraints
603
+ c.WriteTypeExpr(constraint)
604
+ case *ast.ArrayType:
605
+ // Handle []byte specifically
606
+ if ident, ok := t.Elt.(*ast.Ident); ok && ident.Name == "byte" {
607
+ c.tsw.WriteLiterally("Uint8Array")
608
+ } else {
609
+ c.WriteTypeExpr(constraint)
610
+ }
611
+ case *ast.SliceExpr:
612
+ // Handle slice types in constraints
613
+ c.WriteTypeExpr(constraint)
614
+ default:
615
+ // Fallback: use the standard type expression writer
616
+ c.WriteTypeExpr(constraint)
617
+ }
618
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "goscript",
3
3
  "description": "Go to TypeScript transpiler",
4
- "version": "0.0.22",
4
+ "version": "0.0.23",
5
5
  "author": {
6
6
  "name": "Aperture Robotics LLC.",
7
7
  "email": "support@aperture.us",
@@ -34,10 +34,10 @@
34
34
  "default": "./dist/compiler/index.js"
35
35
  }
36
36
  },
37
- "./builtin": {
37
+ "./gs/builtin": {
38
38
  "import": {
39
- "types": "./dist/builtin/builtin.d.ts",
40
- "default": "./dist/builtin/builtin.js"
39
+ "types": "./dist/gs/builtin/builtin.d.ts",
40
+ "default": "./dist/gs/builtin/builtin.js"
41
41
  }
42
42
  }
43
43
  },
@@ -52,7 +52,7 @@
52
52
  "format": "npm run format:go && npm run format:js && npm run format:config",
53
53
  "format:config": "prettier --write tsconfig.json package.json",
54
54
  "format:go": "gofumpt -w .",
55
- "format:js": "prettier --write './{src,builtin,example}/**/(*.ts|*.tsx|*.html|*.css|*.scss)'",
55
+ "format:js": "prettier --write './{src,gs,example}/**/(*.ts|*.tsx|*.html|*.css|*.scss)'",
56
56
  "release": "npm run release:version && npm run release:commit",
57
57
  "release:minor": "npm run release:version:minor && npm run release:commit",
58
58
  "release:version": "npm version patch -m \"release: v%s\" --no-git-tag-version",
@@ -1,11 +0,0 @@
1
- package builtin
2
-
3
- import (
4
- _ "embed"
5
- )
6
-
7
- // BuiltinTs contains the contents of the builtin.ts file which provides
8
- // runtime support for GoScript compiled code.
9
- //
10
- //go:embed builtin.ts
11
- var BuiltinTs string