0

I am new to typescript, I apologize if my lingo for the language is off.

I want to make a generic function that optionally has an OAUTH token passed to it.

Here is my attempt:

import { AxiosStatic } from 'axios'

export function createAxiosInstance(
  axiosFactory: AxiosStatic,
  baseUrl: string,
  apiKey: string,
  clientId: string,
  clientSecret: string,
  authorization?: string | undefined
) {
  const headers = authorization
    ? {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'X-Api-Key': apiKey,
      Authorization: authorization
    }
    : {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'X-Api-Key': apiKey
    }
  return axiosFactory.create({
    baseURL: baseUrl,
    headers
  })
}

The headers object either has the Authorization property or it doesn't based on the parameter.

However, the headers object in the return statement within axiosFactory.create is throwing a typescript error:

Type '{ Accept: string; 'Content-Type': string; 'X-Api-Key': string; Authorization: string; } | { Accept: string; 'Content-Type': string; 'X-Api-Key': string; Authorization?: undefined; }' is not assignable to type 'AxiosRequestHeaders | undefined'. Type '{ Accept: string; 'Content-Type': string; 'X-Api-Key': string; Authorization?: undefined; }' is not assignable to type 'AxiosRequestHeaders'. Property 'Authorization' is incompatible with index signature. Type 'undefined' is not assignable to type 'string | number | boolean'.

Here is the tsconfig.json file:

{
  "compileOnSave": false,
  "compilerOptions": {
    "rootDir": ".",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es2015",
    "module": "esnext",
    "lib": ["es2017", "dom"],
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "baseUrl": ".",
    "strictNullChecks": true
  },
  "exclude": ["node_modules", "tmp"],
  "ts-node": {
    "compilerOptions": {
      "module": "commonjs"
    }
  }
}

The axios library I'm using has the AxiosRequestHeaders defined and it appears Authorization can only be string | number | boolean. In my scenario, Authorization can be undefined. I thought the type check (checking the value of authorization) would have resolved this since I never consume authorization as undefined however this hasn't resolved the typescript error. Any ideas on how to resolve this?

6
  • axiosFactory is defined by you? Please share its definitions Commented Sep 19, 2023 at 14:14
  • 1
    And your TS config. I can't reproduce this in a playground with the default settings. Commented Sep 19, 2023 at 14:16
  • Here is the axiosFactory, it is this interface, github.com/axios/axios/blob/… I plan on creating my own when creating an instance of axios. I haven't called this function yet, I am still defining it. I also added the tsconfig.json file from the project, thanks! Commented Sep 19, 2023 at 14:35
  • 1
    @HelloWorld Could you please create a TS Playground or StackBlitz Project where you can reproduce the error? That will give us something more concrete to work with. Commented Sep 19, 2023 at 14:44
  • 1
    Right now this still isn't a minimal reproducible example, unfortunately. What can we do? Commented Sep 19, 2023 at 14:53

1 Answer 1

0

Adding the AxiosRequestHeaders type to the headers variable solved the type error.

import { AxiosRequestHeaders, AxiosStatic } from 'axios'

export function createAxiosInstance(
  axiosFactory: AxiosStatic,
  baseUrl: string,
  apiKey: string,
  clientId: string,
  clientSecret: string,
  authorization?: string | undefined
) {
  const headers: AxiosRequestHeaders = authorization
    ? {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'X-Api-Key': apiKey,
      Authorization: authorization
    }
    : {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      'X-Api-Key': apiKey
    }
  return axiosFactory.create({
    baseURL: baseUrl,
    headers
  })
}

Without adding the type to headers, this is what was inferred:

enter image description here

Adding the type: const headers: AxiosRequestHeaders = authorization infers this:

enter image description here

As mentioned in some comments, there is likely more going on in my tsconfig that caused this, my original solution worked in a basic config.

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

Comments

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.