As noted in the comments, you can invert the boolean logic to return early, which is always nicer to read and you can easily extract the switch statement into it's own function. E.g.
updateSort(s: Sort) {
if (s.active === this.personSort.active
&& s.direction === this.personSort.direction) {
return
}
const sortFunc = this.getSortFunc(s.active)
if (s.direction === 'desc') {
this.sliceList.sort((a, b) => sortFunc(b, a))
} else {
this.sliceList.sort(sortFunc)
}
}
getSortFunc(type: string): (a: PersonInfo, b: PersonInfo) => number {
// no need to repeat that as well
const localeCompare = (a: string, b: string) => a.localeCompare(b)
switch (type) {
default:
case 'personName':
return (a, b) => localeCompare(a.name, b.name)
case 'personAddress':
return (a, b) =>
localeCompare(
a.pageTypeDescription.toLocaleString(),
b.pageTypeDescription.toLocaleString()
)
case 'personVisitors':
return (a, b) => a.viewsCount - b.viewsCount
case 'personContacts':
return (a, b) => a.clicksCount - b.clicksCount
}
}
and an example of getting rid of the switch
entirely like noted by @caTS could be
localeCompare = (a: string, b: string) => a.localeCompare(b)
sortsFunctions: Record<string, (a: PersonInfo, b: PersonInfo) => number> = {
personName: (a, b) => this.localeCompare(a.name, b.name),
personAddress: (a, b) =>
this.localeCompare(
a.pageTypeDescription.toLocaleString(),
b.pageTypeDescription.toLocaleString()
),
personVisitors: (a, b) => a.viewsCount - b.viewsCount,
personContacts: (a, b) => a.clicksCount - b.clicksCount,
}
getSortFunc(type: string): (a: PersonInfo, b: PersonInfo) => number {
return this.sortsFunctions[type] ?? this.sortsFunctions.personName
}
There's more you could do, similar to 3limin4t0r you could also refactor into
// fully generic part
type Comparator<T> = (a: T, b: T) => number
const numCompare: Comparator<number> =
(a, b) => a - b
const localeCompare: Comparator<string> =
(a, b) => a.localeCompare(b)
const invert = <T>(comparator: Comparator<T>): Comparator<T> =>
(a, b) => comparator(b, a)
const compareProperties = <T, P>(propExtract: (object: T) => P, comparator: Comparator<P>): Comparator<T> =>
(a, b) => comparator(propExtract(a), propExtract(b))
// specific to the task
const sortFunctions: Record<string, Comparator<PersonInfo>> = {
personName: compareProperties(p => p.name, localeCompare),
personAddress: compareProperties(p => p.pageTypeDescription.toLocaleString(), localeCompare),
personVisitors: compareProperties(p => p.viewsCount, numCompare),
personContacts: compareProperties(p => p.clicksCount, numCompare),
}
const getSortFunc = (type: string) => sortFunctions[type] ?? sortFunctions.personName
const sortsEquals = (a: Sort, b: Sort) => a.active === b.active
&& a.direction == b.direction
class PersonPage {
personSort: Sort
sliceList: PersonInfo[]
updateSort(s: Sort) {
if (sortsEquals(s, this.personSort)) {
return
}
let sortFunc = getSortFunc(s.active)
if (s.direction === 'desc') {
sortFunc = invert(sortFunc)
}
this.sliceList.sort(sortFunc)
}
}