Without a minimum reproducible example including the type definitions for this.con
as well as the particular sort order you'd like to see (if an element of this.con
is not defined, should it sort in the same place as if it were defined with an empty lastname
? or somewhere else?), it's hard to be sure, but assuming it's something like:
declare const con: Array<{
lastname?: string | null
} | null | undefined>;
then you can use the optional chaining and nullish coalescing operators introduced in TypeScript 3.7 to get the following one-liner:
con.sort((a, b) => (a?.lastname ?? "").localeCompare(b?.lastname ?? ""));
The optional chaining in a?.lastname
is similar to (a != null ? a.lastname : undefined)
, and the nullish coalescing expr ?? ""
is similar to (expr != null ? expr : "")
. So that together produces something similar to
con.sort((a, b) => ((a || {}).lastname || "").localeCompare((b || {}).lastname || ""));
which is uglier but should work in TS3.6 and below. Both of these make the elements null
, {lastname: undefined}
, {lastname: null}
, and {lastname: ""}
all interchangeable in terms of the sort order. If you want to see those sorted in some particular order with respect to each other or with respect to elements with non-empty lastname
properties, then you should specify that in the question.
Let's see how it acts:
const con: Array<{ lastname?: string | null } | null | undefined> = [
{ lastname: "" },
{ lastname: "B" },
{ lastname: null },
null,
{ lastname: "A" },
{},
{ lastname: "C" }
]
console.log(JSON.stringify(con));
// [{"lastname":""},{"lastname":"B"},{"lastname":null},null,{"lastname":"A"},{},{"lastname":"C"}]
Sorting with the TS3.7 code:
const newCon = con.slice();
newCon.sort((a, b) => (a?.lastname ?? "").localeCompare(b?.lastname ?? ""));
console.log(JSON.stringify(newCon));
// [{"lastname":""},{"lastname":null},null,{},{"lastname":"A"},{"lastname":"B"},{"lastname":"C"}]
and with the TS3.6- code:
const newCon2 = con.slice();
newCon2.sort((a, b) => ((a || {}).lastname || "").localeCompare((b || {}).lastname || ""));
console.log(JSON.stringify(newCon2));
// [{"lastname":""},{"lastname":null},null,{},{"lastname":"A"},{"lastname":"B"},{"lastname":"C"}]
both yields the same ordering, where the "empty" elements are moved to the front and in the original order from the array (you can't count on Array.prototype.sort
being stable but it usually is), and the rest of the elements are sorted in order of the lastname
property.
Playground link to code
Anyway, hope that helps; good luck!