Skip to content

Conversation

@bitgopatmcl
Copy link
Contributor

@bitgopatmcl bitgopatmcl commented Apr 5, 2022

Instead of never this should be something like the union of all
responses with any or unknown body.

Broken:
image

Fixed:
image

@bitgopatmcl bitgopatmcl force-pushed the fix-response-inference branch from ad533fa to f466304 Compare April 5, 2022 19:45
@bitgopatmcl bitgopatmcl marked this pull request as ready for review April 5, 2022 19:46
@bitgopatmcl bitgopatmcl requested a review from a team April 5, 2022 19:46
Instead of `never` this should be something like the union of all
responses with `any` or `unknown` body.
@bitgopatmcl bitgopatmcl force-pushed the fix-response-inference branch from f466304 to 81431c8 Compare April 5, 2022 19:47
@bitgopatmcl
Copy link
Contributor Author

This is primarily for correctness. The intention of ResponseType<thing> is to be used on a subtype of HttpResponse, but the boundary case should work.

@ericcrosson-bitgo
Copy link
Contributor

I scheduled a meeting to discuss this change in more detail; I think I'm too hazy on the specifics but I have a concern I'd love to run past you in a higher-bandwidth medium before approving

body: res.body,
original: res.original,
};
return res as ExpectedDecodedResponse<Route, StatusCode>;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

To be honest I actually don't know why the type of res isn't narrowed by control flow here. Maybe just because of some complexity limit?

Comment on lines 17 to 21
const ensureAllResponsesDefined = <T extends { [K in Status]: number }>(
responseCodes: T,
) => responseCodes;

export const HttpResponseCodes = ensureAllResponsesDefined({
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like a smell to use this identity function (with penalty in code size and execution time) to enforce a type-level relationship, what about using the following patch?

export const HttpResponseCodes = {
  ok: 200,
  invalidRequest: 400,
  unauthenticated: 401,
  permissionDenied: 403,
  notFound: 404,
  rateLimitExceeded: 429,
  internalError: 500,
  serviceUnavailable: 503,
} as const;

// Create a type-level assertion that the HttpResponseCodes map contains every key
// in the Status union of string literals, and no unexpected keys. Violations of
// this assertion will cause compile-time errors.
//
// Thanks to https://stackoverflow.com/a/67027737
type ShapeOf<T> = Record<keyof T, any>
type AssertKeysEqual<X extends ShapeOf<Y>, Y extends ShapeOf<X>> = never
type _AssertHttpStatusCodeIsDefinedForAllResponses = AssertKeysEqual<{ [K in Status]: number }, HttpResponseCodes>;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 311d8a0, but did it in a test file as an assignment check.

@bitgopatmcl bitgopatmcl force-pushed the fix-response-inference branch from 7d1eb57 to 311d8a0 Compare April 8, 2022 17:34
This changes the way that `HttpResponse` is declared. The language
server now offers actual helpful autocomplete suggestions, and type
inferencing behaves correctly as far as I can tell.
@bitgopatmcl bitgopatmcl force-pushed the fix-response-inference branch from 311d8a0 to 01f9c88 Compare April 11, 2022 22:39
Copy link
Contributor

@ericcrosson-bitgo ericcrosson-bitgo left a comment

Choose a reason for hiding this comment

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

Looks great 🙂

:shipit:

@bitgopatmcl bitgopatmcl merged commit 1eae9e7 into BitGo:master Apr 12, 2022
@bitgopatmcl bitgopatmcl deleted the fix-response-inference branch April 12, 2022 12:45
@github-actions
Copy link

🎉 This PR is included in version 1.0.0-beta.1 🎉

The release is available on npm package (@beta dist-tag)

Your semantic-release bot 📦🚀

@github-actions
Copy link

🎉 This PR is included in version 0.2.0-beta.1 🎉

The release is available on npm package (@beta dist-tag)

Your semantic-release bot 📦🚀

@github-actions
Copy link

🎉 This PR is included in version 0.1.1-beta.1 🎉

The release is available on npm package (@beta dist-tag)

Your semantic-release bot 📦🚀

@github-actions
Copy link

🎉 This PR is included in version 0.2.0-beta.1 🎉

The release is available on npm package (@beta dist-tag)

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants