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

[kfetch] TypeScript-ify #20914

Merged
merged 7 commits into from
Jul 19, 2018
Merged

[kfetch] TypeScript-ify #20914

merged 7 commits into from
Jul 19, 2018

Conversation

spalger
Copy link
Contributor

@spalger spalger commented Jul 18, 2018

In order to make the awesome new kfetch api easier to consume in purely TypeScript projects, and since it's a pretty small module with very few dependencies, I converted it to TypeScript.

Along with kfetch I also started a type definition file for ui/chrome that we can extend as we go, but will likely be unnecessary after #19992

@spalger spalger added review Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.0.0 v6.4.0 labels Jul 18, 2018
@spalger spalger requested a review from sorenlouv July 18, 2018 05:49
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

* under the License.
*/

import Angular from 'angular';
Copy link
Member

Choose a reason for hiding this comment

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

I don't see Angular used here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, had another method typed but removed it because it was irrelevant

describe('kfetch', () => {
const matcherName = /my\/path/;
const matcherName: any = /my\/path/;
Copy link
Member

Choose a reason for hiding this comment

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

Can you use the RegExp type instead of any?

Copy link
Member

Choose a reason for hiding this comment

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

.. or actually, i'd just ditch the type. Typescript will infer it since it is static

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason any is necessary is that the types for fetch-mock insist that the matcherName must be a string. By casting the variable to any we bypass the checks, and since the tests won't pass if the matcher isn't working correctly I feel okay about using any here.

Copy link
Member

Choose a reason for hiding this comment

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

👍

// attempt to read the body of the response
return reject(new FetchError(res, await res.json()));
} catch (err) {
// ignore error if we are not be able to get body for response
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps update/remove this comment, since we no longer ignore the error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, we still ignore the err variable

@@ -29,7 +31,10 @@ function createAbortable() {
};
}

export function kfetchAbortable(fetchOptions, kibanaOptions) {
export function kfetchAbortable(
fetchOptions?: Omit<KFetchOptions, 'signal'>,
Copy link
Member

Choose a reason for hiding this comment

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

I'm probably reading this wrong but I don't understand the need for excluding signal. It's not part of KFetchOptions.

I'd expect fetchOptions: KFetchOptions to be fine - but maybe not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

KFetchOptions extends the default options for the global fetch API, which includes signal, which is why I've explicitly removed it from the type here (since we overwrite it)

Copy link
Member

@sorenlouv sorenlouv Jul 18, 2018

Choose a reason for hiding this comment

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

I see that the RequestInit interface has signal of type AbortSignal. The signal we are overwriting kibanaOptions with is also of type AbortSignal - so should be compatible.

I pulled your branch and removed the Omit part, and it still compiles. Haven't worked with TS for a while so I might be missing something.

Do you get a compile error if you remove the Omit part?

Copy link
Contributor Author

@spalger spalger Jul 19, 2018

Choose a reason for hiding this comment

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

Nope, the type described in the arguments should be the type that callers must match, it doesn't describe the type of the object we'll be passing to kfetch(). I'm just trying to remove the signal option so when a caller is looking at the options through intelisense or something they will see signal as an option for kfetch():

image

but not for kfetchAbortable():

image

Copy link
Member

Choose a reason for hiding this comment

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

Got it :) Thanks for the explanation.

@sorenlouv
Copy link
Member

sorenlouv commented Jul 18, 2018

Unrelated to this: I noticed we have three fetch polyfills in OSS and x-pack: node-fetch, whatwg-fetch and isomorphic-fetch.
isomorphic-fetch works in both Node and the browser so perhaps we can ditch the two others? Alternatively we should ditch isomorphic-fetch.

EDIT: at a closer look isomorphic-fetch just uses the two others under the hood, and the versions are fairly outdated: https://github.com/matthew-andrews/isomorphic-fetch/blob/master/package.json#L22-L23

So isomorphic-fetch should probably go - but that's for another PR.

Copy link
Member

@sorenlouv sorenlouv left a comment

Choose a reason for hiding this comment

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

A few nits and questions but overall looks really good. Awesome with types!

prependBasePath?: boolean;
}

export function kfetch(fetchOptions?: KFetchOptions, kibanaOptions?: KFetchKibanaOptions) {
Copy link
Member

Choose a reason for hiding this comment

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

fetchOptions should probably be required. Are there any cases where it makes sense to call kfetch() (without args)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only if you want to do a get request to "/", I'm not sure why I made it optional... I guess because it would work fine if it wasn't specified. I'll update it anyway.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@spalger spalger merged commit b434652 into elastic:master Jul 19, 2018
spalger pushed a commit to spalger/kibana that referenced this pull request Jul 19, 2018
In order to make the awesome new kfetch api easier to consume in purely TypeScript projects, and since it's a pretty small module with very few dependencies, I converted it to TypeScript.

Along with kfetch I also started a type definition file for `ui/chrome` that we can extend as we go, but will likely be unnecessary after elastic#19992
spalger pushed a commit that referenced this pull request Jul 19, 2018
In order to make the awesome new kfetch api easier to consume in purely TypeScript projects, and since it's a pretty small module with very few dependencies, I converted it to TypeScript.

Along with kfetch I also started a type definition file for `ui/chrome` that we can extend as we go, but will likely be unnecessary after #19992
@spalger
Copy link
Contributor Author

spalger commented Jul 19, 2018

6.x/6.4: 801e5c0

@spalger spalger deleted the ts/kfetch branch July 19, 2018 22:37
spalger pushed a commit to spalger/kibana that referenced this pull request Jul 19, 2018
As @sqren mentioned in elastic#20914 (comment) we are using three different fetch polyfills, and it's not totally clear which one is winning out. For some time `import 'whatwg-fetch'` has been included globally in the browser for the last 6 months or so, but wasn't compatible with jest tests running in node.js, which seems to be the reason people have been reaching for `isomorphic-fetch`. Rather than relying on the version of `whatwg-fetch` and `node-fetch` that `isomorphic-fetch` depends on, we can just rely on them directly and stub out the global fetch for jest tests in a jest setup module.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v6.4.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants