Have ideas to improve npm?Join in the discussion! »

    type-fest
    TypeScript icon, indicating that this package has built-in type declarations

    1.0.2 • Public • Published


    type-fest

    A collection of essential TypeScript types







    npm dependents npm downloads

    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.4

    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 - Create a type that strips readonly from all or some of an object's keys. 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.
    • ValueOf - Create a union of the given object's values, and optionally specify which keys to get the values from.
    • PromiseValue - Returns the type that is wrapped inside a Promise.
    • AsyncReturnType - Unwrap the return type of a function that returns a Promise.
    • ConditionalKeys - Extract keys from a shape where values extend the given Condition type.
    • ConditionalPick - Like Pick except it selects properties from a shape where the values extend the given Condition type.
    • ConditionalExcept - Like Omit except it removes properties from a shape where the values extend the given Condition type.
    • UnionToIntersection - Convert a union type to an intersection type.
    • Stringified - Create a type with the keys of the given type changed to string type.
    • FixedLengthArray - Create a type that represents an array of the given type and length.
    • IterableElement - Get the element type of an Iterable/AsyncIterable. For example, an array or a generator.
    • Entry - Create a type that represents the type of an entry of a collection.
    • Entries - Create a type that represents the type of the entries of a collection.
    • SetReturnType - Create a function type with a return type of your choice and the same parameters as the given function type.
    • Asyncify - Create an async version of the given function type.

    Template literal types

    Note: These require TypeScript 4.1 or newer.

    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 didn't 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 shouldn't use an object as a dictionary. We have Map in JavaScript now.
    • SubType - The type is powerful, but lacks good use-cases and is prone to misuse.
    • ExtractProperties and ExtractMethods - The types violate the single responsibility principle. Instead, refine your types into more granular type hierarchies.

    Tips

    Related

    • typed-query-selector - Enhances document.querySelector and document.querySelectorAll with a template literal type that matches element types returned from an HTML element query selector.

    Built-in types

    There are many advanced types most users don't 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
       		};
      
       		private updateConfig<Key extends keyof NodeConfig>(key: Key, value: NodeConfig[Key]) {
       				this.configuration[key] = value;
       		}
      
       		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.updateConfig(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;
       }
    • Uppercase<S extends string> - Transforms every character in a string into uppercase.

      Example
       type T = Uppercase<'hello'>;  // 'HELLO'
      
       type T2 = Uppercase<'foo' | 'bar'>;  // 'FOO' | 'BAR'
      
       type T3<S extends string> = Uppercase<`aB${S}`>;
       type T4 = T30<'xYz'>;  // 'ABXYZ'
      
       type T5 = Uppercase<string>;  // string
       type T6 = Uppercase<any>;  // any
       type T7 = Uppercase<never>;  // never
       type T8 = Uppercase<42>;  // Error, type 'number' does not satisfy the constraint 'string'
    • Lowercase<S extends string> - Transforms every character in a string into lowercase.

      Example
       type T = Lowercase<'HELLO'>;  // 'hello'
      
       type T2 = Lowercase<'FOO' | 'BAR'>;  // 'foo' | 'bar'
      
       type T3<S extends string> = Lowercase<`aB${S}`>;
       type T4 = T32<'xYz'>;  // 'abxyz'
      
       type T5 = Lowercase<string>;  // string
       type T6 = Lowercase<any>;  // any
       type T7 = Lowercase<never>;  // never
       type T8 = Lowercase<42>;  // Error, type 'number' does not satisfy the constraint 'string'
    • Capitalize<S extends string> - Transforms the first character in a string into uppercase.

      Example
       type T = Capitalize<'hello'>;  // 'Hello'
      
       type T2 = Capitalize<'foo' | 'bar'>;  // 'Foo' | 'Bar'
      
       type T3<S extends string> = Capitalize<`aB${S}`>;
       type T4 = T32<'xYz'>;  // 'ABxYz'
      
       type T5 = Capitalize<string>;  // string
       type T6 = Capitalize<any>;  // any
       type T7 = Capitalize<never>;  // never
       type T8 = Capitalize<42>;  // Error, type 'number' does not satisfy the constraint 'string'
    • Uncapitalize<S extends string> - Transforms the first character in a string into lowercase.

      Example
       type T = Uncapitalize<'Hello'>;  // 'hello'
      
       type T2 = Uncapitalize<'Foo' | 'Bar'>;  // 'foo' | 'bar'
      
       type T3<S extends string> = Uncapitalize<`AB${S}`>;
       type T4 = T30<'xYz'>;  // 'aBxYz'
      
       type T5 = Uncapitalize<string>;  // string
       type T6 = Uncapitalize<any>;  // any
       type T7 = Uncapitalize<never>;  // never
       type T8 = Uncapitalize<42>;  // Error, type 'number' does not satisfy the constraint 'string'

    You can find some examples in the TypeScript docs.

    Maintainers

    License

    (MIT OR CC0-1.0)


    Get professional support for this package with a Tidelift subscription
    Tidelift helps make open source sustainable for maintainers while giving companies
    assurances about security, maintenance, and licensing for their dependencies.

    Install

    npm i type-fest

    DownloadsWeekly Downloads

    58,780,321

    Version

    1.0.2

    License

    (MIT OR CC0-1.0)

    Unpacked Size

    137 kB

    Total Files

    60

    Last publish

    Collaborators

    • avatar