Параметры Typescript - общий массив объектов и массив ключей объекта (частичный) - PullRequest
1 голос
/ 28 мая 2019

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

данные:

[
  {"firstName": "Jane", "lastName": "Doe"},
  {"firstName": "John", "lastName": "Doe"}
]

поля:

["firstName"]

результат:

[["Jane"], ["John"]]

К настоящему времени у меня есть функция, которая обеспечивает желаемый результат, но я не уверен, как лучше обрабатывать типы.

mapToCsvData: (data: { [key: string]: any }[], fields: string[]) => {
  return data.map((item: any) => {
    return fields.map(field => item[field]);
  });
}

Я пробовал некоторые варианты следующего фрагмента, но получаю ошибку.

mapToCsvData: <T extends object>(data: T[], fields: keyof T[]) => {
Property 'map' does not exist on type 'number'.

1 Ответ

0 голосов
/ 28 мая 2019

Вам понадобится дополнительный параметр типа для захвата фактического кортежа передаваемых ключей. Вы можете сопоставить этот кортеж с соответствующими типами свойств в T. Все работает очень хорошо:

type MapKeyTupleToProps<T, P extends [keyof T] | Array<keyof T>> = {
    [K in keyof P]: P[K] extends keyof T ? T[P[K]] : never
}
const m = {
    mapToCsvData: <T, P extends [keyof T] | Array<keyof T>>(data: T[], fields: P): MapKeyTupleToProps<T, P> => {
        return data.map((item: any) => {
            return fields.map(field => item[field]);
        }) as any;
    }
}

const data = [
    {"firstName": "Jane", "lastName": "Doe", age: 0},
    {"firstName": "John", "lastName": "Doe", age: 0}
]

let r = m.mapToCsvData(data, ["firstName", "lastName"]) // [string, string]
let r2 = m.mapToCsvData(data, ["firstName", "age"]) //[string, number]
...