Ищете однострочник для преобразования x или x [] в x []

Я ищу короткий и действительный однострочный текст TypeScript, который мог бы заменить следующую функцию:

function arrayOrMemberToArray<T>(input: T | T[]): T[] {
  if(Arrary.isArray(input)) return input
  return [input]
}

Втиснуть приведенную выше логику в однострочный тернарный оператор довольно беспорядочно, и его трудно понять при объединении с другими операциями:

const y = (Array.isArray(input) ? input : [input]).map(() => { /* ... */}) // Too messy

Array.concat отлично работает в консоли браузера, но TS этого не позволяет:

const x: number | number[] = 0
const y = [].concat(x)
Error:(27, 21) TS2769: No overload matches this call.
  Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
    Argument of type 'number' is not assignable to parameter of type 'ConcatArray<never>'.
  Overload 2 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
    Argument of type 'number' is not assignable to parameter of type 'ConcatArray<never>'.

3 ответа

Решение

В concatрешение не проверяется типом из-за пустого литерала массива. Вам нужно написать

const arr = ([] as number[]).concat(input);

В качестве альтернативы вы можете использовать flat:

const arr = [input].flat();

Это было бы не только короче, но и предпочтительнее, потому что оно не полагается на свойство concat-spreadable ввода, а фактически проверяет массивы.

Кажется, это работает:

const x: number | number[] = 0
const y = ((): number[] => [])().concat(x)
console.log(y)

Не уверен, зачем вам однострочный, но вы можете просто использовать тернарный оператор:

function arrayOrMemberToArray<T>(input: T | T[]): T[] {
  return Array.isArray(input) ? input : [input];
}
Другие вопросы по тегам