TypeScript Converter qualquer array tipado em um array de valor-chave genérico

Sep 24 2020

Tenho vários dados de matriz parecidos com estes:

Countries: [{code: "USA", countryDesc: "United States"},{code: "MEX", countryDesc: "Mexico"}]

e

States: [{code: "NY", countryDesc: "New York"},{code: "VA", stateDesc: "Virginia"}]

O que desejo fazer é converter o código / countryDesc específico ou code / stateDesc em um par de valores-chave "genérico" para usar. Portanto, minha rotina de conversão me forneceria:

[{key:"USA", value:"United States"},{key:"MEX", value:"Mexico"}]

e

[{key:"NY", value:"New York"},{key:"VA", value:"Virginia"}]

Meu objetivo é escrever uma função que receba o array e os nomes das propriedades da chave e do valor e os converta em um array com uma chave e um valor em vez dos outros nomes de propriedade.

O que eu tenho é isto:

export interface IAnyArray {
  key: string;
  value: string;
}

const convertToKeyValue = (
  array: IAnyArray[],
  keyname: string,
  valuename: string
) => {
  if (array && array.length > 0) {
    return array.map((a) => {
      return { key: a[keyname], value: array[valuename] };
    });
  }
};

Estou recebendo o erro:

O elemento tem implicitamente um tipo 'qualquer' porque a expressão do tipo 'string' não pode ser usada para indexar o tipo 'IAnyArray'. Nenhuma assinatura de índice com um parâmetro do tipo 'string' foi encontrada no tipo 'IAnyArray'.ts (7053)

para um [nome-chave] e um [nome do valor] na função.

É assim que eu faria, específico para a entrada, mas gostaria de um mecanismo "genérico", se possível:

  const convertCountriesToKeyValue = (
    countries: { code: string; countryDesc: string }[]
  ) => {
    return countries.map((country) => {
      return { key: country.code, value: country.countryDesc };
    });
  };

Pesquisei na web e não consigo encontrar nada útil para ajudar com este problema.

Eu agradeceria qualquer ajuda nisso. Obrigado.

Respostas

2 ritaj Sep 24 2020 at 21:07

Se entendi sua pergunta corretamente, você deseja passar uma matriz de objeto de quaisquer nomes de propriedade, mas retornar IAnyArray. Talvez algo assim?

const convertToKeyValue = <T extends any>(
    array: T[],
    keyname: keyof T,
    valuename: keyof T
) => {
    return array.map((a) => {
        return { key: a[keyname], value: a[valuename] };
    });
};

const countries = [{ code: "USA", countryDesc: "United States" }, { code: "MEX", countryDesc: "Mexico" }];

const keyValueCountries = convertToKeyValue(countries, "code", "countryDesc");

Parque infantil

1 jlouzado Sep 24 2020 at 21:08

De acordo com sua descrição, isso deve ser o que você está procurando:

const convertToKeyValue = (
  array: IAnyArray[],
  keyName: string,
  valueName: string
) => {
  return array.map((a) => {
    return {[keyName]: a.key, [valueName]: a.value}
  })
}

Link Playground

Observação lateral: eu recomendaria manter keyNamee valueNamecomo os dois primeiros parâmetros (como fiz no playground), para tornar a função mais combinável se você decidir curry no futuro.