Typescript возвращает тип функции из параметра - PullRequest
1 голос
/ 09 января 2020

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

, если у меня есть эта функция:

function getQueries(query) {
  return Object.keys(query).reduce((list, key) => {
    return { ...list, [key]: query[key].length > 3  }
  }, {})
}

, в которой я хочу передать объект, подобный этому

getQueries({ first: 'dsds', second: 'dsdsds', third: 'ds' })

и я хочу, чтобы тип этой функции возвращал точно такую ​​же структуру, которую я передаю, но вместо этого с булевыми значениями.

const queries = getQueries({ first: 'dsds', second: 'dsdsds', third: 'ds' })
queries.first // ts error -> Property 'first' does not exist on type '{}'

Как мне подойти к этой типизации?

Ответы [ 3 ]

3 голосов
/ 09 января 2020

Вы ищете обобщенные и сопоставленные типы:

function getQueries<T>(query: T): {[key in keyof T]: boolean} {
}
1 голос
/ 09 января 2020

Мой ответ будет больше для вашего конкретного случая c, мне нужно немного изменить текущий код, чтобы заполнить корректность типа. Рассмотрим следующий код:

type BoolRecord<T extends Record<string, string>> = Record<keyof T, boolean> 
function getQueries<Q extends Record<string, string>>(query: Q): BoolRecord<Q> {
  return Object.keys(query).reduce((list, key) => {
    return { ...list, [key]: query[key as keyof Q].length > 3  }
  }, {} as BoolRecord<Q>)
}

const result = getQueries({ first: 'dsds', second: 'dsdsds', third: 'ds' });
// Record<"first" | "second" | "third", boolean>

Я предположил, что функция getQueries должна получить в качестве объекта аргумента строковые значения, поскольку вы внутри используете свойство length (проверки реализации .length>3). Таким образом, тип аргумента функции Record<string, string>. Следующим шагом является определение типа возвращаемого значения, и это выполняется с помощью BoolRecord, этот тип берет исходную запись и создает то же самое, но с полями bool, как вы хотели.

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

Интересной частью является BoolRecord, определение которого гласит, что для любой Записи дайте мне запись с теми же ключами (сделано keyof T) с bool в качестве типа значения.

0 голосов
/ 09 января 2020
function getQueries<T>(query: any):{[key in keyof T]: boolean} {
    return Object.keys(query).reduce((list, key) => {
      return { ...list, [key]: query[key].length > 3  }
    }, {}) as {[key in keyof T]: boolean}
  }
...