Typescript: возвращает тип функции на основе входного значения (enum). - PullRequest
0 голосов
/ 01 октября 2018

Я храню некоторые настройки в локальном хранилище, и я хотел бы напечатать ответы, когда получу (и в идеале также вставлю) значения из / в хранилище.

Из того, что я видел,Лучше всего использовать перегрузку функций.Вот что у меня сейчас и работает:

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 и т. Д., Но это, очевидно, не так просто.

Мне кажется, что условные типы могли бы решить эту проблему, но я не могу полностью понять, как это работает.

Я также видел это подход, но это кажется слишком сложным.

Любая проницательность будет принята с благодарностью!

1 Ответ

0 голосов
/ 01 октября 2018

Вы можете использовать дополнительный тип для отображения между перечислением и типом возврата обещания.Затем мы добавляем универсальный параметр к 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> {
   ///...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...