繁体   English   中英

推断由包含 object 类型声明为“any”的函数返回类型

[英]Infer a functions return type that is declared as `any` by the containing object type

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

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

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

通过将该类型应用于我的 object,我无法推断该对象函数的返回类型,因为我必须将其键入为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推断出推断的有效负载(例如typeloading )。 这个想法对共享代码库来说可能过于保护了吗?

分配给 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,
  }),
};

操场

在某些情况下,您更喜欢键入而不是推断。 在这里,如果您打算将 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM