У меня есть следующая функция, которая работает как ramdas isEmpty , но с учетом моих собственных потребностей:
/**
* Checks if a value is empty.
* It will return true for the following cases:
* null, undefined, empty string, empty Set, empty Map, an object without properties.
* @param input Can be any value.
* @example
*
* isEmpty([1, 2, 3]); //=> false
* isEmpty([]); //=> true
*
* isEmpty(''); //=> true
*
* isEmpty(null); //=> true
* isEmpty(undefined); //=> true
*
* isEmpty({}); //=> true
*
* isEmpty(new Set([1, 2, 3])); //=> false
* isEmpty(new Set()); //=> true
*
* isEmpty(0); //=> false
*
* isEmpty(new Date()); //=> true
* isEmpty(Date.now()); //=> false
*/
export const isEmpty = (input: any): boolean => {
const isMapOrSet = input instanceof Map || input instanceof Set;
return input === null
|| input === undefined
|| (input instanceof String ? input.length > 0 : false)
|| (isMapOrSet ? input.size === 0 : false)
|| (!isMapOrSet && input instanceof Object ? Object.keys(input).length === 0 : false);
};
Использование этой функции довольно просто, но я недоволенboolean
тип возвращаемого значения, поскольку TypeScript не может определить нулевые проверки, предоставляемые этой функцией.
Например, следующий код вполне подходит, но TypeScript будет жаловаться на возможное значение NULL при вызове someResult[0]
.
const someResult: [] | null = getStuffFromAPI();
const x = isEmpty(someResult)
? {}
: someResult[0]; // TypeScript will complain about a possible _null_ here.
Итак, вопрос: Как улучшить сигнатуру функции, чтобы TypeScript мог правильно определить тип возвращаемого значения?
Я пытался смоделировать тип возвращаемого пользователем значенияиспользуя условные типы , но я не мог понять, как это правильно.
Чтобы сделать на 100% понятным то, что я ищу, вот некоторый псевдокод (обратите внимание, что HasNoElements
и IsEmpty
не существуют в TS):
type IsEmpty<T> =
T extends null | undefined ? true :
T extends Map & HasNoElements ? true :
T extends Set & HasNoElements ? true :
T extends String & IsEmpty ? true :
T extends Object & IsEmpty ? true :
false;
Возможно, я обдумываю это, но я бы хотел немного расширить свой кругозор.