Typescript:根据输入值(枚举)返回函数的类型

Posted

技术标签:

【中文标题】Typescript:根据输入值(枚举)返回函数的类型【英文标题】:Typescript: Return type of function based on input value (enum) 【发布时间】:2019-03-06 16:27:26 【问题描述】:

我正在将一些设置存储到本地存储中,并且我想在从存储中获取(并且最好还插入)值时输入响应。

据我所知,最好的方法似乎是使用函数重载。所以这就是我现在所拥有的并且它有效:

export enum SettingsKey 
  hasOnboarded = 'hasOnboarded',
  phoneNumber = 'phoneNumber'


export async function getSetting(storage: Storage, key: SettingsKey.phoneNumber): Promise<string>
export async function getSetting(storage: Storage, key: SettingsKey.hasOnboarded): Promise<boolean>
export async function getSetting(storage: Storage, key: any) 
  return storage.get(key)

我不喜欢这个解决方案的一点是,它可能会忘记在枚举中添加一个新元素到重载类型定义中。有没有办法强制处理所有枚举值?或者有没有更好的方法来做到这一点?

我认为这将是一件简单的事情,从值 hasOnboarded 到返回类型 boolean 等的映射,但这显然不是那么容易。

在我看来 conditional types 可能会解决这个问题,但我无法完全理解它是如何工作的。

我也看到了this 的方法,但这似乎有点过多的开销。

任何见解将不胜感激!

【问题讨论】:

【参考方案1】:

您可以使用额外的类型在枚举和承诺返回类型之间进行映射。然后我们向getSettings 添加一个泛型参数,扩展SettingsKey 枚举并使用泛型类型来索引映射类型。泛型参数将根据我们指定为参数的枚举成员进行推断。

如果映射类型不包含枚举的所有键,我们将在函数上得到错误。

export enum SettingsKey 
    hasOnboarded = 'hasOnboarded',
    phoneNumber = 'phoneNumber'


type SettingsKeyReturnType = 
    [SettingsKey.hasOnboarded]: boolean,
    [SettingsKey.phoneNumber]: string

export async function getSetting<K extends SettingsKey>(storage: Storage, key: K): Promise<SettingsKeyReturnType[K]> 
    return storage.get(key)

let a = getSetting(window.localStorage, SettingsKey.phoneNumber); // Promise<string>
let b = getSetting(window.localStorage, SettingsKey.hasOnboarded); // Promise<booelan> 

// We can also define a set function in a similar way
export async function setSetting<K extends SettingsKey>(storage: Storage, key: K, value: SettingsKeyReturnType[K]): Promise<void> 
   ///...

【讨论】:

谢谢!这看起来很干净,正是我想要的:)。我什至可以省略 export async function getSetting(storage: Storage, key: any) 并将其缩短一点。 @AndreasGassmann 是的,这应该也可以,我没有重新评估是否需要这样做。我会合并反馈:) 为了完整起见,您可能还想添加setSetting,如果添加, value: SettingsKeyReturnType[K]): Promise&lt;any&gt;,其工作方式相同。你不知道你让我多么开心:) @AndreasGassmann 添加了它,如果没有有用的值被 rerutned,你可能想要返回 Promise @TitianCernicova-Dragomir 这有一些 Typescript 版本限制或标志限制吗?当我尝试使用它时,TS 说:Type 'K' cannot be used to index type 'SettingsKeyReturnType'

以上是关于Typescript:根据输入值(枚举)返回函数的类型的主要内容,如果未能解决你的问题,请参考以下文章

如何根据枚举参数返回不同的类型

Typescript 枚举作为参数类型允许无效值

具有通用联合约束的 TypeScript 函数返回值

用于将字符串枚举成员转换为枚举的Typescript函数

TypeScript入门-枚举类型推论

TypeScript 之 函数