Skip to content

Collections

Targo has two different collection families:

  • Go-native collections such as slice<T>, map<K, V>, Fixed<T, N>, and chan<T>
  • Runtime-backed collections such as Array<T>, Map<K, V>, and Set<T>

Choosing the right one matters for semantics, ergonomics, and performance.

Quick Selection

Use casePrefer
Go-style dynamic sequenceslice<T>
JS-style methods like map() or filter()Array<T>
Go-native key-value mappingmap<K, V>
Ordered map with JS-style helpersMap<K, V>
Ordered set with JS-style helpersSet<T>
Fixed-size arrayFixed<T, N>
Goroutine communicationchan<T>

slice<T>

  • Go-native dynamic collection
  • Best fit for low-overhead code and Go interop
  • Use slice.make, slice.append, slice.copy
  • Prefer this for most core logic
typescript
const nums = slice.of<int>(1, 2, 3);
const buffer = slice.make<byte>(1024);
const grown = slice.append(nums, 4, 5);

Array<T> / T[]

  • Supported runtime-backed collection
  • Use this when you explicitly want methods such as push, map, filter, or reduce
  • Also supports Array.of(...) and Array.make(...) constructor helpers
  • Do not assume every slice<T> operation has the same ergonomics as Array<T>

map<K, V> (Go-native)

  • Maps to Go maps
  • Prefer this when you want plain Go map semantics
  • Model set-like data with map<T, bool> when needed

Lookup Patterns

When the API is documented as @comma-ok, treat the first result as a value that may be absent and the second result as the explicit presence flag.

typescript
const [value, ok] = users.Get(id);
if (!ok) {
  return [zero<User>(), new Error("user not found")];
}
return [value, null];
typescript
const [rawPort, ok] = ports.Get(name);
const port = ok ? rawPort : 0;

Comma-Ok Guidance

  • comma-ok is the Go-style "value plus presence flag" pattern.
  • Prefer the explicit boolean result when absence matters.
  • Do not model comma-ok lookups as JavaScript undefined checks first and only later recover the presence signal.

Map<K, V> (Runtime-backed)

  • Ordered runtime-backed map with JS-style methods
  • Supports set, get, has, delete, clear, size, keys, values, forEach, entries, and for...of
  • Map.get(key) returns V | undefined; checker and compiler treat it as a @comma-ok lookup pattern
  • Choose this when you want the JS-like method surface with ordered iteration

Set<T> (Runtime-backed)

  • Ordered runtime-backed set
  • Supports add, has, delete, clear, size, values, forEach, and for...of

WeakMap<K, V> / WeakSet<T>

  • Runtime-backed weak collections for object keys
  • Use only when you specifically need weak-reference semantics

Fixed<T, N>

  • Maps to fixed-size Go arrays
  • Useful when size is part of the type contract

chan<T>

  • Use it for Go-style concurrency
  • Pair it with go(() => { ... })
  • Use select-style coordination through switch (chan.$select)
  • See concurrency.md for detailed usage patterns

Practical Distinction

  • Choose Array<T>, Map<K, V>, or Set<T> when you want the JS-like method surface.
  • Choose slice<T> or map<K, V> when the code is primarily Go-shaped and interop-heavy.

Common Mistakes

  • Using Array<T> everywhere out of TypeScript habit instead of choosing slice<T> when Go-native behavior is the better fit.
  • Expecting slice<T> to expose the same method surface as Array<T>.
  • Reaching for JavaScript Map or Set patterns before checking whether the current API is a Go-shaped comma-ok lookup.
  • Confusing Go-native map<K, V> with runtime-backed Map<K, V>.