This repository has been archived on 2020-11-02. You can view files and clone it, but cannot push or open issues or pull requests.
TripSit_Suite/node_modules/type-fest
cranberry ed23347e56 Initial comission of TheLounge base files 2020-11-01 22:46:04 +00:00
..
source Initial comission of TheLounge base files 2020-11-01 22:46:04 +00:00
index.d.ts Initial comission of TheLounge base files 2020-11-01 22:46:04 +00:00
license Initial comission of TheLounge base files 2020-11-01 22:46:04 +00:00
package.json Initial comission of TheLounge base files 2020-11-01 22:46:04 +00:00
readme.md Initial comission of TheLounge base files 2020-11-01 22:46:04 +00:00

readme.md

<br>
<br>
<img src="media/logo.svg" alt="type-fest" height="300">
<br>
<br>
<b>A collection of essential TypeScript types</b>
<br>
<hr>



Build Status

Many of the types here should have been built-in. You can help by suggesting some of them to the TypeScript project.

Either add this package as a dependency or copy-paste the needed types. No credit required. 👌

PR welcome for additional commonly needed types and docs improvements. Read the contributing guidelines first.

Install

$ npm install type-fest

Requires TypeScript >=3.2

Usage

import {Except} from 'type-fest';

type Foo = {
    unicorn: string;
    rainbow: boolean;
};

type FooWithoutRainbow = Except<Foo, 'rainbow'>;
//=> {unicorn: string}

API

Click the type names for complete docs.

Basic

Utilities

  • Except - Create a type from an object type without certain keys. This is a stricter version of Omit.
  • Mutable - Convert an object with readonly keys into a mutable object. The inverse of Readonly<T>.
  • Merge - Merge two types into a new type. Keys of the second type overrides keys of the first type.
  • MergeExclusive - Create a type that has mutually exclusive keys.
  • RequireAtLeastOne - Create a type that requires at least one of the given keys.
  • RequireExactlyOne - Create a type that requires exactly a single key of the given keys and disallows more.
  • PartialDeep - Create a deeply optional version of another type. Use Partial<T> if you only need one level deep.
  • ReadonlyDeep - Create a deeply immutable version of an object/Map/Set/Array type. Use Readonly<T> if you only need one level deep.
  • LiteralUnion - Create a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. Workaround for Microsoft/TypeScript#29729.
  • Promisable - Create a type that represents either the value or the value wrapped in PromiseLike.
  • Opaque - Create an opaque type.
  • SetOptional - Create a type that makes the given keys optional.
  • SetRequired - Create a type that makes the given keys required.

Miscellaneous

Declined types

If we decline a type addition, we will make sure to document the better solution here.

  • Diff and Spread - The PR author didnt provide any real-world use-cases and the PR went stale. If you think this type is useful, provide some real-world use-cases and we might reconsider.
  • Dictionary - You only save a few characters (Dictionary<number> vs Record<string, number>) from Record, which is more flexible and well-known. Also, you shouldnt use an object as a dictionary. We have Map in JavaScript now.

Tips

Built-in types

