How to write path resolutions for assets that require declarations and open the implementation

179 views Asked by At

In typescript, is there a way to resolve asset (pngs,svgs...etc) files that require declarations and keep path validation?

The Problem

  1. With a relative path import the Spinner.svg will show multiple definitions but resolve the declaration over navigating you to the file. No path validation for typos or level
  2. With a path alias using paths in tsconfig.json, it will not resolve any files and only show the declaration file with the .svg definitions.
  3. Invalid imports silently pass.

Example with SVG assets in a React Project

file directory structure:

  • src
  • src/assets.d.ts
  • src/assets
  • src/assets/Spinner.svg
  • src/component/Component.tsx

For typescript to directly import a svg|png|jpg or other asset unsupported assets, you have to write a custom declaration file.

Example with react + react-native-svg

declare module '*.svg' {
  const content: React.FC<React.SVGAttributes<SVGElement>>
  export default content
}

tsconfig.json file with assets as a path alias.

{
  "compilerOptions": {
    "esModuleInterop": true,
    "isolatedModules": true,
    "jsx": "react",
    "lib": ["ES2023"],
    "moduleResolution": "node",
    "noEmit": true,
    "strict": true,
    "strictNullChecks": true,
    "resolveJsonModule": true,
    "target": "esnext",
    "baseUrl": "./",
    "paths": {
      "assets/*": ["src/assets/*"]
    }
  },
  "include": ["src/**/*"],
  "exclude": [
    "node_modules",
    "babel.config.js",
    "metro.config.js",
    "jest.config.js"
  ]
}

Example typescript imports in Component.tsx


// opens a definitions window and shows both the relative path import and declaration file
import ../assets/Spinner.svg

// Only resolve the assets.d.ts file
import assets/Spinner.svg

// bad imports that do not error (until runtime)
import ../assets/Spinner1.svg
import ../assets/123/Spinner.svg

Hoping for the following solution(s):

  1. Path validation works and redirects the IDE to the asset implementation file (IE the file with the actual asset data).
  2. VSCode (and other IDEs) can validate that the path is valid.
  3. Works in CI so those paths can be validated to exist.

The solution does not need to be scoped directly towards tsconfig.json or declarations but that would be optimal.

Alternatives

  1. Use a scoped path and only resolve .svg from that scoped path.
  • prevents path level import issues
  • still has potential to fail with typos in a filename.

Example declaration

declare module 'assets/*.svg' {
  const content: React.FC<React.SVGAttributes<SVGElement>>
  export default content
}
  1. Create / Add a plugin that resolves paths in IDE
0

There are 0 answers