@theia/core
Version:
Theia is a cloud & desktop IDE framework implemented in TypeScript.
158 lines (134 loc) • 5.73 kB
text/typescript
// *****************************************************************************
// Copyright (C) 2017 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
export { ArrayUtils } from './array-utils';
export { Prioritizeable } from './prioritizeable';
type UnknownObject<T extends object> = Record<string | number | symbol, unknown> & { [K in keyof T]: unknown };
export type Deferred<T> = { [P in keyof T]: Promise<T[P]> };
export type MaybeArray<T> = T | T[];
export type MaybeNull<T> = { [P in keyof T]: T[P] | null };
export type MaybePromise<T> = T | PromiseLike<T>;
export type MaybeUndefined<T> = { [P in keyof T]?: T[P] | undefined };
export type Mutable<T> = { -readonly [P in keyof T]: T[P] };
export type RecursivePartial<T> = {
[P in keyof T]?: T[P] extends (infer I)[]
? RecursivePartial<I>[]
: RecursivePartial<T[P]>;
};
export type RecursiveReadonly<T> = {
readonly [P in keyof T]: T[P] extends Array<infer I>
? RecursiveReadonly<I>[]
: T[P] extends object ? RecursiveReadonly<T[P]>
: T[P];
};
export function isBoolean(value: unknown): value is boolean {
return value === true || value === false;
}
export function isString(value: unknown): value is string {
return typeof value === 'string' || value instanceof String;
}
export function isNumber(value: unknown): value is number {
return typeof value === 'number' || value instanceof Number;
}
export function isError(value: unknown): value is Error {
return value instanceof Error;
}
export function isErrorLike(value: unknown): value is Error {
return isObject(value) && isString(value.name) && isString(value.message) && (isUndefined(value.stack) || isString(value.stack));
}
// eslint-disable-next-line space-before-function-paren
export function isFunction<T extends (...args: unknown[]) => unknown>(value: unknown): value is T {
return typeof value === 'function';
}
/**
* @returns whether the provided parameter is an empty JavaScript Object or not.
*/
export function isEmptyObject(obj: unknown): obj is object {
if (!isObject(obj)) {
return false;
}
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
return false;
}
}
return true;
}
export function isObject<T extends object>(value: unknown): value is UnknownObject<T> {
// eslint-disable-next-line no-null/no-null
return typeof value === 'object' && value !== null;
}
export function isUndefined(value: unknown): value is undefined {
return typeof value === 'undefined';
}
/**
* @param value value to check.
* @param every optional predicate ran on every element of the array.
* @param thisArg value to substitute `this` with when invoking in the predicate.
* @returns whether or not `value` is an array.
*/
export function isArray<T>(value: unknown, every?: (value: unknown) => unknown, thisArg?: unknown): value is T[] {
return Array.isArray(value) && (!isFunction(every) || value.every(every, thisArg));
}
export function isStringArray(value: unknown): value is string[] {
return isArray(value, isString);
}
/**
* Creates a shallow copy with all ownkeys of the original object that are `null` made `undefined`
*/
export function nullToUndefined<T>(nullable: MaybeNull<T>): MaybeUndefined<T> {
const undefinable = { ...nullable } as MaybeUndefined<T>;
for (const key in nullable) {
// eslint-disable-next-line no-null/no-null
if (nullable[key] === null && Object.prototype.hasOwnProperty.call(nullable, key)) {
undefinable[key] = undefined;
}
}
return undefinable;
}
/**
* Throws when called and statically makes sure that all variants of a type were consumed.
*/
export function unreachable(_never: never, message: string = 'unhandled case'): never {
throw new Error(message);
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation and others. All rights reserved.
* Licensed under the MIT License. See https://github.com/Microsoft/vscode/blob/master/LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/
// Copied from https://github.com/microsoft/vscode/blob/1.72.2/src/vs/base/common/types.ts
/**
* @returns whether the provided parameter is defined.
*/
export function isDefined<T>(arg: T | null | undefined): arg is T {
return !isUndefinedOrNull(arg);
}
/**
* @returns whether the provided parameter is undefined or null.
*/
export function isUndefinedOrNull(obj: unknown): obj is undefined | null {
// eslint-disable-next-line no-null/no-null
return (isUndefined(obj) || obj === null);
}
export namespace MapUtils {
export function addOrInsertWith<K, V>(container: Map<K, V[]>, key: K, ...values: V[]): void {
const existing = container.get(key);
if (existing) {
existing.push(...values);
} else {
container.set(key, values);
}
}
}