typescript Преобразование, сужение string[] | string к типу string. Переход от массива к единственному элементу

Проблема

Type 'string | string[] | null' is not assignable to type 'string | null'.
Type 'string[]' is not assignable to type 'string'. TS2322

Есть код:

const params = queryString.parse(history.location.search);

    let initFilterValue: string | null = null;

    if ((typeof params[filterParamName] === 'string')) {
      initFilterValue = params[filterParamName]; // ошибка
    }

При этом типы для queryString.parse() определены так:

export function parse(query: string, options?: ParseOptions): ParsedQuery;
export interface ParsedQuery<T = string> {
	[key: string]: T | T[] | null;
}

Т.е. требуется преобразование string | string[] | null (массива строк, строки или null) к string, так чтобы typescript не ругался на происходящее

Причина

Судя по всему typescript не может проверить "динамическое" выражение:

params[filterParamName]

и поэтому нужно:

  1. записать его значение предварительно в отдельную переменную
  2. и потом уже использовать typeof

Решение


const params = queryString.parse(history.location.search);
let initFilterValue: string | null = null;
let filerValue = params[filterParamName];
if ((typeof filerValue === 'string')) {
      initFilterValue = filerValue;
    }
vedro-compota's picture

причина "отказа" от проверки, без создания отдельной переменной может быть в том, что свойство к которому мы обращаемся может быть, например, геттером - а значит (в теории) возвращать неодинаковые значения при одинаковом обращении к свойству дважды (при проверке и чтении):

if ((typeof params[filterParamName] === 'string')) {
      initFilterValue = params[filterParamName];
    }

а вот запись значения в переменную делает его стабильным, что позволяет вызову typeof надежно проверить типа значения.

_____________
матфак вгу и остальная классика =)