Typescript: How to declare the type for a function with custom properties that is returned from an IIFE

Tags: ,



Say I have an object like this

const someObject: SomeObject = {
  someMethod: (function() {
    function mainMethod(x) {return x+1}
    yolo.subMethod = function(x) { return x-1 }

    return mainMethod;
  })()
}

I tried defining its type like this:

type SomeObject = {
  someMethod: {
    (x:number): number
    subMethod(x:number): number
  }
}

however I am getting Parameter 'x' implicitly has an 'any' type. warnings in everything inside the IIFE, which means my type is not applied.

I have already read this similar answer however it doesn’t seem to work.

I am quite new to TS, and I am not yet familiar with more intricate usecases such as this, so any help would be much appreciated.

Answer

Contextual typing (where TS infers parameter types based on expected type) has its limitations. One of them is that the function has to be assigned directly to a typed reference. Since mainMethod is not directly assigned anywhere upon declaration it will not benefit form contextual typing. It will be checked in the return, but it will not be contextually typed.

You will have to declare the parameter types explicitly to the functions. If you want to keep things dry you could define the type in relation to the inferred constant type instead:

const someObject = {
    someMethod: (function () {
        function mainMethod(x: number) { return x + 1 }
        mainMethod.subMethod = function (x: number) { return x - 1 }

        return mainMethod;
    })()
}

type SomeObject = typeof someObject

Playground Link



Source: stackoverflow