TypeScript typeof Возвращаемое значение функции

Признай, у меня есть такая функция

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

Как я могу, не объявляя интерфейс или тип перед объявлением createPerson, получить тип возвращаемого значения?

Что-то вроде этого:

type Person = typeof createPerson()

Пример сценария

У меня есть контейнер Redux, который отображает состояние и действия по отправке на реквизиты компонента.

Контейнеры /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)

компоненты /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>
)

Я хочу иметь возможность экспортировать тип mapDispatchToProps без необходимости создания интерфейса MappedDispatch.

Я сократил код здесь, но он заставляет меня печатать одно и то же дважды.

Ответ 1

Оригинальный пост

TypeScript <2.8

Я создал небольшую библиотеку, которая разрешает обходной путь, пока в TypeScript не будет добавлен полностью декларативный способ:

https://npmjs.com/package/returnof

Также создал проблему на Github, запрашивающую вывод обобщенных типов, которая позволила бы полностью декларативный способ сделать это:

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


Обновление февраль 2018

TypeScript 2.8

TypeScript 2.8 представил новый статический тип ReturnType который позволяет достичь этого:

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

Теперь вы можете легко получить возвращаемый тип функции полностью декларативным способом:

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

type Person = ReturnType<typeof createPerson>

Ответ 3

Адаптировано с 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

Пример в ссылке использует null as T вместо {} as T, но этот разрыв с Type 'null' cannot be converted to type 'T'.

Самое приятное, что функция, заданная в качестве параметра для fakeReturn фактически не вызывается.

Протестировано с TypeScript 2.5.3


В TypeScript 2.8 введены некоторые предопределенные условные типы, включая ReturnType<T> который получает тип возврата типа функции.

const hello = () => 'World'

type Hello = ReturnType<typeof hello> // string