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>
Ответ 2
Этот https://github.com/Microsoft/TypeScript/issues/4233#issuecomment-139978012 может помочь:
let r = true ? undefined : someFunction();
type ReturnType = typeof r;
Ответ 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