[{"data":1,"prerenderedAt":79},["ShallowReactive",2],{"entry-\u002Fprojects\u002Ftypescript-migration-en":3},{"entry":4,"writtenIn":77,"onlyIn":78},{"id":5,"title":6,"body":7,"date":59,"description":60,"extension":61,"meta":62,"navigation":63,"path":64,"role":65,"seo":66,"stack":67,"stem":71,"tags":72,"year":75,"__hash__":76},"content_en\u002Fprojects\u002Ftypescript-migration.md","TypeScript in a SAPUI5 codebase",{"type":8,"value":9,"toc":50},"minimark",[10,15,19,23,26,30,33,36,40,43,47],[11,12,14],"h2",{"id":13},"context","Context",[16,17,18],"p",{},"An internal SAPUI5 application used daily by a logistics team. Around forty controllers, six years of history, and three people maintaining it. Every screen had been written in plain JavaScript against the UI5 module system.",[11,20,22],{"id":21},"problem","Problem",[16,24,25],{},"The failures that reached production were almost never logic errors. They were shape errors: a field renamed on the OData service, a model path that no longer resolved, a controller reading a property the entity set had stopped returning. None of it was visible until someone opened the screen.",[11,27,29],{"id":28},"approach","Approach",[16,31,32],{},"Migration ran one folder at a time, with feature work continuing in parallel. Type definitions were generated from the service metadata rather than written by hand, so the OData contract stayed the single source of truth. Controllers were converted only when they were being touched for other reasons, which kept the diff of any one pull request reviewable.",[16,34,35],{},"The build stayed on the existing UI5 tooling. Introducing a second bundler would have meant maintaining two build paths for the length of the migration.",[11,37,39],{"id":38},"result","Result",[16,41,42],{},"Not measured against a baseline — no error tracking existed before the migration, so any before-and-after number would be invented. What is observable: renames on the service now fail the build instead of a screen, and the three shape errors found during conversion had all been live in production.",[11,44,46],{"id":45},"lesson","Lesson",[16,48,49],{},"Generating types from the service metadata mattered more than the migration itself. Hand-written interfaces would have drifted from the backend within a release, and a type that lies is worse than no type at all.",{"title":51,"searchDepth":52,"depth":52,"links":53},"",2,[54,55,56,57,58],{"id":13,"depth":52,"text":14},{"id":21,"depth":52,"text":22},{"id":28,"depth":52,"text":29},{"id":38,"depth":52,"text":39},{"id":45,"depth":52,"text":46},"2026-05-12","A gradual migration of a large SAPUI5 application to TypeScript, done without a freeze on feature work.","md",{},true,"\u002Fprojects\u002Ftypescript-migration","Frontend engineer",{"title":6,"description":60},[68,69,70],"SAPUI5","TYPESCRIPT","NODE","projects\u002Ftypescript-migration",[73,74],"sapui5","typescript","2025 — 2026","UhbRaPUUHMvT8a2xIGcTX6VotUAmMwlEO2RWADt4Zi0","en",null,1788956392544]