1

I am wrapping Angular's HttpClient service in my own method but still want users to be able to pass in options, however I can't seem to find a good way to reference that type in my own method parameter definition.

example:

  constructor(private http: HttpClient) {}

  my_request<T = any>(endpoint: string, payload: T, options: WhatTypeHere = {}) {
    return this.http.post<MyHttpResponse>(this.build_url(endpoint), this.build_payload(payload), {
      ...options,
      withCredentials: true,
    });
  }

You can see the options parameter of my_request() I don't know what I can put there so that when using my_request it can enforce it.

Here is the definition of HttpClient.post() fyi

post(url: string, body: any | null, options?: {
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe?: 'body';
        params?: HttpParams | {
            [param: string]: string | string[];
        };
        reportProgress?: boolean;
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<Object>;

I'm aware I could copy-paste that entire definition into my method, but if there is some way I can reference it I would rather for conciseness and if definitions change in the future.

One things I tried that didn't work was something like options: HttpClient['post']['options']

Is there anything thing like this I can use to reference that type?

4
  • Did you try using interface ? Commented Mar 27, 2019 at 20:18
  • What do you mean? Like make my own interface that mirrors their definition? I'd rather not go that route. Commented Mar 27, 2019 at 20:18
  • Why not ? I think that would your best shot, just like you reference non primitive types in typescript. Commented Mar 27, 2019 at 20:23
  • 2
    Two reasons. Since This definition comes from a 3rd-party library if I make my interface and their definition changes at some point I will have to update my interface, and will probably forget about it which will cause problems down the road. Also, it seems redundant to have the same definition twice. That's the reason I asked this question. I know I can make an interface, but I'm looking for another option. Some way to directly reference their definition. Commented Mar 27, 2019 at 20:29

1 Answer 1

2

In at least typescript 3.3 (version on the playground at the time of writing), you can extract the type of the 3rd parameter of post. See the trimmed down example below:

interface A {
    eh: number
}
function post(url: string, body: any | null, options?: {a: A}): void {}

// Create an alias for convenience 
type PostOptions = Parameters<typeof post>[2];

let options: PostOptions;
options = {}; // Expected error: Property 'a' is missing in type '{}' but required in type '{ a: A; }'.
options = { a: {} }; // Expected error: Property 'eh' is missing in type '{}' but required in type 'A'.
options = {a: {eh: 10}} // Ahh... just right :)

Playground link

A little more explanation: Parameters<T> is the type of the parameters of the function T as a tuple. typeof post gets the type of the function and then we want the 3rd parameter which is the type in the tuple at index 2.

Sign up to request clarification or add additional context in comments.

1 Comment

duuude, this is exactly what I was looking for. thanks! Was able to use Parameters<HttpClient['post']>[2].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.