There are many advanced types most users dont know about.

  • Partial<T> - Make all properties in T optional.

    Example

    Playground

      interface NodeConfig {
              appName: string;
              port: number;
      }
    
      class NodeAppBuilder {
              private configuration: NodeConfig = {
                      appName: 'NodeApp',
                      port: 3000
              };
    
              config(config: Partial<NodeConfig>) {
                      type NodeConfigKey = keyof NodeConfig;
    
                      for (const key of Object.keys(config) as NodeConfigKey[]) {
                              const updateValue = config[key];
    
                              if (updateValue === undefined) {
                                      continue;
                              }
    
                              this.configuration[key] = updateValue;
                      }
    
                      return this;
              }
      }
    
      // `Partial<NodeConfig>`` allows us to provide only a part of the
      // NodeConfig interface.
      new NodeAppBuilder().config({appName: 'ToDoApp'});
  • Required<T> - Make all properties in T required.

    Example

    Playground

      interface ContactForm {
              email?: string;
              message?: string;
      }
    
      function submitContactForm(formData: Required<ContactForm>) {
              // Send the form data to the server.
      }
    
      submitContactForm({
              email: 'ex@mple.com',
              message: 'Hi! Could you tell me more about…',
      });
    
      // TypeScript error: missing property 'message'
      submitContactForm({
              email: 'ex@mple.com',
      });
  • Readonly<T> - Make all properties in T readonly.

    Example

    Playground

      enum LogLevel {
              Off,
              Debug,
              Error,
              Fatal
      };
    
      interface LoggerConfig {
              name: string;
              level: LogLevel;
      }
    
      class Logger {
              config: Readonly<LoggerConfig>;
    
              constructor({name, level}: LoggerConfig) {
                      this.config = {name, level};
                      Object.freeze(this.config);
              }
      }
    
      const config: LoggerConfig = {
          name: 'MyApp',
          level: LogLevel.Debug
      };
    
      const logger = new Logger(config);
    
      // TypeScript Error: cannot assign to read-only property.
      logger.config.level = LogLevel.Error;
    
      // We are able to edit config variable as we please.
      config.level = LogLevel.Error;
  • Pick<T, K> - From T, pick a set of properties whose keys are in the union K.

    Example

    Playground

      interface Article {
              title: string;
              thumbnail: string;
              content: string;
      }
    
      // Creates new type out of the `Article` interface composed
      // from the Articles' two properties: `title` and `thumbnail`.
      // `ArticlePreview = {title: string; thumbnail: string}`
      type ArticlePreview = Pick<Article, 'title' | 'thumbnail'>;
    
      // Render a list of articles using only title and description.
      function renderArticlePreviews(previews: ArticlePreview[]): HTMLElement {
              const articles = document.createElement('div');
    
              for (const preview of previews) {
                      // Append preview to the articles.
              }
    
              return articles;
      }
    
      const articles = renderArticlePreviews([
              {
                  title: 'TypeScript tutorial!',
                  thumbnail: '/assets/ts.jpg'
              }
      ]);
  • Record<K, T> - Construct a type with a set of properties K of type T.

    Example

    Playground

      // Positions of employees in our company.
      type MemberPosition = 'intern' | 'developer' | 'tech-lead';
    
      // Interface describing properties of a single employee.
      interface Employee {
              firstName: string;
              lastName: string;
              yearsOfExperience: number;
      }
    
      // Create an object that has all possible `MemberPosition` values set as keys.
      // Those keys will store a collection of Employees of the same position.
      const team: Record<MemberPosition, Employee[]> = {
              intern: [],
              developer: [],
              'tech-lead': [],
      };
    
      // Our team has decided to help John with his dream of becoming Software Developer.
      team.intern.push({
          firstName: 'John',
          lastName: 'Doe',
          yearsOfExperience: 0
      });
    
      // `Record` forces you to initialize all of the property keys.
      // TypeScript Error: "tech-lead" property is missing
      const teamEmpty: Record<MemberPosition, null> = {
              intern: null,
              developer: null,
      };
  • Exclude<T, U> - Exclude from T those types that are assignable to U.

    Example

    Playground

      interface ServerConfig {
          port: null | string | number;
      }
    
      type RequestHandler = (request: Request, response: Response) => void;
    
      // Exclude `null` type from `null | string | number`.
      // In case the port is equal to `null`, we will use default value.
      function getPortValue(port: Exclude<ServerConfig['port'], null>): number {
          if (typeof port === 'string') {
              return parseInt(port, 10);
          }
    
          return port;
      }
    
      function startServer(handler: RequestHandler, config: ServerConfig): void {
          const server = require('http').createServer(handler);
    
          const port = config.port === null ? 3000 : getPortValue(config.port);
          server.listen(port);
      }
  • Extract<T, U> - Extract from T those types that are assignable to U.

    Example

    Playground

      declare function uniqueId(): number;
    
      const ID = Symbol('ID');
    
      interface Person {
          [ID]: number;
          name: string;
          age: number;
      }
    
      // Allows changing the person data as long as the property key is of string type.
      function changePersonData<
          Obj extends Person,
          Key extends Extract<keyof Person, string>,
          Value extends Obj[Key]
      > (obj: Obj, key: Key, value: Value): void {
          obj[key] = value;
      }
    
      // Tiny Andrew was born.
      const andrew = {
          [ID]: uniqueId(),
          name: 'Andrew',
          age: 0,
      };
    
      // Cool, we're fine with that.
      changePersonData(andrew, 'name', 'Pony');
    
      // Goverment didn't like the fact that you wanted to change your identity.
      changePersonData(andrew, ID, uniqueId());
  • NonNullable<T> - Exclude null and undefined from T.

    Example

    Works with strictNullChecks set to true. (Read more here)

    Playground

      type PortNumber = string | number | null;
    
      /** Part of a class definition that is used to build a server */
      class ServerBuilder {
              portNumber!: NonNullable<PortNumber>;
    
              port(this: ServerBuilder, port: PortNumber): ServerBuilder {
                      if (port == null) {
                              this.portNumber = 8000;
                      } else {
                              this.portNumber = port;
                      }
    
                      return this;
              }
      }
    
      const serverBuilder = new ServerBuilder();
    
      serverBuilder
              .port('8000')   // portNumber = '8000'
              .port(null)     // portNumber =  8000
              .port(3000);    // portNumber =  3000
    
      // TypeScript error
      serverBuilder.portNumber = null;
  • Parameters<T> - Obtain the parameters of a function type in a tuple.

    Example

    Playground

      function shuffle(input: any[]): void {
          // Mutate array randomly changing its' elements indexes.
      }
    
      function callNTimes<Fn extends (...args: any[]) => any> (func: Fn, callCount: number) {
          // Type that represents the type of the received function parameters.
          type FunctionParameters = Parameters<Fn>;
    
          return function (...args: FunctionParameters) {
              for (let i = 0; i < callCount; i++) {
                  func(...args);
              }
          }
      }
    
      const shuffleTwice = callNTimes(shuffle, 2);
  • ConstructorParameters<T> - Obtain the parameters of a constructor function type in a tuple.

    Example

    Playground

      class ArticleModel {
          title: string;
          content?: string;
    
          constructor(title: string) {
              this.title = title;
          }
      }
    
      class InstanceCache<T extends (new (...args: any[]) => any)> {
          private ClassConstructor: T;
          private cache: Map<string, InstanceType<T>> = new Map();
    
          constructor (ctr: T) {
              this.ClassConstructor = ctr;
          }
    
          getInstance (...args: ConstructorParameters<T>): InstanceType<T> {
              const hash = this.calculateArgumentsHash(...args);
    
              const existingInstance = this.cache.get(hash);
              if (existingInstance !== undefined) {
                  return existingInstance;
              }
    
              return new this.ClassConstructor(...args);
          }
    
          private calculateArgumentsHash(...args: any[]): string {
              // Calculate hash.
              return 'hash';
          }
      }
    
      const articleCache = new InstanceCache(ArticleModel);
      const amazonArticle = articleCache.getInstance('Amazon forests burining!');
  • ReturnType<T> Obtain the return type of a function type.

    Example

    Playground

      /** Provides every element of the iterable `iter` into the `callback` function and stores the results in an array. */
      function mapIter<
              Elem,
              Func extends (elem: Elem) => any,
              Ret extends ReturnType<Func>
      >(iter: Iterable<Elem>, callback: Func): Ret[] {
              const mapped: Ret[] = [];
    
              for (const elem of iter) {
                      mapped.push(callback(elem));
              }
    
              return mapped;
      }
    
      const setObject: Set<string> = new Set();
      const mapObject: Map<number, string> = new Map();
    
      mapIter(setObject, (value: string) => value.indexOf('Foo')); // number[]
    
      mapIter(mapObject, ([key, value]: [number, string]) => {
              return key % 2 === 0 ? value : 'Odd';
      }); // string[]
  • InstanceType<T> Obtain the instance type of a constructor function type.

    Example

    Playground

      class IdleService {
              doNothing (): void {}
      }
    
      class News {
              title: string;
              content: string;
    
              constructor(title: string, content: string) {
                      this.title = title;
                      this.content = content;
              }
      }
    
      const instanceCounter: Map<Function, number> = new Map();
    
      interface Constructor {
              new(...args: any[]): any;
      }
    
      // Keep track how many instances of `Constr` constructor have been created.
      function getInstance<
              Constr extends Constructor,
              Args extends ConstructorParameters<Constr>
      >(constructor: Constr, ...args: Args): InstanceType<Constr> {
              let count = instanceCounter.get(constructor) || 0;
    
              const instance = new constructor(...args);
    
              instanceCounter.set(constructor, count + 1);
    
              console.log(`Created ${count + 1} instances of ${Constr.name} class`);
    
              return instance;
      }
    
    
      const idleService = getInstance(IdleService);
      // Will log: `Created 1 instances of IdleService class`
      const newsEntry = getInstance(News, 'New ECMAScript proposals!', 'Last month...');
      // Will log: `Created 1 instances of News class`
  • Omit<T, K> Constructs a type by picking all properties from T and then removing K.

    Example

    Playground

      interface Animal {
              imageUrl: string;
              species: string;
              images: string[];
              paragraphs: string[];
      }
    
      // Creates new type with all properties of the `Animal` interface
      // except 'images' and 'paragraphs' properties. We can use this
      // type to render small hover tooltip for a wiki entry list.
      type AnimalShortInfo = Omit<Animal, 'images' | 'paragraphs'>;
    
      function renderAnimalHoverInfo (animals: AnimalShortInfo[]): HTMLElement {
              const container =  document.createElement('div');
              // Internal implementation.
              return container;
      }

You can find some examples in the TypeScript docs.

Maintainers

License

(MIT OR CC0-1.0)


<b>
    <a href="https://tidelift.com/subscription/pkg/npm-type-fest?utm_source=npm-type-fest&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
</b>
<br>
<sub>
    Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
</sub>