Как привести запись redis к типу typescript?

#typescript #redis

#typescript #redis

Вопрос:

У меня есть класс, который хранит хэш-карту в экземпляре redis примерно так.

 static async store(obj: KeyObject) {
    return client.hmset(`obj:${obj.objKey}`, {
      id: obj.id, // number
      ownerId: obj.ownerId.toBase58(), // string
      key: obj.key, // number
    });
  }
 

Когда я получаю get эту строку из redis, она возвращает

 { 
  id : '1',
  ownerId: '2',
  key: '3'
}
 

Я хочу получить id параметр как a number (как это было, когда я его вводил)

Я могу использовать его конкретно как число, когда использую его в своей программе, но я скорее просто применяю его ко всему объекту, когда получаю его как

 client.hgetall(`obj:${objKey}`) as KeyObject
 

возможно ли это?

Спасибо!

Ответ №1:

Нет, это невозможно, это не из-за Typescript. Когда Redis возвращает вам идентификатор, это НЕ число (это деталь реализации Redis, которая не делает различий между строками и числами, ничего общего с js или ts). Вам нужно будет вручную изменить его обратно:

 const row = { 
  id : '1',
  ownerId: '2',
  key: '3'
}

row.id = Number(row.id)
 

Если у вас есть несколько ключей, которые вам нужно превратить обратно в число, и вы чувствуете себя ленивым, вы можете создать вспомогательную функцию:

 type ConvertKeys<Object, Keys extends Array<keyof Object>, To> = { 
  [P in keyof Object]: P extends Keys[number] ? To : Object[P]
}

function convertKeys<O, K extends Array<keyof O>, T>(
  converter: (arg: any) => T,
  obj: O, 
  ...keys: K
): ConvertKeys<O, K, T> {
  // type system is too stupid to see how this transformation works
  const copy = Object.assign({}, obj) as any
  keys.forEach(k => copy[k] = converter(copy[k]))
  return copy
}
 

А затем использовать его:

 const fixedRow = convertKeys(Number, row, "id", "key")
const id: number = fixedRow.id; // A-OK!