skip to Main Content

Let’s assume we have a type and an array:

type Fruit = 'apple' | 'orange' | 'pineapple'

const initialFruits: Fruit[] = ['pineapple', 'apple', 'orange']

If I try to sort the array before assign the value I get an error:

const initialFruits: Fruit[] = ['pineapple', 'apple', 'orange'].sort()

// Type 'string[]' is not assignable to type 'Fruit[]'.

I found one way to save types after sorting, but it looks weird:

const initialFruits: Fruit[] = [
  'pineapple' as const,
  'apple' as const,
  'orange' as const
].sort()

Is there more convenient way to fix that?

2

Answers


  1. Array is sorted according to Fruit type.

    type Fruit = 'apple' | 'orange' | 'pineapple'
    
    const initialFruits: Fruit[] = ['pineapple', 'apple', 'orange'].sort() as Fruit[];
    
    const sortedFruits: Fruit[] = ['pineapple', 'apple', 'orange'].sort((a, b) => {
      return initialFruits.indexOf(a) - initialFruits.indexOf(b);
    }) as Fruit[];
    
    Login or Signup to reply.
  2. If you want your code to be type safe without changing the runtime behavior (e.g., without calling sort() in a separate statement), then my suggestion would be to use the satisfies operator to give the compiler context that the array literal ['pineapple', 'apple', 'orange'] will be treated as a Fruit[]. Like this:

    const initialFruits =
        (['pineapple', 'apple', 'orange'] satisfies Fruit[]).sort()
    

    That compiles. ['pineapple', 'apple', 'orange'] satisfies Fruit[] results in an expression of type ("apple" | "orange" | "pineapple")[] (which is equivalent to Fruit[] but wouldn’t be if you, for example, wrote ['apple', 'orange'] satisfies Fruit[], where you’d get a value of type ("apple" | "orange")[]). And so you’ve still got a mutable array type, which is known to have a sort() method. So you get:

    initialFruits
    //^? const initialFruits: ("apple" | "orange" | "pineapple")[]
    

    which should work for you.


    Note that this is a stronger guarantee of type safety than using a type assertion like as Fruit[]. Compare:

    (['pineapple', 'apple', 'cherry'] satisfies Fruit[]).sort(); // error!
    // -------------------> ~~~~~~~~
    // Type '"cherry"' is not assignable to type 'Fruit'.
    
    (['pineapple', 'apple', 'cherry'] as Fruit[]).sort(); // no error!
    

    Playground link to code

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search