GoScript

Go到TypeScript编译器的原理、架构与设计思想

Go与TypeScript结合

code 什么是GoScript?

GoScript是一个Go到TypeScript编译器,它在AST(抽象语法树)级别将Go代码转换为TypeScript。这使得开发人员可以在Go后端和TypeScript前端之间共享算法和业务逻辑,实现"一次编写,到处运行"的目标。

Go代码示例
type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

func (u *User) IsValid() bool {
    return u.Name != "" && u.Email != ""
}
转换后的TypeScript代码
export class User {
  public ID: number = 0
  public Name: string = ""
  public Email: string = ""

  public IsValid(): boolean {
    const u = this
    return u.Name !== "" && u.Email !== ""
  }
}
sync

代码共享

在Go后端和TypeScript前端之间无缝共享算法、业务逻辑和数据结构

architecture

AST级别转换

在抽象语法树级别进行转换,保持代码结构和语义的准确性

settings

丰富的功能支持

支持结构体、接口、方法、通道、goroutines等Go核心特性

integration_instructions

易于集成

提供命令行工具和程序化API,轻松集成到现有开发流程中

GoScript工作原理

GoScript工作原理

AST级别的Go到TypeScript转换机制

AST转换流程图

sync_alt 编译流程

GoScript在抽象语法树(AST)级别进行转换,确保代码结构和语义的准确性。整个编译过程分为以下几个关键步骤:

Go代码解析

使用Go标准库中的解析器将Go源代码解析为抽象语法树(AST),保留代码的结构和语义信息。

AST转换

将Go AST转换为TypeScript兼容的AST结构,处理类型系统差异、语言特性映射和语法转换。

代码生成

将转换后的AST生成为TypeScript代码,确保生成的代码符合TypeScript语法规范和最佳实践。

依赖处理

处理Go包依赖关系,生成对应的TypeScript模块导入结构,确保代码模块化组织。

transform 核心转换机制

GoScript通过以下核心机制实现Go到TypeScript的准确转换:

data_object 类型系统映射

将Go的类型系统映射到TypeScript,包括基本类型、结构体、接口和自定义类型。

schema 结构转换

将Go的结构体(struct)转换为TypeScript类(class),保留字段和方法定义。

swap_horiz 并发模型转换

将Go的goroutines和channels转换为TypeScript的async/await和Promise模式。

api 接口映射

将Go的接口(interface)转换为TypeScript接口,保持多态性和实现关系。

Go代码示例
func ProcessMessages(messages []string) chan string {
    results := make(chan string, len(messages))
    
    for _, msg := range messages {
        go func(m string) {
            // 模拟处理过程
            processed := "✓ " + m
            results <- processed
        }(msg)
    }
    
    return results
}
转换后的TypeScript代码
export function ProcessMessages(messages: string[]): $.Channel {
  let results = $.makeChannel(messages.length, "")
  
  for (let msg of messages) {
    queueMicrotask(async (m: string) => {
      let processed = "✓ " + m
      await results.send(processed)
    })(msg)
  }
  
  return results
}
GoScript架构设计

GoScript架构设计

模块化组件与数据流分析

GoScript架构图

architecture 核心组件

GoScript采用模块化设计,由多个核心组件协同工作,实现Go代码到TypeScript的转换:

code Go解析器

使用Go标准库中的解析器将Go源代码解析为抽象语法树(AST),捕获代码的结构和语义信息。

transform AST转换器

将Go AST转换为TypeScript兼容的AST结构,处理类型系统差异和语言特性映射。

description 代码生成器

将转换后的AST生成为TypeScript代码,确保生成的代码符合TypeScript语法规范。

hub 依赖管理器

处理Go包依赖关系,生成对应的TypeScript模块导入结构,确保代码模块化组织。

alt_route 数据流与处理流程

GoScript的编译过程遵循清晰的数据流,确保转换的准确性和一致性:

input
Go源代码
account_tree
Go AST
swap_horiz
AST转换
code
TypeScript
GoScript API使用示例
import "github.com/aperturerobotics/goscript/compiler"

conf := &compiler.Config{OutputPath: "./dist"}
comp, err := compiler.NewCompiler(conf, logger, nil)
_, err = comp.CompilePackages(ctx, "your/package/path")

lightbulb 架构设计特性

