#[1]gnikyt feed [2]gnikyt Code ramblings. Type definitions without emitting /* Feb 07, 2024 — 3.4KB */ Introduction A Shopify-based project was assigned which was a backend app with frontend extensions. After completion of the backend, it was realized that the frontend extensions needed types from the backend. Extensions with Shopify’s setup does not allow importing relative packages. For example, if this was the loose structure: - app/ - paginate/ index.ts index.test.ts - value/ amount.ts amount.test.ts id.ts id.test.ts - [etc] - extensions/ - order-stats/ - src/ BlockExtension.tsx - [etc] - [etc] We would not be able to do something such as: // extensions/order-stats/src/BlockExtension.tsx import { type PaginatedRecords } from "../../../app/paginate"; import { type ShopifyOrderIdValue } from "../../../app/value/id"; This would produce an error and not compile. You could copy/paste the type definitions into the extension manually, but this is not a great idea.. what if the types you’re importing change? They would be out of sync if you did not manually correct it. A solution is to generate types based upon the app into a local package which the extensions can use. types package Create a directory at the root called types, then cd inside and run npm init. Once done, you should have a package.json inside similar to this: { "name": "app-types", "private": true, "version": "1.0.0" } In my case, I named the package app-types, but you’re free to name as you please. Generation Create a bin/app-typegen with the following contents: #!/usr/bin/env bash # List the files you would like to generate types for srcs=("paginate/index" "value/id", "value/amount") for src in "${srcs[@]}"; do # Generation to the types/ directory tsc -d "app/$src.ts" --declarationDir types # Remove Typescript-generated .js files for file in $(git status -s); do if [[ $file == *"app/"* ]] && [[ $file == *".js"* ]]; then rm "$file" fi done done What this script does is allow you to list out the files you would like to generate types for. It will then utilize tsc to generate the types and dump the d.ts files into the types directory we previously created. Next, it will check the status of git to remove the generated Javascript files as there appears to be no way to not emit Javascript files during generation. Additionally, you can add a slot into your root package.json scripts: "generate:app-types": "bin/app-typegen" Then, you can simply run npm run generate:app-types manually or with your CI setup to (re)generate the types. Importing Modify the package.json for the package you would like to use the types. In my case, extensions/order-stats/package.json. Adding, "app-types": "file:../../../types" to devDependencies, then running npm install. Now, you’ll be able to import the types without compilation errors or warnings as such: // extensions/order-stats/src/BlockExtension.tsx import { type PaginatedRecords } from "app-types/paginate/index"; import { type ShopifyOrderIdValue } from "app-types/value/id"; [3]MD | [4]TXT | [5]CC-4.0 __________________________________________________________________ [6]Ty King Ty King A self-taught, seasoned, and versatile developer from Newfoundland. Crafting innovative solutions with care and expertise. [7]Github [8]About Me [9]CV [10]RSS * * * * * * * * * * References Visible links: 1. /rss.xml 2. / 3. /type-definitions-without-emitting/index.md 4. /type-definitions-without-emitting/index.txt 5. https://creativecommons.org/licenses/by/4.0/ 6. /about 7. https://github.com/gnikyt 8. /about 9. /assets/files/cv.pdf 10. /rss.xml Hidden links: 12. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb2-1 13. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb2-2 14. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb2-3 15. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb2-4 16. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb3-1 17. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb3-2 18. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb3-3 19. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb3-4 20. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb3-5 21. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-1 22. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-2 23. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-3 24. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-4 25. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-5 26. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-6 27. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-7 28. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-8 29. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-9 30. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-10 31. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-11 32. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-12 33. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-13 34. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb4-14 35. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb5-1 36. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb6-1 37. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb6-2 38. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb6-3 39. localhost/tmp/lynxXXXX4vxTUx/L373468-1120TMP.html#cb6-4