Skip to content

Respect X-TypeScript-Types header for remote imports #38864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
5 tasks done
danprince opened this issue May 31, 2020 · 4 comments
Closed
5 tasks done

Respect X-TypeScript-Types header for remote imports #38864

danprince opened this issue May 31, 2020 · 4 comments
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript

Comments

@danprince
Copy link

Search Terms

  • X-TypeScript-Types
  • Pika CDN / UNPKG
  • Remote types

Suggestion

The TypeScript compiler could respect the X-TypeScript-Types header when pointing to a remote import.

For example:

import * as Redux from "https://cdn.pika.dev/redux";

Right now, the compiler will be unable to resolve the module path and I won't get any type safety, despite the fact that the HTTP response comes with a X-TypeScript-Types header that can be used to find the declarations for that module.

The header has been implemented in Pika in anticipation of Deno (and similar work is being done in UNPKG unpkg/unpkg#243), but I think it would be great if TypeScript itself would download, cache and resolve the declarations too.

Use Cases

Lots of my projects use UNPKG/Pika directly and they're written and shipped in modern JS as ES Modules. I use TypeScript declaration files and the JSDoc syntax extensively to maintain type safety without introducing a source transform step.

If I want type safety for third party modules, I have three options.

  1. Download the module with npm and use paths to alias the remote url to the local declarations
  2. Download the module with npm and use a declaration file to declare module "https://..." { export * from "..." } (this doesn't always work depending on how the module is authored)
  3. Write the types by hand

The options that involve downloading the types through npm also require additional overhead in ensuring that the versions are matching at all times.

Examples

This would be used to write TypeScript without relying on npm. It would also help reduce friction with the Deno community.

Here's a rough sketch of the expected behaviour.

  • The TypeScript compiler sees an import to https://cdn.pika.dev/[email protected]
  • The compiler checks whether the types for that remote url have already been cached (not sure where makes most sense to cache yet, if the url is versioned then it might be possible to cache globally otherwise a project local cache makes more sense).
  • If the device is offline and no cached version is found, then compiler can warn that the types can't be fetched and the import can be treated as any.
  • If the device is online, then it should fetch the url
    • The response includes the X-TypeScript-Types header with a value of /-/[email protected]/dist=es2019,mode=types/index.d.ts
    • The compiler downloads that file and parses it
    • Each referenced module also needs to be downloaded and parsed
    • Once all of the module dependencies are downloaded, add the declarations to the cache.

I would recommend that if implemented, this feature would be locked behind a compiler option. Having the compiler access the network would be an unwelcome surprise if you weren't expecting it.

I also appreciate that putting a networking component into the compiler in the first place might be considered too complex to justify what is an uncommon use case right now, but as support for ES Modules continues to improve and more developers start to use the Deno toolchain, I think we'll see remote imports become far more common. It would be nice if they 'just worked' in TypeScript too.

I also think this could be implemented as a proof of concept in a third party CLI tool as a first step. Eventually I'd prefer to see it as out of the box behaviour in TypeScript itself, but having a fetch-remote-types command that did the same process would be a useful stop-gap. It'd just be frustrating to have to run it whenever an import changed.

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, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@MartinJohns
Copy link
Contributor

MartinJohns commented May 31, 2020

Looks like a duplicate of #35749 to me. Search terms used: import url

@danprince
Copy link
Author

Thanks @MartinJohns! Should have been broader with my search terms.

More than happy to have this issue closed/merged if adding support for a X-TypeScript-Types header ends up being an implementation detail for a broader strategy in making URI imports work.

@RyanCavanaugh RyanCavanaugh added Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript labels Jun 10, 2020
@RyanCavanaugh
Copy link
Member

TS doesn't download URL imports at all so inspecting headers in the response is putting the cart pretty far ahead of the horse. We can revisit this if we started loading resources from the network.

@Jack-Works
Copy link
Contributor

Now TS server will download @types from npm in the background. I think it is also possible to do this for browsers and deno (redirect types to local deno cache behind the scene).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants