TypeScript中的typeof函数返回值是什么?

128

承认我有一个像这样的函数

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

我如何在声明createPerson之前,无需声明接口或类型,获取返回值类型?

类似于这样:

type Person = typeof createPerson()

示例场景

我有一个 Redux 容器,将状态和派发操作映射到组件的 props 上。

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)

组件/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接口。

我在此处缩减了代码,但这使我需要两次输入相同的内容。


为什么?有什么意义吗?你能举个例子说明它有意义吗? - Nitzan Tomer
我认为你无法做到这一点。没有办法根据函数返回值的类型来定义类型。 - Nitzan Tomer
3个回答

234

原始帖子

TypeScript < 2.8

我创建了一个小库,允许使用 TypeScript 的完全声明性方式之前的一种解决方法:

https://npmjs.com/package/returnof

我还在 Github 上创建了一个问题,请求通用类型推断,这将允许以完全声明性的方式进行操作:

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


2018年2月更新

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
在使用类时,如何获取方法的返回类型?我不能使用 ReturnType<typeof this.methodName> - Iván Sánchez
11
@IvánSánchez 在一个 Animal 类中,你可以使用 ReturnType<Animal['methodName']> 或者在类方法中使用 ReturnType<this['methodName']> - kube
7
获取静态方法的返回类型:ReturnType<(typeof Animal)['methodName']>, 其中Animal是类名,methodName为该静态方法的名称。 - kube
对于任何想知道的人,如果你的函数使用了泛型,这个方法可能无法解决你的问题。 - Seph Reed

17

5
最近的严格空值检查使得以下代码避免了 (undefined | ...) 部分: let r = true ? (undefined as never) : someFunction(); type ReturnType = typeof r; - Magnus Hiie

13

根据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,但这会导致类型“null”不能转换为类型“T”的错误。
最好的部分是作为fakeReturn参数给出的函数实际上没有被调用。
在TypeScript 2.5.3中进行了测试。
TypeScript 2.8引入了一些预定义的条件类型,包括ReturnType<T>,它获取函数类型的返回类型。
const hello = () => 'World'

type Hello = ReturnType<typeof hello> // string

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接