Skip to content

change type assignments to interfaces for augmentation purposes#58753

Merged
typescript-bot merged 4 commits intoDefinitelyTyped:masterfrom
cwadrupldijjit:ws/convert-type-assignment-to-interface
Feb 19, 2022
Merged

change type assignments to interfaces for augmentation purposes#58753
typescript-bot merged 4 commits intoDefinitelyTyped:masterfrom
cwadrupldijjit:ws/convert-type-assignment-to-interface

Conversation

@cwadrupldijjit
Copy link
Copy Markdown
Contributor

Motivations for this change

I sought to augment the WebSocket implementation for a project I'm working on and I discovered that because of the type assignments (such as the type WebSocket = WebSocketAlias;) made such a thing impossible. I imagine some implementations with WS could benefit from type augmentation, similar to how Express handles the Request and Response objects.

PR Checklist

If changing an existing definition:

  • Provide a URL to documentation or source code which provides context for the suggested changes: N/A (implementation of WS is the same, type definition is tweaked slightly with no breaking changes)
  • If this PR brings the type definitions up to date with a new version of the JS library, update the version number in the header. (Also N/A)

@typescript-bot
Copy link
Copy Markdown
Contributor

typescript-bot commented Feb 13, 2022

@cwadrupldijjit Thank you for submitting this PR! I see this is your first time submitting to DefinitelyTyped 👋 — I'm the local bot who will help you through the process of getting things through.

This is a live comment which I will keep updated.

1 package in this PR

@cwadrupldijjit: I see that you have added yourself as an owner, are you sure you want to become an owner?

Code Reviews

Because this is a widely-used package, a DT maintainer will need to review it before it can be merged.

You can test the changes of this PR in the Playground.

Status

  • ✅ No merge conflicts
  • ✅ Continuous integration tests have passed
  • ✅ Most recent commit is approved by a DT maintainer

All of the items on the list are green. To merge, you need to post a comment including the string "Ready to merge" to bring in your changes.


Diagnostic Information: What the bot saw about this PR
{
  "type": "info",
  "now": "-",
  "pr_number": 58753,
  "author": "cwadrupldijjit",
  "headCommitOid": "954895b186ea07c982148461f3ffbed0e729f5aa",
  "mergeBaseOid": "7dec77e4522d220346c90fcd09044e78feb49dd0",
  "lastPushDate": "2022-02-18T17:49:04.000Z",
  "lastActivityDate": "2022-02-19T02:53:47.000Z",
  "mergeOfferDate": "2022-02-18T23:37:44.000Z",
  "mergeRequestDate": "2022-02-19T02:53:47.000Z",
  "mergeRequestUser": "cwadrupldijjit",
  "hasMergeConflict": false,
  "isFirstContribution": true,
  "tooManyFiles": false,
  "hugeChange": false,
  "popularityLevel": "Critical",
  "pkgInfo": [
    {
      "name": "ws",
      "kind": "edit",
      "files": [
        {
          "path": "types/ws/index.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/ws/ws-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "loyd",
        "mlamp",
        "TitaneBoy",
        "reduckted",
        "teidesu",
        "wojtkowiak",
        "k-yle"
      ],
      "addedOwners": [
        "cwadrupldijjit"
      ],
      "deletedOwners": [],
      "popularityLevel": "Critical"
    }
  ],
  "reviews": [
    {
      "type": "approved",
      "reviewer": "andrewbranch",
      "date": "2022-02-18T23:37:04.000Z",
      "isMaintainer": true
    },
    {
      "type": "approved",
      "reviewer": "k-yle",
      "date": "2022-02-18T20:35:11.000Z",
      "isMaintainer": false
    },
    {
      "type": "approved",
      "reviewer": "vansergen",
      "date": "2022-02-18T19:35:12.000Z",
      "isMaintainer": false
    },
    {
      "type": "stale",
      "reviewer": "doroodgar",
      "date": "2022-02-17T12:27:57.000Z",
      "abbrOid": "d2c6c9f"
    }
  ],
  "mainBotCommentID": 1037950088,
  "ciResult": "pass"
}

@typescript-bot typescript-bot added Edits Owners This PR adds or removes owners Critical package labels Feb 13, 2022
@typescript-bot
Copy link
Copy Markdown
Contributor

🔔 @loyd @mlamp @TitaneBoy @reduckted @teidesu @wojtkowiak @k-yle — please review this PR in the next few days. Be sure to explicitly select Approve or Request Changes in the GitHub UI so I know what's going on.

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

Note: The second check through Azure DevOps seems to have failed due to TypeScript not being where it was expected, which doesn't have anything to do with my changes.

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

Also another note: The dtslint cli was having issues when I ran it either directly or with npm test ws. It goes up a level from the project root to look for the notNeededPackages.json, which naturally doesn't exist there. Running the test all script, it worked correctly. I will have to create an issue in the dtslint repo to ask about it or suggest a change.

Copy link
Copy Markdown
Contributor

@k-yle k-yle left a comment

Choose a reason for hiding this comment

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

Thanks. Do we still need this if #58772 is merged? Also note that #58555 is yet another approach to solving this issue.

cc @mglyzin and @lavalleeale

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

cwadrupldijjit commented Feb 14, 2022

I'd think both approaches could work simultaneously. In my case, I don't want to create a custom WebSocket class to use instead. I just would augment the original WebSocket slightly.

To be fair, I could create a new class, but if it's only for adding a single property, that feels like a little much.

But I could also swallow my pride and do it that way instead if that's just how it should be. Interested to hear others weigh in on this to see if it's necessary.

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

Though thinking back to the other two PRs, the one that looks like it would do closer to what I want would be #58772. The other seems to make sense, too. Those coincide fine.

But I might also note that my approach doesn't change the original class (such as if you import default or import..require) but does change the type found as a namespaced item on that imported object (as far as I can tell).

Example:

// these can't be augmented
import WebSocket = require('ws');
import WebSocket from 'ws';

// these, however, can
import { WebSocket } from 'ws';
import * as wslib from 'ws';
declare const websocket: wslib.WebSocket;

In my case, since I'm never creating a ws object via the class constructor call, importing the type from the package seems to work just fine. It augments everywhere that I've tried it so far.

@k-yle
Copy link
Copy Markdown
Contributor

k-yle commented Feb 15, 2022

But I could also swallow my pride and do it that way instead if that's just how it should be.

The discussion in websockets/ws#2007 suggests that both approaches are valid

I'd think both approaches could work simultaneously.

I think you're right, we should go ahead with this PR and #58772, which would make #58555 redundant (unless I'm misunderstanding the benefit of that PR?)

