@@ -72,6 +72,112 @@ Unknown keyword args and missing required args raise errors.
7272
7373If a return type is annotated, the returned value is checked. If omitted, no return check is enforced.
7474
75+ ## Migration examples
76+
77+ Use a boundary-first strategy: annotate entrypoints that receive external data, then tighten helpers and block callbacks.
78+
79+ ### 1) Start with function boundaries
80+
81+ Before:
82+
83+ ``` vibe
84+ def calculate_total(items)
85+ items.reduce(0) do |acc, item|
86+ acc + item[:amount]
87+ end
88+ end
89+ ```
90+
91+ After:
92+
93+ ``` vibe
94+ def calculate_total(items: array<{ amount: int }>) -> int
95+ items.reduce(0) do |acc: int, item: { amount: int }|
96+ acc + item[:amount]
97+ end
98+ end
99+ ```
100+
101+ ### 2) Migrate optional values with nullable or unions
102+
103+ Before:
104+
105+ ``` vibe
106+ def normalize_id(id)
107+ if id == nil
108+ "unknown"
109+ else
110+ id.string
111+ end
112+ end
113+ ```
114+
115+ After:
116+
117+ ``` vibe
118+ def normalize_id(id: int | string | nil) -> string
119+ if id == nil
120+ "unknown"
121+ else
122+ id.string
123+ end
124+ end
125+ ```
126+
127+ Use ` T? ` when the only optional case is ` nil ` , and use unions when multiple concrete kinds are allowed.
128+
129+ ### 3) Convert loose hashes to shape contracts
130+
131+ Before:
132+
133+ ``` vibe
134+ def reward(payload)
135+ { id: payload[:id], points: payload[:points] + 10 }
136+ end
137+ ```
138+
139+ After:
140+
141+ ``` vibe
142+ def reward(payload: { id: string, points: int }) -> { id: string, points: int }
143+ { id: payload[:id], points: payload[:points] + 10 }
144+ end
145+ ```
146+
147+ Shapes are strict. Missing or extra keys fail checks.
148+
149+ ### 4) Annotate block signatures where callbacks matter
150+
151+ Before:
152+
153+ ``` vibe
154+ def render_scores(scores)
155+ scores.map do |s|
156+ s + 1
157+ end
158+ end
159+ ```
160+
161+ After:
162+
163+ ``` vibe
164+ def render_scores(scores: array<int>) -> array<int>
165+ scores.map do |s: int|
166+ s + 1
167+ end
168+ end
169+ ```
170+
171+ Typed blocks catch callback mismatches at runtime with errors that include parameter name, expected type, and actual type.
172+
173+ ### 5) Roll out incrementally
174+
175+ - Add annotations to one high-value path first.
176+ - Keep internal helpers untyped until boundary contracts stabilize.
177+ - Use ` any ` as a temporary bridge during migration.
178+ - Replace ` any ` with concrete or shape types once call sites are clean.
179+ - Watch runtime type errors in staging, then tighten signatures further.
180+
75181## Time and Duration
76182
77183Duration methods like ` ago ` /` after ` return ` Time ` . Typed signatures use ` time ` or ` time? ` for those values.
0 commit comments