Tengo una función en Typescript en la que, a partir de una cadena, devuelve la clave del objeto que contiene esa variable.
Estoy usando Array.prototype.includes() para verificar que la variable existe, esto puede devolver true o false , por lo que escribir la variable resultante como una string me da un error de tipeo.
Este es el error:
Type 'unknown' cannot be assigned to type 'string'Esta es mi función:
let testData = { data1: ['CAR','PLANE'], data2: ['COUNTRY','CITY'] }; let asset = 'car'; function resKey(asset) { let res = Object.keys(testData).find(key => { const value = testData[key] return value.includes(asset.toUpperCase()) }) return res } console.log(resKey(asset));Solo voy a pasarle los valores que están en el objeto, por lo que no necesito verificar si existe.
Mi problema : ¿cómo puedo modificar la función para que solo devuelva la clave sin la necesidad de verificar si existe?
Como señalé en los comentarios, puede hacer que su función actual sea compatible con TypeScript al darle algunas anotaciones de tipo.
Alternativamente, puede evitar el find() creando un Map de testData y simplemente recuperando la key por value directamente. Tenga en cuenta que si hay valores duplicados entre diferentes matrices de activos, esto devolverá la clave de la última instancia (a diferencia de find() , que devolverá la clave de la primera instancia).
let testData = { data1: ['CAR', 'PLANE'], data2: ['COUNTRY', 'CITY'] }; let asset = 'car'; function resKey(asset) { const resMap = new Map(Object.entries(testData).flatMap(([k, v]) => v.map(a => [a, k]))); return resMap.get(asset.toUpperCase()); } console.log(resKey(asset)); Para evitar crear un nuevo Map en cada llamada de la función, puede emplear un poco de curry.
function resKeyFactory(data) { const resMap = new Map( Object.entries(data) .flatMap(([k, v]) => v.map(a => [a, k])) ); return (asset) => resMap.get(asset.toUpperCase()); } const testData = { data1: ['CAR', 'PLANE'], data2: ['COUNTRY', 'CITY'] }, asset = 'car', resKeyTestData = resKeyFactory(testData); console.log(resKeyTestData(asset)); console.log(resKeyTestData('city')); Typescript requiere un objetivo lo suficientemente alto como para aceptar el área de juegos flatMap .
Podrías usar Object.entries() y find() .
let testData = { data1: ['CAR', 'PLANE'], data2: ['COUNTRY', 'CITY'] }; function resKey(data, asset) { return Object.entries(data).find(([_, v]) => { return v.includes(asset.toUpperCase()) })?.[0] || "no key found"; } console.log(resKey(testData, "car")); console.log(resKey(testData, "something")); console.log(resKey(testData, "city"));Si desea escribir, se vería algo como esto.
interface IData { data1: string[]; data2: string[]; } let testData: IData = { data1: ['CAR', 'PLANE'], data2: ['COUNTRY', 'CITY'] }; function resKey(data: IData, asset: string): string { return Object.entries(data).find(([_, v]) => { return v.includes(asset.toUpperCase()) })?.[0] || "no key found"; }