1

I have tuples in the form (Status and priority)

[State,prio]

States are defined so:

enum State {
    A = "A",
    B = "B",
    C = "C"
   ...
}

Now i want to sort an array of State tuples by priority using the sort function:

compareFn(a:[State,number], b:[State,number]):number {
     if (a[1] > b[1]) {
         return -1;
     } else if (a[1] < b[1]) {
         return 1;
     }
     return 0;
}

This is the array:

let prio =  [
   [State.A, 23], 
   [State.B, 2],
   [State.C, 5]
]

When invoking the array sort function with the compareFn callback

prio.sort(compareFn)

the following error is given:

Argument of type '(a: [State, number], b: [State, number]) => number' is not assignable to parameter of type '(a: (number | State)[], b: (number | State)[]) => number'. Types of parameters 'a' and 'a' are incompatible. Type '(number | State)[]' is not assignable to type '[State, number]'.

I have no idea where this data type comes from and how to resolve this:

(number | State)[]

Any ideas?

2
  • 1
    TS doesn't know that prio is supposed to be an Array<[State, number]>. It infers the type as (State | number)[][] because usually people don't want their arrays to be interpreted as tuple types. If you don't like the inference, you can just annotate the type like let prio: Array<[State, number]> and it will work. Does this fully address the question? If so I'll write an answer or find a duplicate. If not, what's missing? Commented Oct 17 at 16:24
  • TS uses a 'best common type' algorithm. typescriptlang.org/docs/handbook/… Commented Oct 18 at 8:00

2 Answers 2

4

Answer by @nseaprotector is correct. You could also inline the compare directly if you prefer, see below:

enum State {
  A = "A",
  B = "B",
  C = "C"
}

const prio: [State, number][] = [
  [State.A, 23],
  [State.B, 2],
  [State.C, 5]
];

prio.sort((a, b) => b[1] - a[1]);
console.log(prio);
Sign up to request clarification or add additional context in comments.

3 Comments

I'm not sure how this answers the question. The part that needs to be done is the type annotation on prio, but you're not talking about that. Instead you're talking about rewriting the sorting callback... yet the question doesn't ask about it, nor does it solve a problem in the question. Maybe this should be just a comment on the other answer?
The error is already solved. I just added the updated version of compareFn function. If you check my answer, this would solve the error which posted and also give inline function for compareFn.
So do you agree that this doesn't attempt to answer the question which is "already solved"? If so, then it shouldn't be an answer post, but maybe added as a comment. I
2

I guess You must explicitly type the array as an array of [State, number] tuples:

const prio: [State, number][] = [
  [State.A, 23],
  [State.B, 2],
  [State.C, 5]
];

Now your compare function will work fine:

function compareFn(a: [State, number], b: [State, number]): number {
  if (a[1] > b[1]) return -1;
  if (a[1] < b[1]) return 1;
  return 0;
}

prio.sort(compareFn);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.