GoScript的架构设计遵循以下关键特性,确保高效、可靠的代码转换:

extension

模块化设计

各组件职责明确,松耦合,便于维护和扩展

published_with_changes

类型安全转换

在转换过程中保持类型系统的完整性和安全性

settings_suggest

可配置性

提供丰富的配置选项,满足不同场景的需求

integration_instructions

易于集成

提供命令行工具和程序化API,轻松集成到现有开发流程

GoScript设计思想

GoScript设计思想

跨语言代码共享的理念与原则

lightbulb 核心设计理念

GoScript的设计围绕几个核心理念展开,旨在实现Go代码与TypeScript环境的无缝集成:

sync

一次编写,到处运行

让开发者能够编写一次Go代码,同时在后端Go环境和前端TypeScript环境中运行,消除重复开发的负担。

architecture

保持语言特性

在转换过程中尽可能保留Go语言的特性和表达力,使转换后的TypeScript代码保持原始逻辑和结构。

settings_suggest

类型安全

确保类型系统在转换过程中的完整性和安全性,减少运行时错误,提高代码质量。

integration_instructions

无缝集成

设计易于使用的工具和API,使开发者能够轻松地将GoScript集成到现有的开发工作流中。

format_quote

Right now goscript looks pretty cool if you problem is "I want this self-sufficient algorithm be available in Go and JS runtimes".

— nevkontakte, GopherJS开发者

psychology 关键设计思想

GoScript的设计思想体现在以下几个方面,这些思想指导着整个项目的发展方向:

swap_horiz

语义等价性

转换后的TypeScript代码在语义上与原始Go代码等价,保持相同的逻辑行为和执行结果,确保代码在不同环境中的一致性。

auto_fix_high

最小化转换开销

设计高效的转换算法,减少转换过程中的性能开销,使开发者能够快速迭代和测试代码,提高开发效率。

extension

模块化与可扩展性

采用模块化设计,使GoScript能够轻松扩展支持更多Go语言特性和标准库组件,满足不断变化的需求。

diversity_3

开发者友好

提供清晰的错误信息和调试工具,帮助开发者快速定位和解决转换过程中的问题,降低使用门槛。

GoScript设计示例:并发模型转换
// Go代码
func ProcessData(data []string) []string {
    var wg sync.WaitGroup
    results := make([]string, len(data))
    
    for i, item := range data {
        wg.Add(1)
        go func(idx int, d string) {
            defer wg.Done()
            results[idx] = "Processed: " + d
        }(i, item)
    }
    
    wg.Wait()
    return results
}
转换后的TypeScript代码
// TypeScript代码
export async function ProcessData(data: string[]): Promise {
    let results: string[] = new Array(data.length);
    let promises: Promise[] = [];
    
    for (let i = 0; i < data.length; i++) {
        let promise = (async (idx: number, d: string) => {
            results[idx] = "Processed: " + d;
        })(i, data[i]);
        promises.push(promise);
    }
    
    await Promise.all(promises);
    return results;
}
GoScript功能与限制

GoScript功能与限制

支持特性与当前限制详解

check_circle 已支持功能

GoScript已经实现了Go语言的核心特性,能够满足大多数业务逻辑和算法转换需求:

data_object

结构体与接口

完整支持Go的结构体(struct)和接口(interface),包括嵌套结构体和接口组合。

functions

方法与函数

支持Go的方法定义、函数声明,包括多返回值、命名返回值和变参函数。

swap_horiz

通道与Goroutines

将Go的并发模型转换为TypeScript的async/await和Promise模式,保持并发特性。

view_array

切片与映射

支持Go的切片(slice)和映射(map)类型,以及相关操作如append、range等。

Go并发代码示例
func ProcessData(data []string) []string {
    results := make(chan string, len(data))
    
    for _, item := range data {
        go func(d string) {
            processed := "✓ " + d
            results <- processed
        }(item)
    }
    
    var output []string
    for i := 0; i < len(data); i++ {
        output = append(output, <-results)
    }
    
    return output
}

warning 当前限制

虽然GoScript已经支持了许多Go语言特性,但仍存在一些限制需要注意:

exposure

数值类型限制

部分支持

使用JavaScript的number类型(64位浮点数)代替Go的int类型,可能导致精度问题。

memory

指针运算

不支持

