TypeScript typeof Function return value

Typescript

Typescript Problem Overview


Admit I have a function like this

const createPerson = () => ({ firstName: 'John', lastName: 'Doe' })

How can I, without declaring an interface or a type before declaring createPerson, get the return value type?

Something like this:

type Person = typeof createPerson()

Example Scenario

I have a Redux container that maps state and dispatch actions to props of a component.

containers/Counter.tsx
import { CounterState } from 'reducers/counter'

// ... Here I also defined MappedState and mapStateToProps

// The interface I would like to remove
interface MappedDispatch {
  increment: () => any
}

// And get the return value type of this function
const mapDispatchToProps =
  (dispatch: Dispatch<State>): MappedDispatch => ({
    increment: () => dispatch(increment)
  })

// To export it here instead of MappedDispatch
export type MappedProps = MappedState & MappedDispatch
export default connect(mapStateToProps, mapDispatchToProps)(Counter)
components/Counter.tsx
import { MappedProps } from 'containers/Counter'

export default (props: MappedProps) => (
  <div>
    <h1>Counter</h1>
    <p>{props.value}</p>
    <button onClick={props.increment}>+</button>
  </div>
)

I want to be able to export the type of mapDispatchToProps without having to create MappedDispatch interface.

I reduced the code here, but it makes me type the same thing two times.

Typescript Solutions


Solution 1 - Typescript

Original Post

TypeScript < 2.8

I created a little library that permits a workaround, until a fully declarative way is added to TypeScript:

https://npmjs.com/package/returnof

Also created an issue on Github, asking for Generic Types Inference, that would permit a fully declarative way to do this:

https://github.com/Microsoft/TypeScript/issues/14400


Update February 2018

TypeScript 2.8

TypeScript 2.8 introduced a new static type ReturnType which permits to achieve that:

https://github.com/Microsoft/TypeScript/pull/21496

You can now easily get the return type of a function in a fully declarative way:

const createPerson = () => ({
  firstName: 'John',
  lastName: 'Doe'
})

type Person = ReturnType<typeof createPerson>

Solution 2 - Typescript

This https://github.com/Microsoft/TypeScript/issues/4233#issuecomment-139978012 might help:

let r = true ? undefined : someFunction();
type ReturnType = typeof r;

Solution 3 - Typescript

Adapted from https://github.com/Microsoft/TypeScript/issues/14400#issuecomment-291261491

const fakeReturn = <T>(fn: () => T) => ({} as T)

const hello = () => 'World'
const helloReturn = fakeReturn(hello) // {}

type Hello = typeof helloReturn // string

The example in the link uses null as T instead of {} as T, but that breaks with Type 'null' cannot be converted to type 'T'.

The best part is that the function given as parameter to fakeReturn is not actually called.

Tested with TypeScript 2.5.3


TypeScript 2.8 introduced some predefined conditional types, including the ReturnType<T> that obtains the return type of a function type.

const hello = () => 'World'

type Hello = ReturnType<typeof hello> // string

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkubeView Question on Stackoverflow
Solution 1 - TypescriptkubeView Answer on Stackoverflow
Solution 2 - Typescript0x6adb015View Answer on Stackoverflow
Solution 3 - TypescriptMihai RăducanuView Answer on Stackoverflow