Общая типизация для некоторых служебных функций - PullRequest
1 голос
/ 09 ноября 2019

У меня есть некоторые служебные функции, к которым я хочу добавить универсальные типы в машинописи, но не могу понять, как это сделать.

(Они основаны на функциональности ramda, но я нене хочу использовать ramda в этом проекте.)

pick:

function pick(keys, object) {
  const result = Object.assign(
    {},
    ...keys.map(k => (k in object ? { [k]: object[k] } : {}))
  );
  return result;
}

reject:

function reject(keys, object) {
  const result = Object.assign(
    {},
    ...Object.keys(object)
      .filter(k => !keys.includes(k))
      .map(k => ({ [k]: object[k] }))
  );
  return result;
}
}

... Я хотел бы использовать их вот так, чтобы машинопись работала с результирующим типом:


type Item = {title: string, description: string}

const test: { [key: string]: Item } = {
  a: { title: 'TitleA', description: 'DescriptionA' },
  b: { title: 'TitleB', description: 'DescriptionB' },
  c: { title: 'TitleC', description: 'DescriptionC' },
  d: { title: 'TitleD', description: 'DescriptionD' }
};

const test1 = pick(['a', 'c'], test) // {a: { title: 'TitleA', description: 'DescriptionA' }, c: { title: 'TitleC', description: 'DescriptionC' }}
const test2 = reject(['a', 'c'], test) // {b: { title: 'TitleB', description: 'DescriptionB' },d: { title: 'TitleD', description: 'DescriptionD' }}

Есть ли у кого-нибудь предложения о том, как добавить универсальную типизацию к этимpick и reject функции?

1 Ответ

2 голосов
/ 09 ноября 2019

Вы можете использовать два параметра общего типа, один для самого объекта и один для выбранных ключей. Затем вы можете добавить границу типа к ключам, чтобы быть подмножеством ключей объекта. Тип возвращаемого значения - это сопоставленный тип ключей, найденных на объекте:

 function pick<O, K extends keyof O>(keys: K[], object: O): { [T in K]: O[T] }

Функцию reject можно набрать аналогично:

 function reject<O, K extends keyof O>(keys: K[], object: O): { [T in keyof O]: T extends K ? undefined : O[T] }
...