【问题标题】:Typescript: Return type of function based on input value (enum)Typescript:根据输入值(枚举)返回函数的类型
【发布时间】:2023-03-28 20:40:02
【问题描述】:

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

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

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 的方法,但这似乎有点过多的开销。

任何见解将不胜感激!

【问题讨论】:

    标签: typescript enums typescript-typings overloading conditional-types


    【解决方案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'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 2021-12-11
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多