Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

106
Views
El tipo de conjunto de TypeScript para la matriz de objetos causa un problema al ordenar con localCompare

Obtuve una función simple con una variedad de objetos. En esta matriz siempre habrá al menos una propiedad string .

En el cuerpo, quiero poder seleccionar dinámicamente esa string por key y ordenar con localCompare .

El problema es que las propiedades pueden tener numbers y al hacer localCompare TS se queja.

 ;(() => { type entries = { [key: string]: string | number } const data: entries[] = [ { key: 'bbb', number: 1 }, { key: 'aaa', number: 2} ] // Let's imagine index comes as a parameter const index = 'key' const order: entries[] = data.sort((a, b) => a[index].localeCompare(b[index])) console.log(order) })()

Enlace al patio de juegos de TS

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Solo asegúrese de convertir siempre las propiedades en cadenas:

 ;(() => { type entries = { [key: string]: string | number } const data: entries[] = [ { key: 2, number: 4 }, { key: 'bbb', number: 1 }, { key: 'aaa', number: 2}, { key: 1, number: 3} ] const index = 'key' const order: entries[] = data.sort((a, b) => `${a[index]}`.localeCompare(`${b[index]}`)) console.log(order) })()

O bien, verifique el tipo de los valores:

 ;(() => { type entries = { [key: string]: string | number } const data: entries[] = [ { key: 'bbb', number: 1 }, { key: 'aaa', number: 2} ] const index = 'key' const order: entries[] = data.sort((a, b) => { const valA = a[index]; const valB = b[index]; return typeof valA === 'number' && typeof valB === 'number' ? valA - valB : `${valA}`.localeCompare(`${valB}`); }); console.log(order) })()

about 4 years ago · Juan Pablo Isaza Report

0

Según sus comentarios, creo que está diciendo que sabe que a[index] siempre será una cadena debido a la lógica de su código, pero el problema es que TypeScript no lo sabe (porque la firma del objeto dice que puede ser una cadena o un número).

Para tranquilizar a TypeScript, tiene al menos un par de opciones:

Use una función de aserción de tipo:

 function assertIsString(value: any): asserts value is string { if (typeof value !== "string") { throw new Error(`Expected a string, but got ${typeof value}`); } }

Después:

 const order: entries[] = data.sort((a, b) => { const avalue = a[index]; const bvalue = b[index]; assertIsString(avalue); assertIsString(bvalue); return avalue.localeCompare(bvalue); });

Parque infantil actualizado

Esto también tiene la ventaja de generar un error explícito si el código no garantiza que el nombre de la propiedad sea solo el nombre de una propiedad de cadena.

Usar una aserción de tipo

Si no desea la sobrecarga (muy mínima) de la función de aserción, simplemente puede anular TypeScript:

 const order: entries[] = data.sort((a, b) => (a[index] as string).localeCompare(b[index] as string));

Parque infantil actualizado

Ambas cosas

Si sabe que sus objetos son homogéneos, puede combinar los dos enfoques, por ejemplo, usando la función de aserción solo en la primera entrada:

 if (data.length > 1) { assertIsString(data[0][index]); } const order: entries[] = data.sort((a, b) => (a[index] as string).localeCompare(b[index] as string));

Parque infantil actualizado

De esa manera, obtiene un buen error explícito, pero no tiene la sobrecarga de verificar durante la sort .

about 4 years ago · Juan Pablo Isaza Report

0

Su TS no sigue las pautas de TS.

Aquí hice una función sortByProp , que usa keyof para que pueda seleccionar fácilmente la propiedad que desea usar para su clasificación.

Puedes probar el código aquí: Playground .

Cuando descubra cómo filtrar los tipos de propiedades, actualizaré el código nuevamente.

 interface Entrie { key: string; number: number | string; random?: boolean; } // Used so I can filter the keys by the type I want. In this case string | number; type FilteredKeys<T, U> = { [P in keyof T]: T[P] extends U ? P : never }[keyof T]; const data: Entrie[] = [ { key: 'bbb', number: 1 }, { key: 'aaa', number: 3 }, { key: 'aba', number: 2 } ]; function sortByProp<T, F>(arr: T[], prop: FilteredKeys<T, F>) { if (typeof prop == 'string') return arr.sort((a, b) => { if (a[prop] < b[prop]) return -1; if (a[prop] > b[prop]) return 1; return 0; }); return arr.sort((a: any, b: any) => a[prop] - b[prop]); } console.log("SortByKey:", sortByProp<Entrie, string | number>(data, "key")); console.log("SortByNumber:", sortByProp<Entrie, string | number>(data, "number"));
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!