Skip to content

Add support for byte type#90

Merged
gzuidhof merged 2 commits into
gzuidhof:mainfrom
pescew:supportByte
Feb 3, 2026
Merged

Add support for byte type#90
gzuidhof merged 2 commits into
gzuidhof:mainfrom
pescew:supportByte

Conversation

@pescew

@pescew pescew commented Jul 20, 2025

Copy link
Copy Markdown
Contributor

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

pescew commented Jul 20, 2025

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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

pescew commented Jul 24, 2025

Copy link
Copy Markdown
Contributor Author

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 */;
}

@gzuidhof gzuidhof merged commit 0b55b7f into gzuidhof:main Feb 3, 2026
@steffen-4s1

Copy link
Copy Markdown

I don't think it's right to treat []byte and []uint8 the same. Technically, they're the same, but they represent different things. That's why there are two types.

  • []byte used for binary data / strings / I/O
  • []uint8 used more in numeric contexts
data := []byte("hello")   // meaningful: text / bytes
nums := []uint8{1, 2, 3}  // meaningful: numbers

In my source code, I have a slice of uint8 values that shouldn't be interpreted as a string type, but as a number[]. In my case, the latest update therefore results in incorrect types.

@gzuidhof

gzuidhof commented Apr 8, 2026

Copy link
Copy Markdown
Owner

Hmm.. You should be able to use the tstype tag to override its behavior, would that work for your case?

I fear there may not be one size fits all :(

@steffen-4s1

Copy link
Copy Markdown

Yes, tstype:"number[]" it's also my solution for the issue, thank you.

However, I just wanted to make aware that, from a conceptional standpoint, []byte and []uint8 are not the same in Go. I was wondering whether this should be taken into account?!

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.

3 participants