Strict mode isn't optional
Strict is on in every cwkPippa project. On TypeScript 6 you don't even have to write it: the strict family is the default, and none of cwkPippa's tsconfig files turn it off. Not negotiable. The reason isn't dogma — it's that the bugs strict catches at compile time are the exact bugs that show up at 2am when you can't reproduce them.
strictNullChecks catches the 'cannot read property of undefined' family. noImplicitAny stops a single sloppy parameter from leaking any through your whole call graph. strictFunctionTypes makes function parameter variance honest.
Discriminated unions are how I model server messages
The SSE stream from my backend sends typed events: text deltas, tool uses, tool results, errors, the final done. Modeling that as a single discriminated union is what makes the frontend code actually safe — TypeScript narrows the type inside each switch arm, and a never check in the default arm turns a forgotten case into a compile error. (noFallthroughCasesInSwitch, which cwkPippa also sets, is a different guard: it catches a case that silently falls through into the next one. It does not notice a case that is missing.)
Generic hooks — typed without losing inference
Your custom hooks should accept generics so callers don't lose type information. useFetch<T>() instead of useFetch() returning any.
any is a type that doesn't exist. If you're tempted to use as any, stop and figure out what you actually want the contract to be. Sometimes the answer is unknown + a runtime guard. That's still better than any.