abnormi
abnormi

Reputation: 688

Typescript return type inference

In the following code snippet, typescript is able to infer the return type correctly:


{
  type IOFunction< OUTPUT> = (input: number) => OUTPUT

  function createIOFunction<OUTPUT>(input: number, converter: IOFunction<OUTPUT>): OUTPUT {
    return converter(input)
  }

  const x = createIOFunction(12, num => num + '!')
  // x is of type 'string'. Typescript was able to infer the OUTPUT type correctly AND without me specifying what the output type should be

  const y = createIOFunction(24, num => num * 2)
  // y is of type 'number'
}

How can I achieve this with following construct?


{
  type IOFunction<INPUT> = (input: INPUT) => any /* <-- What goes here ?? */
  // I don't want the type to be IOFunction<INPUT, OUTPUT> = (input: INPUT) => OUTPUT

  const convert: IOFunction<number> = num => num + '!'
  const x = convert(12)
  // x is of type any, not string
  // how can x be inferred? 
}

Here a more complex example (as requested):


  interface STATE {
    value: number
  }

  const myState: STATE = {
    value: 12
  } 

  type FAC_FUNCTION<S> = (state: S) => any


  const factory: FAC_FUNCTION<STATE> = state => (
    {
      hello() { 
        return 'Hello ' + state.value;
      }
    })

  const toolbox = factory(myState)
  // toolbox.hello() <!--- not typed :(




  type FACTORY_FUNCTION<S, OUTPUT> = (state:S) => OUTPUT

  function bindFactory<S, OUTPUT>(state:S, fac: FACTORY_FUNCTION<S, OUTPUT>) {
    return fac(state)
  }

  const toolbox2 = bindFactory(myState, state => ({
    hello() {
      return 'Hello ' + state.value
    }
  }))

  toolbox2.hello() // typed :)

The toolbox is not typed, toolbox2 is. I want to bind the state to the specific functions. In the end i wan't the user to write something like const toolbox = bindFactory(state, factory).

Sorry, but this is the best complex example I came up with

Upvotes: 0

Views: 72

Answers (1)

abnormi
abnormi

Reputation: 688

Ok, i figured a way - and it is actually very simple. All you have to provide are the type definitions of the input parameters and let the compiler figure out the rest.

So instead of

  type FAC_FUNCTION<S> = (state: S) => any

  const factory: FAC_FUNCTION<STATE> = state => (
    {
      hello() { 
        return 'Hello ' + state.value;
      }
    })

  const toolbox = factory(myState)

use:

  const factory = (state:PROPS) => (
    {
      hello() { 
        return 'Hello ' + state.value;
      }
    })

  const toolbox = factory(myState)

Upvotes: 1

Related Questions