Skip to content

Conversation

@pescew
Copy link

@pescew pescew commented Jul 20, 2025

In Go, byte is an alias for uint8. However when tygo processes a struct with a field of type byte it does not treat it the same way as a struct with a field of type uint8. This pull request allows tygo to treat Go byte fields as a TS number in the same way as uint8 fields.

For example, currently this Go struct converts to the following TS interface:

type Hours struct {
	OpenHour    byte
	CloseHour   uint8
}
export interface Hours {
	OpenHour: byte;
	CloseHour: number /* uint8 */;
}

After this change the same Go struct converts to:

export interface Hours {
	OpenHour: number /* byte */;
	CloseHour: number /* uint8 */;
}

@pescew
Copy link
Author

pescew commented Jul 20, 2025

Also note byte slices are still treated as strings, from here:
https://github.com/gzuidhof/tygo/blob/main/tygo/write.go#L80

But uint8 slices are converted to number[]. Is this the intended behavior?

@gzuidhof
Copy link
Owner

Thank you, I generated a script using a LLM to see what the encode/json defaults to, I think that should generally be the type that tygo maps to.

package main

import (
	"encoding/json"
	"fmt"
)

type DataHolder struct {
	SingleUint8  uint8   `json:"single_uint8"`
	SliceOfUint8 []uint8 `json:"slice_of_uint8"`
	SingleByte   byte    `json:"single_byte"`
	SliceOfByte  []byte  `json:"slice_of_byte"`
}

func main() {
	// 1. Create an instance of the struct with sample data.
	data := DataHolder{
		SingleUint8:  123,
		SliceOfUint8: []uint8{10, 20, 30, 255},
		SingleByte:   'A', // 'A' is 65 in ASCII
		SliceOfByte:  []byte("Hello, JSON!"),
	}

	// 2. Marshal the struct into JSON. We use MarshalIndent for pretty-printing.
	// The standard json.Marshal() would produce a single line of output.
	jsonData, err := json.MarshalIndent(data, "", "  ")
	if err != nil {
		fmt.Println("Error marshalling JSON:", err)
		return
	}

	// 3. Print the resulting JSON data.
	fmt.Println("JSON Encoded Data:")
	fmt.Println(string(jsonData))
}
JSON Encoded Data:
{
  "single_uint8": 123,
  "slice_of_uint8": "ChQe/w==",
  "single_byte": 65,
  "slice_of_byte": "SGVsbG8sIEpTT04h"
}

So I imagine that []uint8 should realy also mapped to a string (as the json encoder will base64 encode it).

@pescew
Copy link
Author

pescew commented Jul 24, 2025

It's a good idea to follow the json typing. I made a change to handle both byte and uint8 slices as strings, with a Typescript comment to the original Go type.

type DataHolder struct {
	SingleUint8  uint8   `json:"single_uint8"`
	SliceOfUint8 []uint8 `json:"slice_of_uint8"`
	SingleByte   byte    `json:"single_byte"`
	SliceOfByte  []byte  `json:"slice_of_byte"`
}
export interface DataHolder {
    single_uint8: number /* uint8 */;
    slice_of_uint8: string /* []uint8 */;
    single_byte: number /* byte */;
    slice_of_byte: string /* []byte */;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants