打字稿:基于输入值的函数的返回类型(枚举) [英] Typescript: Return type of function based on input value (enum)

查看:113
本文介绍了打字稿:基于输入值的函数的返回类型(枚举)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm storing some settings into local storage and I would like to type the responses when I get (and ideally also insert) values from/to the storage.

据我所见,最好的方法似乎是使用函数重载。所以这就是我现在所拥有的并且可以正常工作:

From what I've seen, the best way seems to be to use function overloading. So this is what I have now and it works:

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)
}

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

The thing that I don't like about this solution is that it's possible to forget adding a new element in the enum to the overload type definitions. Is there a way to enforce that all enum values are handled? Or is there maybe a better way to do this altogether?

我认为这很简单,从值 hasOnboarded映射c $ c>返回类型 boolean 等,但这显然不那么容易。

I thought this would be a simple thing, a mapping from value hasOnboarded to return type boolean etc, but it's obviously not that easy.

在我看来条件类型可能会解决此问题问题,但我无法完全了解它的工作原理。

It looks to me like conditional types might solve this problem, but I can't quite wrap my head around how it works.

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

I also saw this approach, but this seems like a little too much overhead.

任何见识将不胜感激!

推荐答案

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

You can use an extra type to map between the enum and the promise return type. We then add a generic parameter to getSettings that extends the SettingsKey enum and use the generic type to index into the mapping type. The generic parameter will be inferred based on the enum member we specify as an argument.

如果映射类型不包含枚举的所有键,则将出现错误

If the mapping type does not contain all keys of the enum we will get an error on the function.

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> {
   ///...
}

这篇关于打字稿:基于输入值的函数的返回类型(枚举)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