Когда значение имеет тип-объединение, доступны только те операции, которые есть у всех вариантов сразу. Чтобы получить доступ к специфичным методам, нужно доказать компилятору, какой именно вариант перед нами. Это называется сужением типа (narrowing).
Компилятор ругается: «Property 'toUpperCase' does not exist on type 'string | number'». Метод есть у строки, но не у числа, а функция вызывается и с тем, и с другим.
Самый прямой способ различить примитивы это оператор typeof. TypeScript понимает такие проверки: внутри ветки if (typeof x === "string") он считает x строкой, а в else вычёркивает строку из объединения и оставляет число. Никаких приведений типов писать не нужно, компилятор следит за потоком выполнения сам.
Тесты проверяют оба сценария: formatId("abc-123") должен вернуть "ABC-123", а formatId(42) строку "42".
Перепиши тело formatId так, чтобы строковый идентификатор возвращался в верхнем регистре, а числовой превращался в строку. Сигнатуру функции и вызовы внизу файла менять не нужно.