【问题标题】:Infer a functions return type that is declared as `any` by the containing object type推断包含对象类型声明为“any”的函数返回类型
【发布时间】:2020-09-28 21:24:57
【问题描述】:

我想为函数对象创建一个类型,只允许特定枚举的字符串成员作为键:

enum ESharedActions {
  SET_LOADING = 'SET_LOADING',
  SET_LOGGED_IN = 'SET_LOGGED_IN',
}

type SharedActions = { [key in ESharedActions]: (...args: any) => any }

通过将该类型应用于我的对象,我无法推断该对象函数的返回类型,因为我必须在SharedActions 类型中将其键入为any。

const sharedActions: SharedActions = {
  [ESharedActions.SET_LOADING]: (loading: boolean) => ({
    type: ESharedActions.SET_LOADING,
    loading,
  }),
  [ESharedActions.SET_LOGGED_IN]: (loggedIn: boolean) => ({
    type: ESharedActions.SET_LOADING,
    loggedIn,
  }),
};

const foo = sharedActions[ESharedActions.SET_LOADING](true) // infers to `any`, should infer to { type: ESharedActions, loading: boolean }

是否可以通过使用类型/接口而不覆盖其函数返回类型来确保 sharedActions 结构,以便 TypeScript 能够正确推断它?

编辑: 我觉得我的意图还没有完全清楚。我的重点是防止有人在sharedActions 中使用随机密钥,但仍然可以推断出foo 的有效载荷(例如type 和loading)。对于共享代码库,这个想法是否过于保护?

【问题讨论】:

  • 所以你不想改变SharedActions的定义(?
  • 我暂时将其更改为(...args: any) => { type: ESharedActions, [key: string]: any },但这样foo 中只有type 可用,剩余的有效负载(例如loading、loggedIn)会丢失。
  • 你想限制哪一部分,..args 还是返回类型?

标签: typescript


【解决方案1】:

分配给 foo 时只需删除您的 ShareActions 声明:

const sharedActions = {
  [ESharedActions.SET_LOADING]: (loading: boolean) => ({
    type: ESharedActions.SET_LOADING,
    loading,
  }),
  [ESharedActions.SET_LOGGED_IN]: (loggedIn: boolean) => ({
    type: ESharedActions.SET_LOADING,
    loggedIn,
  }),
};

Playground

在某些情况下,您更喜欢打字而不是推理。在这里,如果您打算将 sharedActions 视为 SharedActions(意味着将 (...args: any) => any 作为值对象),那么就像您在示例中所做的那样。 如果您的意图是操纵 sharedActions 的内容,则推断类型而不声明 SharedActions

然后,当您确实需要将其用作类型时,请稍后再进行转换:

const sharedActions = {
  [ESharedActions.SET_LOADING]: (loading: boolean) => ({
    type: ESharedActions.SET_LOADING,
    loading,
  }),
  [ESharedActions.SET_LOGGED_IN]: (loggedIn: boolean) => ({
    type: ESharedActions.SET_LOADING,
    loggedIn,
  }),
};

// use sharedAction
// doStuff(foo.loading)


// cast finally if your only goal is to expose the result as a SharedActions type/interface
// return sharedAction as SharedActions

【讨论】:

  • 我明白了——我只是觉得有必要通过SharedActions 类型强制枚举密钥来“保护”sharedActions' 结构,因此没有人能够使用一些随机密钥。也许我在这里过度保护了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多