不支持指针运算(uintptr)和unsafe包,这些特性在JavaScript环境中无法直接实现。

calculate

复数类型

不支持

不支持Go的复数类型(complex64和complex128),JavaScript没有原生复数支持。

library_books

标准库支持

部分支持

标准库支持有限,但正在快速增长,目前支持常用包如fmt、strings、time等。

compare Go与TypeScript特性对比

Go特性 TypeScript实现 支持状态
结构体(struct) 类(class)与接口(interface)
check_circle 完全支持
通道(channel)与goroutine Promise与async/await
check_circle 完全支持
接口(interface) TypeScript接口
check_circle 完全支持
指针(pointer) 引用类型
warning 部分支持
defer语句 try/finally块
check_circle 完全支持
反射(reflect) 有限反射支持
warning 部分支持

checklist 适用场景

基于当前的功能支持和限制,GoScript特别适合以下场景:

check

算法共享

将Go中的算法转换为TypeScript,在前端和后端共享相同的算法实现。

check

业务逻辑复用

在Go后端和TypeScript前端之间共享业务逻辑,减少重复开发。

check

数据结构转换

将Go的数据结构转换为TypeScript,保持数据模型的一致性。

remove

系统级编程

不适合需要底层系统访问、指针运算或unsafe包的系统级编程场景。

GoScript使用示例

GoScript使用示例

安装、编译与代码转换实例

download 安装指南

GoScript提供了多种安装方式,可以根据您的开发环境选择最适合的安装方法:

1

通过Go安装

使用Go的包管理工具直接安装GoScript命令行工具:

bash
go install github.com/aperturerobotics/goscript/cmd/goscript@latest
2

通过NPM安装

如果您更习惯使用Node.js生态系统,可以通过NPM安装:

bash
npm install -g goscript
3

验证安装

安装完成后,可以通过以下命令验证GoScript是否正确安装:

bash
goscript --version

play_circle 基本使用

安装完成后,您可以使用GoScript编译Go代码为TypeScript。以下是最基本的编译命令:

bash
# 编译您的Go包为TypeScript
goscript compile --package . --output ./dist

GoScript还提供了丰富的命令行选项,以满足不同的编译需求:

bash
# 指定特定的Go包进行编译
goscript compile --package ./my-go-code --output ./dist

# 使用程序化API(Go代码示例)
import "github.com/aperturerobotics/goscript/compiler"

conf := &compiler.Config{OutputPath: "./dist"}
comp, err := compiler.NewCompiler(conf, logger, nil)
_, err = comp.CompilePackages(ctx, "your/package/path")
lightbulb
提示:编译后的TypeScript代码需要配置适当的tsconfig.json设置,特别是target需要设置为ES2022或更新版本,以支持Disposable等特性。
people

示例1:用户管理

以下示例展示了如何将Go中的用户管理代码转换为TypeScript,包括结构体定义、方法和函数:

code Go代码 Go

user.go
package main

type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

func (u *User) IsValid() bool {
    return u.Name != "" && u.Email != ""
}

func NewUser(id int, name, email string) *User {
    return &User{ID: id, Name: name, Email: email}
}

func FindUserByEmail(users []*User, email string) *User {
    for _, user := range users {
        if user.Email == email {
            return user
        }
    }
    return nil
}

code TypeScript代码 TypeScript

user.ts
export class User {
  public ID: number = 0
  public Name: string = ""
  public Email: string = ""

  public IsValid(): boolean {
    const u = this
    return u.Name !== "" && u.Email !== ""
  }

  constructor(init?: Partial) {
    if (init) Object.assign(this, init)
  }
}

export function NewUser(id: number, name: string, email: string): User {
  return new User({ ID: id, Name: name, Email: email })
}

export function FindUserByEmail(users: User[], email: string): User | null {
  for (let user of users) {
    if (user.Email === email) {
      return user
    }
  }
  return null
}
lightbulb
在前端使用:您可以直接导入转换后的TypeScript代码,像使用原生TypeScript代码一样使用它。
sync

示例2:异步处理

以下示例展示了GoScript如何处理Go中的并发特性,将goroutines和channels转换为TypeScript的async/await模式:

code Go代码 Go

