Типизируйте помощник, принимающий один элемент или массив и возвращающий массив
toArray приводит к единой форме значение, которое может прийти либо одним элементом, либо массивом элементов.
Требования:
вызова, без any, без объединения в результате;
- и
toArray(user), иtoArray(users)должны иметь типUser[]— без аргумента типа в месте - входной массив нужно вернуть как есть (не копируя);
- одиночный элемент должен вернуться завёрнутым в массив из одного элемента.
export function toArray(input) {
// ваш код здесь
}
Допишите реализацию.
Объявите function toArray<T>(input: T | T[]): T[]. Компилятор выводит T из любой ветви: и toArray(user), и toArray(users) дают User[]. Внутри Array.isArray(input) сужает объединение, а аргумент типа не нужен.
- ✗Считать, что вывод не может разрешить
Tчерез параметрT | T[] - ✗Возвращать
T[] | T[][], не сузив объединение внутри тела - ✗Браться за перегрузки там, где хватает одного обобщённого union-параметра
- →Что выведется для
TприtoArray(null)и как это исключить? - →Как изменится сигнатура, если на вход может прийти
readonly T[]?
Один обобщённый параметр и union на входе: вывод разбирает обе ветви и даёт один и тот же T.
export function toArray<T>(input: T | T[]): T[] {
return Array.isArray(input) ? input : [input];
}
const a = toArray(user); // User[]
const b = toArray(users); // User[]
Как компилятор выводит T. Кандидаты собираются из обеих ветвей T | T[]: для user: User подходит первая ветвь и даёт T = User; для users: User[] подходит вторая и тоже даёт T = User. Аргумент типа в месте вызова не нужен.
Array.isArray(input) — встроенный type guard: в ветке true тип input сужается до T[], в ветке false — до T. Без этого сужения input остался бы T | T[], и [input] дало бы (T | T[])[].