microsoft / microsoft/TypeScript
Support resolving types from import specifiers using custom schemes
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.4k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 117
Description
Suggestion
I can fully appreciate the complexities in type resolution, so applying more things on top is likely... undesired, but thought I'd present this anyways just in case.
In some environments, especially Rollup, it is common to use custom import schemes (import ... from 'example:...') to denote modules that should use a specialized loader (Webpack before v5 used to similarly recommend 'example!...', but that looks to have gone out of fashion). Unfortunately, if these modules do not share a common interface, it is quite difficult to support this in TypeScript, as, as best as I can tell, it would require generating .d.ts entries for every single module.
This is a type resolution-only issue, the built output should not be altered at all.
🔍 Search Terms
import schema scheme protocol
✅ Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
⭐ Suggestion
Depending on the specifics of supported schemes already (such as node:), perhaps it's possible to allow some method of simply ignoring the scheme? So that example:<anything> resolves to <anything>; node:fs could resolve types from fs, and example:./myModule could resolve from ./myModule. This is likely to introduce issues in the future, however, if Node (or any other equivalent) introduces something that mandates a schema, so probably not viable.
Alternatively, perhaps the paths option could be altered to support this, including some way of using relative specifiers without resolving against baseUrl. This should follow standard relative import semantics, just ignore the scheme. I'm not quite sure what that would look like, though I suppose the following probably isn't breaking, as it is not allowed at the moment?
{
"compilerOptions": {
"paths": {
"example:*": "*"
}
}
}
Very much open to ideas/suggestions.
📃 Motivating Example
It will allow for TS to support transparent loaders that have become commonplace in many bundler ecosystems. It can replace a good deal of code gen when dealing with file types that TS can retrieve types from directly.
💻 Use Cases
Use: In an ideal world, I could (maybe alongside some configuration) write import { something } from 'example:./myModule'; and have TS correctly retrieve the types for something from myModule directly (if it can), without needing to create a declaration file/entry. This allows me to specify custom loaders that should be used on these modules without giving up TypeScript support.
Shortcomings: TS is simply not supported whilst doing this at the moment. While you could generate .d.ts files/entries for each module, this is simply not viable in my experience and is way too much overhead. Potential type issues at the module boundary are cheaper than TS appeasement.
Workarounds: None that are viable long-term, in my experience.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by studying TypeScript's type-resolution behavior for import specifiers and the issue's proposed paths configuration. Compare custom schemes such as example:./myModule and node:fs with the suggested resolution approaches. Done means reaching an agreed design and implementing it without changing emitted JavaScript.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100