From ab5d87f8ef982c51722237d3b1761b7bb285bdb4 Mon Sep 17 00:00:00 2001 From: Matthew Bull Date: Tue, 29 Jan 2019 22:22:25 +0000 Subject: [PATCH 1/8] Add support for `got.extend` --- types/got/got-tests.ts | 4 ++++ types/got/index.d.ts | 2 ++ 2 files changed, 6 insertions(+) diff --git a/types/got/got-tests.ts b/types/got/got-tests.ts index afaac89ba4..6d011b3bc5 100644 --- a/types/got/got-tests.ts +++ b/types/got/got-tests.ts @@ -266,6 +266,10 @@ got('/examples/angularjs', { baseUrl: 'http://todomvc.com' }); got('http://todomvc.com', { headers: { foo: 'bar'} }); got('http://todomvc.com', { cookieJar: new tough.CookieJar() }); +// Test extension +got.extend({ method: 'POST' })('/example'); +got.extend({ method: 'POST' }).extend({ headers: {} }).stream('/example'); + // Test retry options. got('http://todomvc.com', { retry: 2 }); got('http://todomvc.com', { diff --git a/types/got/index.d.ts b/types/got/index.d.ts index 0c847d6489..42c7442f88 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -4,6 +4,7 @@ // Linus Unnebäck // Konstantin Ikonnikov // Stijn Van Nieuwenhuyse +// Matthew Bull // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 @@ -72,6 +73,7 @@ declare const got: got.GotFn & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', got.GotFn> & { stream: got.GotStreamFn & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', got.GotStreamFn>; + extend: (options: got.GotJSONOptions | got.GotFormOptions | got.GotFormOptions | got.GotBodyOptions | got.GotBodyOptions) => typeof got; RequestError: typeof RequestError; ReadError: typeof ReadError; ParseError: typeof ParseError; From 69e5a329034449aa0c6a619227bbd978044765d0 Mon Sep 17 00:00:00 2001 From: Matthew Bull Date: Wed, 30 Jan 2019 15:22:30 +0000 Subject: [PATCH 2/8] Add support for typing the body returned by `got` when extended with `json: true` --- types/got/got-tests.ts | 4 ++++ types/got/index.d.ts | 45 +++++++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/types/got/got-tests.ts b/types/got/got-tests.ts index 6d011b3bc5..dbda609c4c 100644 --- a/types/got/got-tests.ts +++ b/types/got/got-tests.ts @@ -270,6 +270,10 @@ got('http://todomvc.com', { cookieJar: new tough.CookieJar() }); got.extend({ method: 'POST' })('/example'); got.extend({ method: 'POST' }).extend({ headers: {} }).stream('/example'); +got.extend({ json: true })('/example').then(({ body }) => body.value); // Body is `any` +got.extend({ baseUrl: 'https://localhost' }).extend({ json: true })('/example').then(({ body }) => body.value); // Body is `any` +got.extend({})('/example').then(({ body }) => '' + body); // Body is `string` + // Test retry options. got('http://todomvc.com', { retry: 2 }); got('http://todomvc.com', { diff --git a/types/got/index.d.ts b/types/got/index.d.ts index 42c7442f88..bc3861d7a9 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -69,20 +69,7 @@ declare class StdError extends Error { response?: any; } -declare const got: got.GotFn & - Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', got.GotFn> & - { - stream: got.GotStreamFn & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', got.GotStreamFn>; - extend: (options: got.GotJSONOptions | got.GotFormOptions | got.GotFormOptions | got.GotBodyOptions | got.GotBodyOptions) => typeof got; - RequestError: typeof RequestError; - ReadError: typeof ReadError; - ParseError: typeof ParseError; - HTTPError: typeof HTTPError; - MaxRedirectsError: typeof MaxRedirectsError; - UnsupportedProtocolError: typeof UnsupportedProtocolError; - CancelError: typeof CancelError; - TimeoutError: typeof TimeoutError; - }; +declare const got: got.DefaultGotInstance; interface InternalRequestOptions extends https.RequestOptions { // Redeclare options with `any` type for allow specify types incompatible with http.RequestOptions. @@ -100,6 +87,36 @@ declare namespace got { (url: GotUrl, options: GotBodyOptions): GotPromise; } + interface GotJSONFn { + (url: GotUrl): GotPromise; + (url: GotUrl, options: GotJSONOptions): GotPromise; + (url: GotUrl, options: GotFormOptions): GotPromise; + (url: GotUrl, options: GotBodyOptions): GotPromise; + } + + type GotInstance = T & + Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', T> & + { + stream: got.GotStreamFn & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', got.GotStreamFn>; + extend: GotExtend; + RequestError: typeof RequestError; + ReadError: typeof ReadError; + ParseError: typeof ParseError; + HTTPError: typeof HTTPError; + MaxRedirectsError: typeof MaxRedirectsError; + UnsupportedProtocolError: typeof UnsupportedProtocolError; + CancelError: typeof CancelError; + TimeoutError: typeof TimeoutError; + }; + + type DefaultGotInstance = GotInstance; + type JSONGotInstance = GotInstance; + + interface GotExtend { + (options: got.GotFormOptions | got.GotBodyOptions | got.GotFormOptions | got.GotBodyOptions): DefaultGotInstance; + (options: got.GotJSONOptions): JSONGotInstance; + } + type GotStreamFn = (url: GotUrl, options?: GotOptions) => GotEmitter & nodeStream.Duplex; type GotUrl = string | https.RequestOptions | Url | URL; From d3c964d9ebc6d23043f410975707cac718cac240 Mon Sep 17 00:00:00 2001 From: Matthew Bull Date: Wed, 30 Jan 2019 16:27:01 +0000 Subject: [PATCH 3/8] Fix build --- types/got/index.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/types/got/index.d.ts b/types/got/index.d.ts index bc3861d7a9..257362a149 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -97,7 +97,7 @@ declare namespace got { type GotInstance = T & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', T> & { - stream: got.GotStreamFn & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', got.GotStreamFn>; + stream: GotStreamFn & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', GotStreamFn>; extend: GotExtend; RequestError: typeof RequestError; ReadError: typeof ReadError; @@ -113,8 +113,8 @@ declare namespace got { type JSONGotInstance = GotInstance; interface GotExtend { - (options: got.GotFormOptions | got.GotBodyOptions | got.GotFormOptions | got.GotBodyOptions): DefaultGotInstance; - (options: got.GotJSONOptions): JSONGotInstance; + (options: GotJSONOptions): JSONGotInstance; + (options: GotFormOptions | GotBodyOptions | GotFormOptions | GotBodyOptions): DefaultGotInstance; } type GotStreamFn = (url: GotUrl, options?: GotOptions) => GotEmitter & nodeStream.Duplex; From 4a98006b062812c2cf10d267b1a3769c2e0c23e5 Mon Sep 17 00:00:00 2001 From: Matthew Bull Date: Thu, 31 Jan 2019 09:38:31 +0000 Subject: [PATCH 4/8] Use overloads rather than union types. Only support JSON for JSON. Fix tests --- types/got/got-tests.ts | 9 ++++++--- types/got/index.d.ts | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/types/got/got-tests.ts b/types/got/got-tests.ts index dbda609c4c..b22749bfb4 100644 --- a/types/got/got-tests.ts +++ b/types/got/got-tests.ts @@ -270,9 +270,12 @@ got('http://todomvc.com', { cookieJar: new tough.CookieJar() }); got.extend({ method: 'POST' })('/example'); got.extend({ method: 'POST' }).extend({ headers: {} }).stream('/example'); -got.extend({ json: true })('/example').then(({ body }) => body.value); // Body is `any` -got.extend({ baseUrl: 'https://localhost' }).extend({ json: true })('/example').then(({ body }) => body.value); // Body is `any` -got.extend({})('/example').then(({ body }) => '' + body); // Body is `string` +// $ExpectType Promise +got.extend({ json: true })('/example').then(({ body }) => body); +// $ExpectType Promise +got.extend({ baseUrl: 'https://localhost' }).extend({ json: true })('/example').then(({ body }) => body); +// $ExpectType Promise +got.extend({})('/example').then(({ body }) => body); // Test retry options. got('http://todomvc.com', { retry: 2 }); diff --git a/types/got/index.d.ts b/types/got/index.d.ts index 257362a149..43ed5a5f35 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -90,8 +90,6 @@ declare namespace got { interface GotJSONFn { (url: GotUrl): GotPromise; (url: GotUrl, options: GotJSONOptions): GotPromise; - (url: GotUrl, options: GotFormOptions): GotPromise; - (url: GotUrl, options: GotBodyOptions): GotPromise; } type GotInstance = T & @@ -114,7 +112,10 @@ declare namespace got { interface GotExtend { (options: GotJSONOptions): JSONGotInstance; - (options: GotFormOptions | GotBodyOptions | GotFormOptions | GotBodyOptions): DefaultGotInstance; + (options: GotFormOptions): DefaultGotInstance; + (options: GotBodyOptions): DefaultGotInstance; + (options: GotFormOptions): DefaultGotInstance; + (options: GotBodyOptions): DefaultGotInstance; } type GotStreamFn = (url: GotUrl, options?: GotOptions) => GotEmitter & nodeStream.Duplex; From f6a5b6257e933cf5cabccc33d637eb7bc9970b03 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 13 Apr 2019 20:30:44 +0100 Subject: [PATCH 5/8] remove unneccessary aliases --- types/got/index.d.ts | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/types/got/index.d.ts b/types/got/index.d.ts index 43ed5a5f35..e8890429ce 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -69,7 +69,7 @@ declare class StdError extends Error { response?: any; } -declare const got: got.DefaultGotInstance; +declare const got: got.GotInstance; interface InternalRequestOptions extends https.RequestOptions { // Redeclare options with `any` type for allow specify types incompatible with http.RequestOptions. @@ -94,28 +94,25 @@ declare namespace got { type GotInstance = T & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', T> & - { - stream: GotStreamFn & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', GotStreamFn>; - extend: GotExtend; - RequestError: typeof RequestError; - ReadError: typeof ReadError; - ParseError: typeof ParseError; - HTTPError: typeof HTTPError; - MaxRedirectsError: typeof MaxRedirectsError; - UnsupportedProtocolError: typeof UnsupportedProtocolError; - CancelError: typeof CancelError; - TimeoutError: typeof TimeoutError; - }; - - type DefaultGotInstance = GotInstance; - type JSONGotInstance = GotInstance; + { + stream: GotStreamFn & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', GotStreamFn>; + extend: GotExtend; + RequestError: typeof RequestError; + ReadError: typeof ReadError; + ParseError: typeof ParseError; + HTTPError: typeof HTTPError; + MaxRedirectsError: typeof MaxRedirectsError; + UnsupportedProtocolError: typeof UnsupportedProtocolError; + CancelError: typeof CancelError; + TimeoutError: typeof TimeoutError; + }; interface GotExtend { - (options: GotJSONOptions): JSONGotInstance; - (options: GotFormOptions): DefaultGotInstance; - (options: GotBodyOptions): DefaultGotInstance; - (options: GotFormOptions): DefaultGotInstance; - (options: GotBodyOptions): DefaultGotInstance; + (options: GotJSONOptions): GotInstance; + (options: GotFormOptions): GotInstance; + (options: GotBodyOptions): GotInstance; + (options: GotFormOptions): GotInstance; + (options: GotBodyOptions): GotInstance; } type GotStreamFn = (url: GotUrl, options?: GotOptions) => GotEmitter & nodeStream.Duplex; From 36458c7a37b68959ceb5a0ed1dd747868691be45 Mon Sep 17 00:00:00 2001 From: Matthew Bull Date: Sat, 13 Apr 2019 20:46:09 +0100 Subject: [PATCH 6/8] Apply PR feedback --- types/got/index.d.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/types/got/index.d.ts b/types/got/index.d.ts index e8890429ce..e60115f5d1 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -92,6 +92,16 @@ declare namespace got { (url: GotUrl, options: GotJSONOptions): GotPromise; } + interface GotFormFn { + (url: GotUrl): GotPromise; + (url: GotUrl, options: GotFormOptions): GotPromise; + } + + interface GotBodyFn { + (url: GotUrl): GotPromise; + (url: GotUrl, options: GotBodyOptions): GotPromise; + } + type GotInstance = T & Record<'get' | 'post' | 'put' | 'patch' | 'head' | 'delete', T> & { @@ -108,11 +118,12 @@ declare namespace got { }; interface GotExtend { + (options: GotOptions): GotInstance; (options: GotJSONOptions): GotInstance; - (options: GotFormOptions): GotInstance; - (options: GotBodyOptions): GotInstance; - (options: GotFormOptions): GotInstance; - (options: GotBodyOptions): GotInstance; + (options: GotFormOptions): GotInstance>; + (options: GotFormOptions): GotInstance>; + (options: GotBodyOptions): GotInstance>; + (options: GotBodyOptions): GotInstance>; } type GotStreamFn = (url: GotUrl, options?: GotOptions) => GotEmitter & nodeStream.Duplex; From ba4c75612e34da08009fef8fe003aed30dd3cd6a Mon Sep 17 00:00:00 2001 From: Matthew Date: Sat, 13 Apr 2019 21:09:32 +0100 Subject: [PATCH 7/8] improve form & body functions with conditional types --- types/got/index.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/types/got/index.d.ts b/types/got/index.d.ts index 893366846b..5e213ce9db 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -6,7 +6,7 @@ // Stijn Van Nieuwenhuyse // Matthew Bull // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.3 +// TypeScript Version: 2.8 /// @@ -95,12 +95,12 @@ declare namespace got { interface GotFormFn { (url: GotUrl): GotPromise; - (url: GotUrl, options: GotFormOptions): GotPromise; + (url: GotUrl, options: GotFormOptions): GotPromise; } interface GotBodyFn { (url: GotUrl): GotPromise; - (url: GotUrl, options: GotBodyOptions): GotPromise; + (url: GotUrl, options: GotBodyOptions): GotPromise; } type GotInstance = T & From 1b78375d635a79027b0854662c9a4e23edb4310b Mon Sep 17 00:00:00 2001 From: Matthew Bull Date: Sun, 14 Apr 2019 15:42:52 +0100 Subject: [PATCH 8/8] Added additional tests for form + body options Fixed types for these scenarios --- types/got/got-tests.ts | 67 +++++++++++++++++++++++++++--------------- types/got/index.d.ts | 5 ++-- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/types/got/got-tests.ts b/types/got/got-tests.ts index 2582ea784f..8aae7f300d 100644 --- a/types/got/got-tests.ts +++ b/types/got/got-tests.ts @@ -21,35 +21,35 @@ got('todomvc.com') got('todomvc.com').cancel(); -got('todomvc.com', {json: true}).then((response) => { +got('todomvc.com', { json: true }).then((response) => { response.body; // $ExpectType any }); -got('todomvc.com', {json: true, body: {}}).then((response) => { +got('todomvc.com', { json: true, body: {} }).then((response) => { response.body; // $ExpectType any }); -got('todomvc.com', {json: true, body: [{}]}).then((response) => { +got('todomvc.com', { json: true, body: [{}] }).then((response) => { response.body; // $ExpectType any }); -got('todomvc.com', {json: true, form: true}).then((response) => { +got('todomvc.com', { json: true, form: true }).then((response) => { response.body; // $ExpectType any }); -got('todomvc.com', {json: true, form: true, encoding: null}).then((response) => { +got('todomvc.com', { json: true, form: true, encoding: null }).then((response) => { response.body; // $ExpectType any }); -got('todomvc.com', {json: true, form: true, encoding: null, hostname: 'todomvc'}).then((response) => { +got('todomvc.com', { json: true, form: true, encoding: null, hostname: 'todomvc' }).then((response) => { response.body; // $ExpectType any }); -got('todomvc.com', {form: true}).then(response => str = response.body); -got('todomvc.com', {form: true, body: {}}).then(response => str = response.body); -got('todomvc.com', {form: true, body: [{}]}).then(response => str = response.body); -got('todomvc.com', {form: true, body: [{}], encoding: null}).then(response => buf = response.body); -got('todomvc.com', {form: true, body: [{}], encoding: 'utf8'}).then(response => str = response.body); +got('todomvc.com', { form: true }).then(response => str = response.body); +got('todomvc.com', { form: true, body: {} }).then(response => str = response.body); +got('todomvc.com', { form: true, body: [{}] }).then(response => str = response.body); +got('todomvc.com', { form: true, body: [{}], encoding: null }).then(response => buf = response.body); +got('todomvc.com', { form: true, body: [{}], encoding: 'utf8' }).then(response => str = response.body); got('todomvc.com', { form: true, body: [{}], @@ -68,21 +68,21 @@ got('todomvc.com', { body: [{}], encoding: 'utf8', hostname: 'todomvc', - timeout: {connect: 20, request: 20, socket: 20} + timeout: { connect: 20, request: 20, socket: 20 } }).then(response => str = response.body); // following must lead to type checking error: got('todomvc.com', {form: true, body: ''}).then(response => str = response.body); -got('todomvc.com', {encoding: null, hostname: 'todomvc'}).then(response => buf = response.body); -got('todomvc.com', {encoding: 'utf8', hostname: 'todomvc'}).then(response => str = response.body); +got('todomvc.com', { encoding: null, hostname: 'todomvc' }).then(response => buf = response.body); +got('todomvc.com', { encoding: 'utf8', hostname: 'todomvc' }).then(response => str = response.body); -got('todomvc.com', {hostname: 'todomvc'}).then(response => str = response.body); +got('todomvc.com', { hostname: 'todomvc' }).then(response => str = response.body); -got.get('todomvc.com', {hostname: 'todomvc'}).then(response => str = response.body); -got.post('todomvc.com', {hostname: 'todomvc'}).then(response => str = response.body); -got.put('todomvc.com', {hostname: 'todomvc'}).then(response => str = response.body); -got.patch('todomvc.com', {hostname: 'todomvc'}).then(response => str = response.body); -got.head('todomvc.com', {hostname: 'todomvc'}).then(response => str = response.body); -got.delete('todomvc.com', {hostname: 'todomvc'}).then(response => str = response.body); +got.get('todomvc.com', { hostname: 'todomvc' }).then(response => str = response.body); +got.post('todomvc.com', { hostname: 'todomvc' }).then(response => str = response.body); +got.put('todomvc.com', { hostname: 'todomvc' }).then(response => str = response.body); +got.patch('todomvc.com', { hostname: 'todomvc' }).then(response => str = response.body); +got.head('todomvc.com', { hostname: 'todomvc' }).then(response => str = response.body); +got.delete('todomvc.com', { hostname: 'todomvc' }).then(response => str = response.body); got.stream('todomvc.com').pipe(fs.createWriteStream('index.html')); @@ -258,19 +258,38 @@ got(url.parse('http://todomvc.com')); got('https://todomvc.com', { rejectUnauthorized: false }); got('/examples/angularjs', { baseUrl: 'http://todomvc.com' }); -got('http://todomvc.com', { headers: { foo: 'bar'} }); +got('http://todomvc.com', { headers: { foo: 'bar' } }); got('http://todomvc.com', { cookieJar: new tough.CookieJar() }); // Test extension got.extend({ method: 'POST' })('/example'); got.extend({ method: 'POST' }).extend({ headers: {} }).stream('/example'); +// JSON options: // $ExpectType Promise got.extend({ json: true })('/example').then(({ body }) => body); // $ExpectType Promise got.extend({ baseUrl: 'https://localhost' }).extend({ json: true })('/example').then(({ body }) => body); // $ExpectType Promise got.extend({})('/example').then(({ body }) => body); +// Form options: +// $ExpectType Promise +got.extend({ form: true, encoding: null })('/example').then(({ body }) => body); +// $ExpectType Promise +got.extend({ form: true, encoding: null, body: {} })('/example').then(({ body }) => body); +// $ExpectType Promise +got.extend({ form: true, encoding: 'utf8' })('/example').then(({ body }) => body); +// $ExpectType Promise +got.extend({ form: true, encoding: 'utf8', body: {} })('/example').then(({ body }) => body); +// Body options: +// $ExpectType Promise +got.extend({ encoding: null })('/example').then(({ body }) => body); +// $ExpectType Promise +got.extend({ encoding: null, body: '{}' })('/example').then(({ body }) => body); +// $ExpectType Promise +got.extend({ encoding: 'utf8' })('/example').then(({ body }) => body); +// $ExpectType Promise +got.extend({ encoding: 'utf8', body: '{}' })('/example').then(({ body }) => body); // Test retry options. got('http://todomvc.com', { retry: 2 }); @@ -295,7 +314,7 @@ got('http://todomvc.com', { got('http://todomvc.com', { throwHttpErrors: false }); // Test timeout options. -got('http://todomvc.com', {timeout: 1}); +got('http://todomvc.com', { timeout: 1 }); got('http://todomvc.com', { timeout: { lookup: 1, @@ -309,7 +328,7 @@ got('http://todomvc.com', { }); // Test got.TimeoutError. -got('http://todomvc.com', {timeout: 1}).catch((err) => err instanceof got.TimeoutError); +got('http://todomvc.com', { timeout: 1 }).catch((err) => err instanceof got.TimeoutError); // Test hooks. got('example.com', { diff --git a/types/got/index.d.ts b/types/got/index.d.ts index 5e213ce9db..8fb6a71e63 100644 --- a/types/got/index.d.ts +++ b/types/got/index.d.ts @@ -94,12 +94,12 @@ declare namespace got { } interface GotFormFn { - (url: GotUrl): GotPromise; + (url: GotUrl): GotPromise; (url: GotUrl, options: GotFormOptions): GotPromise; } interface GotBodyFn { - (url: GotUrl): GotPromise; + (url: GotUrl): GotPromise; (url: GotUrl, options: GotBodyOptions): GotPromise; } @@ -119,7 +119,6 @@ declare namespace got { }; interface GotExtend { - (options: GotOptions): GotInstance; (options: GotJSONOptions): GotInstance; (options: GotFormOptions): GotInstance>; (options: GotFormOptions): GotInstance>;