Skip to content

Optional Types

PyGo provides explicit nullability handling through the Type? syntax. Unlike Python’s None, which can be ambiguous (is it a missing value or an intentionally unset value?), PyGo’s Type? makes nullability explicit, compile-time checked, and transpiled consistently to both Go and Python.

model User:
name: String
nickname: String? # Optional (nullable), defaults to None
age: Int? # Optional (nullable), no default
updated: DateTime? # Optional DateTime
model User:
# This field MUST be provided (not nullable)
name: String
# This field can be null, defaults to None
nickname: String?
# This field can be null, must be explicitly provided
age: Int?
# This field has a default value but is NOT nullable
status: String = "active"

Go:

type User struct {
Name string // not nullable
Nickname *string // pointer for nullable (Optional)
Age *int // pointer for nullable (Optional)
Status string // not nullable, has default
Updated *time.Time // pointer for nullable DateTime
}

Python:

from typing import Optional
from datetime import datetime
class User(BaseModel):
name: str
nickname: Optional[str] = None
age: Optional[int]
status: str = "active"
updated: Optional[datetime] = None
CREATE TABLE user (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
nickname TEXT, -- NULL allowed (String?)
age INTEGER, -- NULL allowed (Int?)
status TEXT NOT NULL -- NULL not allowed (String = "active")
);
model Profile:
tags: Array[String]? # Optional array
metadata: Map[String, String]? # Optional map
config: Config? # Optional model reference

Optional fields are validated at compile time:

user = User(name="Alice", age=30)
# Valid — age is Int?, 30 is an Int
user.age = 31
# Valid — setting to None is always valid for Optional types
user.age = None
  • Use Type? explicitly when a field can be null
  • Use Type (without ?) when a field must always have a value
  • Always provide sensible defaults for optional fields where possible
  • Use String? rather than String = None for clarity
  • Prefer ? syntax over Optional[T] for new projects
# Old style (still supported, but not recommended)
name: Optional[String]
# New style (recommended)
name: String?

Both generate the same code — Go *T and Python Optional[T].