@lavalleeale
Copy link
Copy Markdown
Contributor

I think the approach in #58555 would be better unless someone wants to make a single pull request that combines this and #58772?

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

I'd say that the this argument in #58555 makes a little more sense from an implementation standpoint, because in theory, that allows the class-based syntax to work fine, too (as seen in #58772). The only thing that might not be the case is if somehow, the original WebSocket implementation is the only value that comes through instead of the custom class. It also promotes better typings by allowing for the dynamicism of this over just the WebSocket implementation.

The result of mine is more related to adding to the original structure of the WebSocket objects instead of creating a new type to handle it. The this: this reference would still handle it just as well as leaving it as this: WebSocket, I believe, so it doesn't fully negate the use of it.

I'm also personally for more flexibility than anything. I don't think any of those approaches are "wrong", though I think that the use cases for each approach might vary.

Prefer to use your own WebSocket class? That's available for you. Want to fix the type of the this keyword to make more sense? That's also available for you. Just want to augment each time a WebSocket is used to add minimal properties to it? That also works.

Does that sound reasonable to you @k-yle and @lavalleeale?

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

Since I anticipate there will be merge conflicts between the three for the tests, I'm willing to merge both of your branches into mine, fix the merge conflicts, and update this PR with those changes, if that makes sense and works for you. Or I'm willing to be the last one to deal with those in my code if you'd prefer.

@lavalleeale
Copy link
Copy Markdown
Contributor

I think that sounds all good to me as long as the tests reflect all of the use cases

@vansergen
Copy link
Copy Markdown
Contributor

Do we really need tests here?🤔 Otherwise LGTM

Comment on lines +317 to +330

declare module 'ws' {
interface WebSocket {
id?: string;
}
}