processor.go
func ProcessMessages(messages []string) chan string {
    results := make(chan string, len(messages))
    
    for _, msg := range messages {
        go func(m string) {
            // 模拟处理过程
            processed := "✓ " + m
            results <- processed
        }(msg)
    }
    
    return results
}

code TypeScript代码 TypeScript

processor.ts
export function ProcessMessages(messages: string[]): $.Channel {
  let results = $.makeChannel(messages.length, "")
  
  for (let msg of messages) {
    queueMicrotask(async (m: string) => {
      let processed = "✓ " + m
      await results.send(processed)
    })(msg)
  }
  
  return results
}
lightbulb
在前端使用:您可以使用async/await语法处理转换后的异步代码,保持与原生TypeScript异步代码相同的开发体验。

integration_instructions 前端框架集成

GoScript生成的TypeScript代码可以轻松集成到各种前端框架中。以下是React和Vue的集成示例:

react React集成

tsx
import { useState } from 'react'
import { NewCalculator } from '@goscript/myapp/calculator'

function CalculatorApp() {
  const [calc] = useState(() => NewCalculator())
  const [result, setResult] = useState(0)
  
  const handleAdd = () => {
    const result = calc.Add(5, 3)
    setResult(result)
  }

  return (
    

Result: {result}

) }

vue Vue集成

vue
<script setup lang="ts">
import { ref } from 'vue'
import { NewUser, FindUserByEmail } from '@goscript/myapp/user'

const users = ref([
  NewUser(1, "Alice", "alice@example.com")
])

const searchUser = (email: string) => {
  return FindUserByEmail(users.value, email)
}
</script>

<template>
  <div>
    <input v-model="searchEmail" placeholder="输入邮箱搜索用户">
    <button @click="findUser">搜索</button>
  </div>
</template>
GoScript未来发展

GoScript未来发展

当前状态与未来规划

assessment 当前状态

GoScript已经实现了Go语言的核心特性,能够满足大多数业务逻辑和算法转换需求:

check_circle

核心语言特性

已完成

结构体、方法、接口、控制流等核心语言特性已完全支持。

check_circle

并发模型转换

已完成

Goroutines和channels已成功转换为async/await和Promise模式。

check_circle

基本反射支持

已完成

实现了基本的反射功能,支持类型检查和动态调用。

check_circle

控制流与数据类型

已完成

支持大多数控制流语句和Go内置数据类型的转换。

upcoming 即将推出的功能

GoScript团队正在积极开发以下功能,以进一步扩展其能力和应用场景:

pending

扩展标准库

进行中

增加对更多Go标准库包的支持,如net、http、encoding等,使更多Go代码能够无缝转换。

schedule

测试转换

计划中

实现Go测试到TypeScript测试的自动转换,确保转换后的代码行为一致性。

schedule

性能优化

计划中

优化转换算法和生成的TypeScript代码,提高运行时性能和减少代码体积。

schedule

工具集成

计划中

提供更好的IDE集成、调试工具和自动化构建流程,提升开发体验。

timeline 发展路线图

GoScript的发展路线图规划了未来的关键里程碑和功能迭代:

flag

library_books 标准库扩展

优先扩展对常用标准库包的支持,包括io、os、path、strings等,使更多Go代码能够无缝转换。

flag

science 测试框架集成

实现Go测试到TypeScript测试的自动转换,支持主流测试框架,确保转换后代码的行为一致性。

flag

speed 性能优化

优化转换算法和生成的TypeScript代码,提高运行时性能,减少代码体积,提升开发体验。

flag

integration_instructions 工具链完善

提供更好的IDE集成、调试工具和自动化构建流程,降低使用门槛,提升开发效率。

emoji_events 关键里程碑

GoScript的发展将通过以下关键里程碑来衡量进展:

auto_awesome

标准库覆盖率达到80%

2024 Q3

实现对Go标准库80%以上包的完整支持,覆盖大多数常用场景。

verified

测试转换完整支持

2024 Q4

完成Go测试到TypeScript测试的完整转换支持,包括表驱动测试和基准测试。

rocket_launch

1.0正式版发布

2025 Q1

发布GoScript 1.0正式版,提供稳定、全面的Go到TypeScript转换解决方案。

groups

参与GoScript的发展

GoScript是一个开源项目,欢迎社区贡献代码、报告问题或提出新功能建议。您的参与将帮助GoScript变得更好!

访问GitHub仓库 →