ethanent / phin

Node HTTP client
MIT License
576 stars 33 forks source link

Types for "defaults" function #57

Closed charles-allen closed 3 years ago

charles-allen commented 4 years ago

There is a disclaimer in the types file:

// Default Options feature is not supported because it's basically impossible to write strongly-typed definitions for it.

I think perhaps Partial<T> is the piece of the puzzle you were missing? I tried to write a definition, but I'm not sure I understand the relation between JS source & TS types. Does this help? (might not be correct!)

export function defaults<T>(
  defaultOptions:
    | Partial<phin.IJSONResponseOptions>
    | Partial<IWithData<phin.IJSONResponseOptions>>
    | Partial<IWithForm<phin.IJSONResponseOptions>>
): (
  options:
    | phin.IJSONResponseOptions
    | IWithData<phin.IJSONResponseOptions>
    | IWithForm<phin.IJSONResponseOptions>
) => Promise<phin.IJSONResponse<T>>
ethanent commented 3 years ago

Thanks! This does seem like a good idea.

jdforsythe commented 3 years ago

I think this is now handled by optional properties in IOptionsBase

sleeyax commented 1 year ago

If anyone is wondering how exactly to extend the phin type definitions to include the suggested additions in your project, you can do so as follows:

  1. Create the type declaration file, e.g. types/phin.d.ts:
    
    import phin, { IWithData, IWithForm } from 'phin';

declare module 'phin' { export function defaults( defaultOptions: | Partial | Partial<IWithData> | Partial<IWithForm> ): ( options: | phin.IJSONResponseOptions | IWithData | IWithForm ) => Promise<phin.IJSONResponse>; }

2. Update `tsconfig.json` as follows:
```json
"compilerOptions": {
    "typeRoots": [
      "./types/"
    ],
  }
  1. This enables you to access defaults like this:
    
    import p from 'phin';

export const httpClient = p.defaults({ headers: { 'User-Agent': 'My App', }, });