{
const ws: wslib.WebSocket = new wslib.WebSocket('ws://www.host.com/path');

// $ExpectType string | undefined
ws.id;
ws.id = 'foo';
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
declare module 'ws' {
interface WebSocket {
id?: string;
}
}
{
const ws: wslib.WebSocket = new wslib.WebSocket('ws://www.host.com/path');
// $ExpectType string | undefined
ws.id;
ws.id = 'foo';
}

Module augmentation is the feature in TypeScript. I do not think that there is a need to test explicitly, like

declare module 'ws' {
    interface WebSocket {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

True, it's a feature in TypeScript, but if it's ever changed back to a type assignment, then that test would fail. If the test isn't necessary, fine with me.

Perhaps I should put together another test next to it showing that the type would prevent augmentation?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

but if it's ever changed back to a type assignment, then that test would fail.

Agree, but the owners of the package would not allow that (I think) because of what we discuss here. I would just leave the test here to explain the motivation of this PR (as an example of usage).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I this test is worth keeping in case someone tries to change this back to a type assignment. A comment linking to this PR would be helpful but not required.

@cwadrupldijjit, do you want to merge this PR first, as it is now? I'm happy to approve this now and deal with conflicts in the other two PRs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm fine with that. I don't mind which order things are merged together. I'm also fine with helping to deal with the merge conflicts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this test is worth keeping in case someone tries to change this back to a type assignment.

Let's keep it if this is the concern. Is something else blocking this PR from merging?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since we want to keep the test to prevent changing interface to type, we should add a test for the Server class as well (for consistency).

@cwadrupldijjit Could you consider adding it? Something like

declare module 'ws' {
    interface Server {
        id?: string;
    }
}
{
    const ws = new wslib.Server({});
    // $ExpectType string | undefined
    ws.id;
    ws.id = 'foo';
}

should be enough.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@vansergen, that's a great point. Let me add that real quick.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've adjusted the test to include a server augmentation, too. Could you, @vansergen and @k-yle, review it and see if it looks good to you?

@typescript-bot typescript-bot added the Other Approved This PR was reviewed and signed-off by a community member. label Feb 17, 2022
@typescript-bot typescript-bot added The CI failed When GH Actions fails and removed Other Approved This PR was reviewed and signed-off by a community member. labels Feb 18, 2022
@typescript-bot
Copy link
Copy Markdown
Contributor

@cwadrupldijjit The CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

Note: builds which are failing do not end up on the list of PRs for the DT maintainers to review.

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

Alas... A blank line that broke the CI...

@typescript-bot typescript-bot removed the The CI failed When GH Actions fails label Feb 18, 2022
@typescript-bot
Copy link
Copy Markdown
Contributor

@vansergen, @k-yle, @doroodgar Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review?

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

My heart about stopped when I thought that all of the checks failed again, even though I watched the GitHub action run to successful completion...

Sigh of relief when I refreshed the page and saw that it said all checks had passed.

Copy link
Copy Markdown
Contributor

@vansergen vansergen left a comment

Choose a reason for hiding this comment

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

LGTM

@typescript-bot
Copy link
Copy Markdown
Contributor

@k-yle, @doroodgar Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review?

@typescript-bot typescript-bot added the Other Approved This PR was reviewed and signed-off by a community member. label Feb 18, 2022
Copy link
Copy Markdown
Contributor

@k-yle k-yle left a comment

Choose a reason for hiding this comment

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

thanks again

@typescript-bot
Copy link
Copy Markdown
Contributor

@doroodgar Thank you for reviewing this PR! The author has pushed new commits since your last review. Could you take another look and submit a fresh review?

@typescript-bot typescript-bot added the Owner Approved A listed owner of this package signed off on the pull request. label Feb 18, 2022
@typescript-bot typescript-bot added Maintainer Approved Self Merge This PR can now be self-merged by the PR author or an owner labels Feb 18, 2022
@typescript-bot
Copy link
Copy Markdown
Contributor

@cwadrupldijjit: Everything looks good here. I am ready to merge this PR (at 954895b) on your behalf whenever you think it's ready.

If you'd like that to happen, please post a comment saying:

Ready to merge

and I'll merge this PR almost instantly. Thanks for helping out! ❤️

(@loyd, @mlamp, @TitaneBoy, @reduckted, @teidesu, @wojtkowiak, @k-yle: you can do this too.)

@cwadrupldijjit
Copy link
Copy Markdown
Contributor Author

Ready to merge

@typescript-bot typescript-bot merged commit 6fd002b into DefinitelyTyped:master Feb 19, 2022
@cwadrupldijjit cwadrupldijjit deleted the ws/convert-type-assignment-to-interface branch February 19, 2022 04:21
martin-badin pushed a commit to martin-badin/DefinitelyTyped that referenced this pull request Feb 23, 2022
…s for augmentation purposes by @cwadrupldijjit

* change type assignments to interfaces for augmentation purposes

* fix tests for expected type for augmentation and no-empty-interfaces

* add server augmentation test

* Remove the failing blank line
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Critical package Edits Owners This PR adds or removes owners Maintainer Approved Other Approved This PR was reviewed and signed-off by a community member. Owner Approved A listed owner of this package signed off on the pull request. Self Merge This PR can now be self-merged by the PR author or an owner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants