-
-
Notifications
You must be signed in to change notification settings - Fork 935
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
TypeScript cannot figure out which Got type to use #954
Comments
I don't understand the example. The URL is invalid. |
Sorry was being too terse. There would be a bunch of properties and a valid url passed to options, there just isn't a good type to import and use. |
const options: GotOptions = {
url: 'https://example.com'
}; This is correct. The example: const response = await got(options); fails because it tries to use <T>(url: string | Merge<Options, {isStream: true}>, options?: Merge<Options, {isStream: true}>): ProxyStream<T>; instead of <T = string>(url: string | OptionsOfDefaultResponseBody, options?: OptionsOfDefaultResponseBody): CancelableRequest<Response<T>> The Got interface looks like: export type OptionsOfDefaultResponseBody = Merge<Options, {isStream?: false; resolveBodyOnly?: false; responseType?: 'default'}>;
type OptionsOfTextResponseBody = Merge<Options, {isStream?: false; resolveBodyOnly?: false; responseType: 'text'}>;
type OptionsOfJSONResponseBody = Merge<Options, {isStream?: false; resolveBodyOnly?: false; responseType: 'json'}>;
type OptionsOfBufferResponseBody = Merge<Options, {isStream?: false; resolveBodyOnly?: false; responseType: 'buffer'}>;
type ResponseBodyOnly = {resolveBodyOnly: true};
interface GotFunctions {
// `asPromise` usage
<T = string>(url: string | OptionsOfDefaultResponseBody, options?: OptionsOfDefaultResponseBody): CancelableRequest<Response<T>>;
(url: string | OptionsOfTextResponseBody, options?: OptionsOfTextResponseBody): CancelableRequest<Response<string>>;
<T>(url: string | OptionsOfJSONResponseBody, options?: OptionsOfJSONResponseBody): CancelableRequest<Response<T>>;
(url: string | OptionsOfBufferResponseBody, options?: OptionsOfBufferResponseBody): CancelableRequest<Response<Buffer>>;
// `resolveBodyOnly` usage
<T = string>(url: string | Merge<OptionsOfDefaultResponseBody, ResponseBodyOnly>, options?: Merge<OptionsOfDefaultResponseBody, ResponseBodyOnly>): CancelableRequest<T>;
(url: string | Merge<OptionsOfTextResponseBody, ResponseBodyOnly>, options?: Merge<OptionsOfTextResponseBody, ResponseBodyOnly>): CancelableRequest<string>;
<T>(url: string | Merge<OptionsOfJSONResponseBody, ResponseBodyOnly>, options?: Merge<OptionsOfJSONResponseBody, ResponseBodyOnly>): CancelableRequest<T>;
(url: string | Merge<OptionsOfBufferResponseBody, ResponseBodyOnly>, options?: Merge<OptionsOfBufferResponseBody, ResponseBodyOnly>): CancelableRequest<Buffer>;
// `asStream` usage
<T>(url: string | Merge<Options, {isStream: true}>, options?: Merge<Options, {isStream: true}>): ProxyStream<T>;
} And if we do: type CorrectGotType = <T = string>(url: string | OptionsOfDefaultResponseBody, options?: OptionsOfDefaultResponseBody) => CancelableRequest<Response<T>>;
const typedInstance = instance as CorrectGotType;
await typedInstance(options as GotOptions); it still fails because: Argument of type 'GotOptions' is not assignable to parameter of type 'Merge<Merge<RequestOptions, Merge<GotOptions, URLOptions>>, { isStream?: false | undefined; resolveBodyOnly?: false | undefined; responseType?: "default" | undefined; }>'.
Type 'GotOptions' is not assignable to type '{ isStream?: false | undefined; resolveBodyOnly?: false | undefined; responseType?: "default" | undefined; }'.
Types of property 'isStream' are incompatible.
Type 'boolean | undefined' is not assignable to type 'false | undefined'.
Type 'true' is not assignable to type 'false | undefined'.ts(2345) TS is dumb, because it ignores the fact that we handle |
This comment has been minimized.
This comment has been minimized.
If we extend // Generic usage
<T>(url: string | Options, options?: Options): CancelableRequest<T> | ProxyStream<T>; then it would pass but you would have to cast it as
|
// @pmmmwh |
Workaround: type OptionsOfJSONResponseBody = Merge<
Options,
{
isStream?: false;
resolveBodyOnly?: false;
responseType: 'json';
}
>;
await got<ResultType>(url, opts as OptionsOfJSONResponseBody) |
I am thinking, maybe we should expose some of the internal option types to the outside world? Or instead, exporting a type for promise and another one for stream? That seems like a good idea to make sure TypeScript infers them correctly. For example, the following works: const options: OptionsOfDefaultResponseBody = {
url: 'https://example.com',
};
const response = await got(options); Edit: |
@pmmmwh is right about the bigger picture of this issue. Just trying to proxy arguments types to nested function const queuedGet = (...args: Parameters<GotFunctions>) =>
queue.add(() => got.get(...args)) will fail with error
P.S. I have submitted a PR for exporting |
Put differently, the type definitions in Got are so complex they're bumping up against TypeScript's limits. There's little point railing against TypeScript here. Got's ideal API may just not be expressible. You should consider moving a little closer to what TypeScript can handle. With my compile errors so far, it seems like providing the URL as a |
See function overloads. The same should be possible when using interfaces IMO. |
go back to the old and good JavaScript... |
I was coming across this error as well when trying to use got.post and pass in options.
It worked when I used got.extend instead.
|
The entire problem is a result of the dynamic return type being inferred from values in the options object. IMO the simplest workaround is to avoid using the // got.get<CustomType>(url, { responseType: 'json' })
got.get(url).json<CustomType>()
// got.get(url, { responseType: 'blob' })
got.get(url).blob()
// got.get(url, { responseType: 'text' })
got.get(url).text()
// got.get(url, { isStream: true })
got.stream(url) This allows for a base options type that always matches the default overload (i.e. type StrictOptions = Omit<Options, 'isStream' | 'responseType' | 'resolveBodyOnly'> I might even suggest |
I'm bumping up against something with the typings, although it might not be related to this issue. After an update, it no longer seems possible to import I also can't import |
Well if we don't, I'll explore other alternatives. This is really weird, as it was working great last time I checked. Thanks anyway for the package, Sindre. ❤️ |
@resynth1943 I'm not sure where you managed to find |
Nope. I'm pretty sure it exported something named |
You were using |
Well that package has a lot of weekly downloads. 171,998, to be exact. It's an understandable point of confusion. 😛 |
Maybe someone should add a package removal pr to for |
Or just mark it as deprecated.
El lun., 24 feb. 2020 a las 15:06, Michael Kriese (<notifications@github.com>)
escribió:
… Maybe someone should add a package removal pr
<https://github.com/DefinitelyTyped/DefinitelyTyped#removing-a-package>
to for @types/got
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#954?email_source=notifications&email_token=ACTTGMQDGD6WOIZQ6KUSAK3REPH43A5CNFSM4JTOJM22YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEMX4YOQ#issuecomment-590335034>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACTTGMTXRGZ7NE5UOACRU3DREPH43ANCNFSM4JTOJM2Q>
.
|
That what the link above does, it will remove the types from the repo and pushes a new version to npm with deprecation notice |
Some people are still using Got 9 so removal is inappropriate |
the type are still available on npm, they will only be removed from git repo. on npm only a new deprecated version (here major) will be published. |
My problem is that some of my dependencies use got@9 and @types/got. So i cant update my project to 10 before i update that dependencies. maybe we should create two new packages |
This issue is about v10 stream vs cancellable request response types not 10’s built in types vs 9’s definitely typed package. |
Another workaround for those still using Got v10 const textRequest = got.extend({ responseType: 'text' })
const res = await textRequest.put('https://api.example.com/v1/whatever', {
json: { some: 'property' },
}) |
What would you like to discuss?
With
@types/got
we could use typeGotOptions
and be able to pass this togot.get(options)
however with v10 the types arestring | OptionsOfDefaultResponseBody
andOptionsOfDefaultResponseBody
and its friends are not available to import at the root of the project. I was wondering if this was on purpose.What i'm looking for and not sure how to do with v10
Also, this example from the docs isn't working for me and I'm wondering if it should accept a partial? Opened #953 with a demo
Checklist
Really excited about the release of v10 🎉
The text was updated successfully, but these errors were encountered: