Skip to content

Commit

Permalink
feat(type-helper): new package for ts types
Browse files Browse the repository at this point in the history
  • Loading branch information
alimd committed Dec 26, 2023
1 parent d592830 commit 4d81aaf
Show file tree
Hide file tree
Showing 4 changed files with 285 additions and 0 deletions.
26 changes: 26 additions & 0 deletions packages/type-helper/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Typescript Type Helpers

Collection of useful typescript type helpers.

## Installation

```bash
yarn add @alwatr/type-helper
```

## Usage

```typescript
import type {JSONObject} from '@alwatr/type-helper';

const obj: JSONObject = {
foo: 'bar',
baz: {
qux: 1,
arr: [1, 2, 3],
},
qux: true,
};
```

Read the [source code](https://github.com/Alwatr/nanolib/tree/next/packages/type-helper/src) for more details.
56 changes: 56 additions & 0 deletions packages/type-helper/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "@alwatr/type-helper",
"version": "1.0.0",
"description": "Collection of useful typescript type helpers.",
"author": "S. Ali Mihandoost <[email protected]>",
"keywords": [
"type",
"type-helper",
"types",
"typescript",
"utility",
"util",
"utils",
"nanolib",
"alwatr"
],
"main": "",
"types": "./dist/main.d.ts",
"license": "MIT",
"files": [
"**/*.{js,mjs,cjs,map,d.ts,html,md}",
"!demo/**/*"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/Alwatr/nanolib",
"directory": "packages/type-helper"
},
"homepage": "https://github.com/Alwatr/nanolib/tree/next/packages/type-helper#readme",
"bugs": {
"url": "https://github.com/Alwatr/nanolib/issues"
},
"prettier": "@alwatr/prettier-config",
"scripts": {
"b": "yarn run build",
"w": "yarn run watch",
"c": "yarn run clean",
"cb": "yarn run clean && yarn run build",
"d": "yarn run build:es && ALWATR_DEBUG=1 yarn node",
"build": "yarn run build:ts",
"build:es": "echo skip build:es",
"build:ts": "tsc --build",
"watch": "yarn run watch:ts & yarn run watch:es",
"watch:es": "yarn run build:es --watch",
"watch:ts": "yarn run build:ts --watch --preserveWatchOutput",
"clean": "rm -rfv dist *.tsbuildinfo"
},
"devDependencies": {
"@alwatr/prettier-config": "workspace:^",
"@alwatr/tsconfig-base": "workspace:^",
"typescript": "^5.3.3"
}
}
192 changes: 192 additions & 0 deletions packages/type-helper/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-indexed-object-style */

/**
* Represents a primitive type in TypeScript.
* @typedef {string | number | bigint | boolean | symbol | null | undefined} Primitive
*/
export type Primitive = string | number | bigint | boolean | symbol | null | undefined;

/**
* Represents a type that includes all falsy values: false, '', 0, null, and undefined.
*/
export type Falsy = false | '' | 0 | null | undefined;

/**
* Represents a type that can be null or undefined.
*/
export type Nullish = null | undefined;

/**
* Represents a type that can be either a value of type T or null.
* @template T - The type of the value.
*/
export type Nullable<T> = T | null;

/**
* Represents a type that can either be of type T or undefined.
* @template T - The type parameter.
*/
export type Maybe<T> = T | undefined;

/**
* Represents a type that can either be a value of type T or a promise that resolves to a value of type T.
* @template T - The type of the value or the resolved value.
*/
export type MaybePromise<T> = T | Promise<T>;

/**
* Represents a type that can be either a single value or an array of values.
* @template T - The type of the value(s).
*/
export type SingleOrArray<T> = T | T[];

/**
* Type helper that removes the undefined type from a given type.
* @template T The type to remove undefined from.
* @returns The type without undefined.
*/
export type NonUndefined<T> = T extends undefined ? never : T;

/**
* Returns the keys of an object type `T` that are required (not optional).
*
* @template T - The object type.
* @returns The keys of `T` that are required.
*/
export type RequiredKeys<T> = {
[K in keyof T]-?: {} extends Pick<T, K> ? never : K;
}[keyof T];

/**
* Returns the keys of an object type `T` that are optional.
*
* @template T - The object type.
* @returns The keys of `T` that are optional.
*/
export type OptionalKeys<T> = {
[K in keyof T]-?: {} extends Pick<T, K> ? K : never;
}[keyof T];

/**
* Represents a type that makes all properties of an object and its nested objects readonly.
* @template T - The type to make readonly.
* @returns The readonly version of the input type.
*/
export type DeepReadonly<T> = T extends ((...args: any[]) => any) | Primitive
? T
: T extends DeepReadonlyArray_<infer U>
? DeepReadonlyArray_<U>
: T extends DeepReadonlyObject_<infer V>
? DeepReadonlyObject_<V>
: T;
type DeepReadonlyArray_<T> = readonly DeepReadonly<T>[];
type DeepReadonlyObject_<T> = {
readonly [P in keyof T]: DeepReadonly<T[P]>;
};

/**
* Recursively makes all properties of an object and its nested objects/array required.
*
* @template T - The type to make deep required.
* @param {T} value - The value to make deep required.
* @returns {DeepRequired<T>} - The deep required type.
*/
export type DeepRequired<T> = T extends (...args: any[]) => any
? T
: T extends any[]
? DeepRequiredArray_<T[number]>
: T extends object
? DeepRequiredObject_<T>
: T;
type DeepRequiredArray_<T> = DeepRequired<NonUndefined<T>>[];
type DeepRequiredObject_<T> = {
[P in keyof T]-?: DeepRequired<NonUndefined<T[P]>>;
};

/**
* Represents a type that makes all properties of the given type optional recursively.
* @template T - The type to make partial.
*/
export type DeepPartial<T> = {[P in keyof T]?: DeepPartial_<T[P]>};
type DeepPartial_<T> = T extends ((...args: any[]) => any) | Primitive
? T
: T extends (infer U)[]
? DeepPartialArray_<U>
: T extends object
? DeepPartial<T>
: T | undefined;
type DeepPartialArray_<T> = DeepPartial_<T>[];

/**
* Represents a class constructor.
* @template T - The type of the class.
*/
export type Class<T> = new (...args: any[]) => T;

/**
* Removes the first parameter from a function type.
* @template F The function type.
* @returns A new function type without the first parameter.
*/
export type OmitFirstParam<F> = F extends (x: any, ...args: infer A) => infer R ? (...args: A) => R : never;

/**
* Retrieves the type of a property from an object type.
*
* @template T - The object type.
* @template K - The property key.
* @returns {Prop<T, K>} - The type of the property.
*/
export type Prop<T, K> = K extends keyof T ? T[K] : never;

/**
* Retrieves the union of all values in the given object type.
* @typeparam T - The object type.
* @returns The union of all values in the object type.
*/
export type Values<T> = T[keyof T];

/**
* Extracts the type of individual items in an array.
* If the input type is an array, it returns the type of the array items.
* If the input type is not an array, it returns the input type itself.
*
* @typeParam T - The input type.
* @returns The type of individual items in the array, or the input type itself.
*/
export type ArrayItems<T> = T extends (infer K)[] ? K : T;

/**
* Merges two types together by omitting keys from the first type that exist in the second type,
* and then combining the remaining keys with the keys from the second type.
* @template M - The first type to merge.
* @template N - The second type to merge.
* @returns A new type that is the result of merging the two input types.
*/
export type Merge<M, N> = Omit<M, keyof N> & N;

/**
* Represents a dictionary object with string keys and values of type T.
*/
export interface Dictionary<T> {
[key: string]: T;
}

/**
* Strigifyable JSON value
*/
/**
* Represents a JSON value that can be of type string, number, boolean, null, undefined,
* JSONArray, or JSONObject.
*/
export type JSONValue = string | number | boolean | null | undefined | JSONArray | JSONObject;

/**
* Represents an array of JSONValues.
*/
type JSONArray = JSONValue[];

/**
* Represents an object of Record<string, JSONValues>
*/
type JSONObject = Dictionary<JSONValue>;
11 changes: 11 additions & 0 deletions packages/type-helper/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "@alwatr/tsconfig-base/tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist",
"declarationMap": false,
"emitDeclarationOnly": true,
"composite": true,
},
"include": ["src/**/*.ts"]
}

0 comments on commit 4d81aaf

Please sign in to comment.