I spent some time and finally figured out the solution.
Note the difference between the paths in the tsconfig.json file and the alias in the babel.config.js file. The module resolver automatically adds a slash after the @ character, then uses it to generate a regular expression /^@(\/.*|)$/ to match the import path.
So if we add a slash after @ in the alias (@/), the module resolver can't match (using /^@\/(\/.*|)$/) the import path.
For example, if we have the following directory structure: