前言

目前 TS 官方 API 还不支持获取函数返回值类型,但是对于函数式编程流行的当今,这个功能非常的重要,比如我们希望能在使用 redux-thunk 中 getState 或者 mapStateToProps 中 state 时 IDE 提示 state 类型,这时就需要获取 reducer 函数的返回值类型,并且进行联合导出供我们使用。

前置知识

以上几点都能在 TS 文档中找到非常清晰简洁的解释和例子,这里就不花篇幅解释了。

核心代码

  1. // 声明一个泛型类型别名,返回值与泛型类型相同,入参类型不限制。
  2. type Reverse<T> = (arg: any) => T;
  3. // 声明一个泛型方法,入参arg继承泛型约束,返回空对象并断言其类型为T
  4. function returnResultType<T>(arg: Reverse<T>): T {
  5. return {} as T;
  6. }
  7. // 调用returnResultType,传入方法 (arg: any) => 3,获得result返回值
  8. const result = returnResultType((arg: any) => 3);
  9. // 获取result类型并重名为ResultType
  10. type ResultType = typeof result;

代码分析

returnResultType((arg:any)=>3);

调用 returnResultType 时,由于没有显示声明泛型类型,所以 TS 只能通过入参来进行类型推论,接着往下面走:

type Reverse<T> = (arg: any) => T;

由于入参的类型为 Reverse ,通过入参返回值是 3 可以推断出:

type Reverse<number> = (arg: any) => number;

由于 Reverse 的 T 是根据 returnResultType 传入的,所以同理得出:

function returnResultType<number>(arg: Reverse<number>): number {
  return {} as number;
}

由于返回值已经进行类型断言为 number。所以在 typeof result 时,可以得出 number 类型。

该方法确实比较绕,因为存在多个泛型 T 的来回推论和反推论。

~~~

结合 Redux 应用

接下来我们通过 reducer 函数来应用一下:

  1. 首先编写两个简单的 reducer:userReducer 和 loginReducer
/**
* userReducer
*/
const initUserState = {
  name: ''
}

const userReducer = (state = initUserState, action: any) => {
  switch (action.type) { 
    case 'setName':
      return {
        name: 'Larry',
        ...state
      };
    default:
      return state;
  }
}

/**
* loginReducer
*/
const initLoginState = {
  token: ''
}

const loginReducer = (state = initLoginState, action: any) => {
  switch (action.type) { 
    case 'login':
      return {
        token: 'token',
        ...state
      };
    default:
      return state;
  }
}
  1. 在 store 中
const reducers = combineReducers({
  userReducer,
  loginReducer
});

type Reverse<T> = (state: any, action:any) => T;

function returnResultType<T>(arg: Reverse<T>): T {
  return {} as T;
}

const GlobalState = returnResultType(reducers);

type GlobalStateType = typeof GlobalState;

此时的 GlobalStateType 就是我们需要的所有 reducer 函数返回的对象类型。

Typescript之获取函数返回值类型 - 知乎 - 图1

最后得到的类型

最后,导出 GlobalStateType,在我们 mapStateToProps 中使用时就能轻松得到类型:

Typescript之获取函数返回值类型 - 知乎 - 图2


逃~~~
https://zhuanlan.zhihu.com/p/59434318