skip to Main Content
type UpdateConsumerT = {
  obj: {
    min_quantity: number
    fixed_price: number
    date_start: string | boolean
    date_end: string | boolean
  }
}

type UpdateProducerT = {
  obj: {
    min_qty: number
    price: number
    date_start: string | boolean
    date_end: string | boolean
  }
}

export async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateConsumerT,
  isProduction: false
): Promise<number>
export async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateProducerT,
  isProduction: true
): Promise<number>
export async function updatePricelistItem(
  pricelist_item_id,
  obj,
  isProduction = false
) { ... }

I have this function, and i try to use overloads

But for some reason it says

Parameter ‘pricelist_item_id’ implicitly has an ‘any’ type.ts(7006)

enter image description here

My question is, what am i doing wrong here?

3

Answers


  1. You will need to explicitly specify the parameter types and return type on the implementation:

    type UpdateConsumerT = {
      obj: {
        min_quantity: number
        fixed_price: number
        date_start: string | boolean
        date_end: string | boolean
      }
    }
    
    type UpdateProducerT = {
      obj: {
        min_qty: number
        price: number
        date_start: string | boolean
        date_end: string | boolean
      }
    }
    
    async function updatePricelistItem(
      pricelist_item_id: number,
      obj: UpdateConsumerT,
      isProduction: false
    ): Promise<number>
    async function updatePricelistItem(
      pricelist_item_id: number,
      obj: UpdateProducerT,
      isProduction: true
    ): Promise<number>
    async function updatePricelistItem(
      pricelist_item_id: number,
      obj: UpdateProducerT | UpdateConsumerT,
      isProduction = false
    ): Promise<number> { return new Promise(() => {}) }
    

    Playground

    Login or Signup to reply.
  2. If you have noImplicitAny set to true in your tsconfig file, any function parameter without an explicitly declared type will be considered as implicitly any, leading to a compilation error.

    You can fix that error by adding type annotation or add explicit any type

    type UpdateConsumerT = {
      obj: {
        min_quantity: number
        fixed_price: number
        date_start: string | boolean
        date_end: string | boolean
      }
    }
    
    type UpdateProducerT = {
      obj: {
        min_qty: number
        price: number
        date_start: string | boolean
        date_end: string | boolean
      }
    }
    
    export async function updatePricelistItem(
      pricelist_item_id: number,
      obj: UpdateConsumerT,
      isProduction: false
    ): Promise<number>
    export async function updatePricelistItem(
      pricelist_item_id: number,
      obj: UpdateProducerT,
      isProduction: true
    ): Promise<number>
    
    export async function updatePricelistItem(
      pricelist_item_id:any,
      obj:any,
      isProduction:any,
    ){
      // Function implementation goes here
      // ...
      // Return the result, e.g., return 1;
      return 1;
    }
    

    Example Playground

    Login or Signup to reply.
  3. Overload function implementations do not currently have their parameter types inferred contextually from the call signatures. There’s a longstanding open feature request for this at microsoft/TypeScript#25352, but for now it’s not part of the language.

    Until and unless that gets implemented, you will need to manually annotate the function implementation’s parameters:

    export async function updatePricelistItem(
      pricelist_item_id: number,
      obj: UpdateConsumerT,
      isProduction: false
    ): Promise<number>
    export async function updatePricelistItem(
      pricelist_item_id: number,
      obj: UpdateProducerT,
      isProduction: true
    ): Promise<number>
    
    export async function updatePricelistItem(
      pricelist_item_id: number, // <-- annotate
      obj: UpdateConsumerT | UpdateProducerT, // <-- annotate
      isProduction = false // this is inferred as boolean from false
    ) {
      return null!; // suppress errors
    }
    

    Do note that because your call signatures return the same type for each call, you don’t need to use overloads. Instead you can use a rest parameter whose type is a union of tuple types:

    export async function updatePricelistItem(
      pricelist_item_id: number,
      ...[obj, isProduction]:
        [obj: UpdateConsumerT, isProduction: false] |
        [obj: UpdateProducerT, isProduction: true]
    ): Promise<number> {
      return null!; // suppress errors
    }
    
    declare const consumer: UpdateConsumerT;
    declare const producer: UpdateProducerT;
    updatePricelistItem(123, consumer, false); // okay
    updatePricelistItem(123, producer, true); // okay
    updatePricelistItem(123, consumer, true); // error
    

    This approach is even better for your implementation because that rest parameter is a discriminated union with isProduction as the discriminant, so you can use control flow analysis on the destructured parameters to narrow obj based on isProduction:

    export async function updatePricelistItem(
      pricelist_item_id: number,
      ...[obj, isProduction]:
        [obj: UpdateConsumerT, isProduction: false] |
        [obj: UpdateProducerT, isProduction: true]
    ): Promise<number> {
      if (isProduction) {
        obj.obj.price // okay, known to be UpdateProducerT
      } else {
        obj.obj.fixed_price // okay, known to be UpdateConsumerT
      }
      return null!;
    }
    

    Playground link to code

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search