- Pumili ang pangkat ng TypeScript ng isang port para sa isang buong muling pagsusulat upang mapanatiling magkapareho ang mga mensahe ng error at semantika.
- Ang garbage collection at mga primera klaseng pagsasara ng Go ay mahalaga para sa paghawak ng mga kumplikadong istruktura ng datos ng compiler.
- Ang borrow checker ng Rust ay magpipilit ng mga manu-manong workaround para sa mga pabilog na sanggunian, na magdaragdag ng hindi kinakailangang pagiging kumplikado.
- Nagbigay ang Go ng mature native code generation at shared-memory concurrency nang walang anumang karagdagang pagsisikap.

Nang magdesisyon ang pangkat ng TypeScript na i-port ang kanilang compiler sa isang bagong wika, mayroon silang malinaw na layunin: panatilihing gumagana ang lahat nang eksakto gaya ng dati. Nangangahulugan ito ng pagpapanatili ng eksaktong mga mensahe ng error at semantika na pinag-aralan ng mga developer sa loob ng maraming taon. Ayon kay Anders Hejlsberg, ang pangunahing arkitekto, hindi isinaalang-alang ang isang buong muling pagsusulat dahil manganib itong masira ang backward compatibility. Sa halip, pinili nila ang isang port—at ang desisyong iyon ang naghanda para sa isang nakakagulat na pagpipilian: Iwasan ang Rust.
Nangailangan ang port ng isang wika na kayang humawak sa masalimuot na panloob na istruktura ng compiler nang hindi pinipilit ang malalaking pagbabago. Mabilis na napagtanto ng team na ang garbage collection at mga primera klaseng pagsasara ay hindi maaaring pag-usapan. Nag-aalok ang Go ng parehong out-of-the-box, kasama ang mature native code generation at shared-memory concurrency sa bawat pangunahing platform. Sa kabilang banda, mangangailangan ang Rust ng mahahalagang manual workaround, lalo na para sa mga circular data structure ng compiler.
Bakit Mas Iiwasan ang Kalawang para sa Port
Ipinaliwanag ni Hejlsberg na ang compiler ay puno ng mga parent pointer, recursive type, at mga simbolo na tumutukoy sa isa't isa. Lumilikha ang mga ito ng mga pabilog na sanggunian na natural sa isang wikang may garbage collection. Maayos itong pinangangasiwaan ng runtime ng Go, na nagbibigay-daan sa team na tumuon sa port sa halip na labanan ang wika. Bagama't mabisa ang borrow checker ng Rust para sa kaligtasan ng memorya, hindi nito pinapayagan ang hugis na iyon nang hindi gumagamit ng hindi ligtas na code o mga trick sa pagbibilang ng sanggunian. Magdaragdag iyon ng pagiging kumplikado at panganib, nang walang malinaw na kabayaran.
Nang ikumpara ang dalawang wika, walang nakitang makabuluhang kalamangan ang pangkat sa pagbuo ng code o concurrency para sa Rust. Mature na ang pagbuo ng native code ng Go, at ang mga goroutine nito ay nagbibigay ng simple at epektibong modelo para sa sabay-sabay na pagpapatupad. Maaaring bahagyang mas mahusay ang performance ng Rust sa ilang mga edge case, ngunit hindi makatwiran ang karagdagang pagsisikap na kinakailangan upang mapagana ang compiler gamit ang mga ownership rule nito. Kailangang maging praktikal ang port, hindi isang pagpapakita ng mga feature ng wika.
Pagkakatugma at Semantika: Ang Pangunahing Prayoridad
Ang pangunahing dahilan sa likod ng port ay ang pagpapanatili ng magkaparehong gawi. Umaasa ang mga developer sa mga mensahe ng error ng TypeScript upang i-debug ang kanilang code, at ang anumang pagbabago ay maaaring makasira sa kanilang mga daloy ng trabaho. Sa pamamagitan ng pag-port sa Go, maaaring muling gamitin ng team ang mga umiiral na logic at data structure, na tinitiyak na ang output ay mananatiling tugma sa byte-for-byte. Binabawasan din ng pamamaraang ito ang panganib ng pagpapakilala ng mga banayad na bug na maaaring idulot ng isang muling pagsusulat.
Ang garbage collection ng Go ay isang mahalagang dahilan. Ang internal graph ng compiler ng mga node at reference ay lubos na magkakaugnay, at ang manual memory management ay magiging isang bangungot. Gamit ang Go, awtomatikong maa-allocate at mapapalaya ng team ang memory, na nagbibigay-daan sa kanila na tumuon sa logic ng compiler. Pinadali rin ng mga primera klaseng closure ang pagpapatupad ng iba't ibang pass at transformation na ginagawa ng compiler, dahil natural nilang nakukuha ang konteksto.
Rust's Borrow Checker: Isang Dealbreaker
Ang borrow checker ng Rust ay dinisenyo upang maiwasan ang mga data race at mga error sa memorya sa oras ng pag-compile, ngunit mayroon itong mahigpit na mga patakaran. Ang mga istruktura ng datos ng TypeScript compiler ay puno ng mga cycle at shared reference, na tinatanggihan ng borrow checker maliban kung gagamit ka ng mga unsafe block o Rc/RefCell. Nabanggit ni Hejlsberg na mapipilitan nito ang mga manual workaround para sa bawat circular data structure, na magdaragdag ng boilerplate at magpapahirap sa pagpapanatili ng code. Walang codegen o concurrency advantage upang bigyang-katwiran ang karagdagang trabahong iyon.
Sa huli, malinaw ang pagpipilian. Inialok ni Go ang tamang balanse ng pagiging simple, pagganap, at pagiging tugma. Sinisimulan na ngayon ang port, at tiwala ang koponan na maghahatid ito ng parehong karanasan sa TypeScript na may mas mabilis at mas mahusay na compiler. Para sa mga developer, nangangahulugan ito na walang sorpresa—kundi ang parehong maaasahang tool na lagi nilang ginagamit, na tumatakbo sa mas modernong pundasyon.
Kung isasaalang-alang ang lahat, ang desisyon na piliin ang Go kaysa sa Rust para sa TypeScript port ay bumababa sa praktikal na inhinyeriya. Ang pangangailangan para sa pagkolekta ng basura, mga de-kalidad na pagsasara, at maayos na paghawak ng mga pabilog na sanggunian ang naging dahilan upang maging natural ang Go. Kahanga-hanga ang mga garantiya sa kaligtasan ng Rust, ngunit may kaakibat itong halaga na hindi handang bayaran ng pangkat ng TypeScript. Ang resulta ay isang port na nagpapanatili ng lahat ng minamahal ng mga developer tungkol sa TypeScript habang inilalatag ang pundasyon para sa mga pagpapabuti sa hinaharap.