Sindre Sorhus' open source work is supported by the community
Special thanks to: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.
Help wanted with reviewing proposals and pull requests.
npm install type-fest
Requires TypeScript >=5.1
Works best with {strict: true}
in your tsconfig.
import type {Except} from 'type-fest';
type Foo = {
unicorn: string;
rainbow: boolean;
};
type FooWithoutRainbow = Except<Foo, 'rainbow'>;
//=> {unicorn: string}
Click the type names for complete docs.
Primitive
- Matches any primitive value.Class
- Matches a class
.Constructor
- Matches a class
constructor.AbstractClass
- Matches an abstract class
.AbstractConstructor
- Matches an abstract class
constructor.TypedArray
- Matches any typed array, like Uint8Array
or Float64Array
.ObservableLike
- Matches a value that is like an Observable.EmptyObject
- Represents a strictly empty plain object, the {}
value.NonEmptyObject
- Represents an object with at least 1 non-optional key.UnknownRecord
- Represents an object with unknown
value. You probably want this instead of {}
.UnknownArray
- Represents an array with unknown
value.Except
- Create a type from an object type without certain keys. This is a stricter version of Omit
.Writable
- Create a type that strips readonly
from the given type. Inverse of Readonly<T>
.WritableDeep
- Create a deeply mutable version of an object
/ReadonlyMap
/ReadonlySet
/ReadonlyArray
type. The inverse of ReadonlyDeep<T>
. Use Writable<T>
if you only need one level deep.Merge
- Merge two types into a new type. Keys of the second type overrides keys of the first type.MergeDeep
- Merge two objects or two arrays/tuples recursively into a new type.MergeExclusive
- Create a type that has mutually exclusive keys.OverrideProperties
- Override only existing properties of the given type. Similar to Merge
, but enforces that the original type has the properties you want to override.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.RequireAllOrNone
- Create a type that requires all of the given keys or none of the given keys.RequireOneOrNone
- Create a type that requires exactly a single key of the given keys and disallows more, or none of the given keys.SingleKeyObject
- Create a type that only accepts an object with a single key.RequiredDeep
- Create a deeply required version of another type. Use Required<T>
if you only need one level deep.PickDeep
- Pick properties from a deeply-nested object. Use Pick<T>
if you only need one level deep.OmitDeep
- Omit properties from a deeply-nested object. Use Omit<T>
if you only need one level deep.OmitIndexSignature
- Omit any index signatures from the given object type, leaving only explicitly defined properties.PickIndexSignature
- Pick only index signatures from the given object type, leaving out all explicitly defined properties.PartialDeep
- Create a deeply optional version of another type. Use Partial<T>
if you only need one level deep.PartialOnUndefinedDeep
- Create a deep version of another type where all keys accepting undefined
type are set to optional.UndefinedOnPartialDeep
- Create a deep version of another type where all optional keys are set to also accept undefined
.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.Tagged
- Create a tagged type that can support multiple tags and per-tag metadata. (This replaces the previous Opaque
type, which is now deprecated.)UnwrapTagged
- Get the untagged portion of a tagged type created with Tagged
. (This replaces the previous UnwrapOpaque
type, which is now deprecated.)InvariantOf
- Create an invariant type, which is a type that does not accept supertypes and subtypes.SetOptional
- Create a type that makes the given keys optional.SetReadonly
- Create a type that makes the given keys readonly.SetRequired
- Create a type that makes the given keys required.SetNonNullable
- Create a type that makes the given keys non-nullable.ValueOf
- Create a union of the given object's values, and optionally specify which keys to get the values from.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.ConditionalPickDeep
- Like ConditionalPick
except that it selects the properties deeply.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.LiteralToPrimitive
- Convert a literal type to the primitive type it belongs to.LiteralToPrimitiveDeep
- Like LiteralToPrimitive
except it converts literal types inside an object or array deeply.Stringified
- Create a type with the keys of the given type changed to string
type.IterableElement
- Get the element type of an Iterable
/AsyncIterable
. For example, Array
, Set
, Map
, generator, stream, etc.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.SetParameterType
- Create a function that replaces some parameters with the given parameters.Simplify
- Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability.SimplifyDeep
- Deeply simplifies an object type.Get
- Get a deeply-nested property from an object using a key path, like Lodash's .get()
function.StringKeyOf
- Get keys of the given type as strings.Schema
- Create a deep version of another object type where property values are recursively replaced into a given value type.Exact
- Create a type that does not allow extra properties.OptionalKeysOf
- Extract all optional keys from the given type.KeysOfUnion
- Create a union of all keys from a given type, even those exclusive to specific union members.HasOptionalKeys
- Create a true
/false
type depending on whether the given type has any optional fields.RequiredKeysOf
- Extract all required keys from the given type.HasRequiredKeys
- Create a true
/false
type depending on whether the given type has any required fields.ReadonlyKeysOf
- Extract all readonly keys from the given type.HasReadonlyKeys
- Create a true
/false
type depending on whether the given type has any readonly fields.WritableKeysOf
- Extract all writable (non-readonly) keys from the given type.HasWritableKeys
- Create a true
/false
type depending on whether the given type has any writable fields.Spread
- Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.IsEqual
- Returns a boolean for whether the two given types are equal.TaggedUnion
- Create a union of types that share a common discriminant property.IntRange
- Generate a union of numbers (includes the start and excludes the end).IntClosedRange
- Generate a union of numbers (includes the start and the end).ArrayIndices
- Provides valid indices for a constant array or tuple.ArrayValues
- Provides all values for a constant array or tuple.ArraySplice
- Creates a new array type by adding or removing elements at a specified index range in the original array.ArrayTail
- Extracts the type of an array or tuple minus the first element.SetFieldType
- Create a type that changes the type of the given keys.Paths
- Generate a union of all possible paths to properties in the given object.SharedUnionFields
- Create a type with shared fields from a union of object types.SharedUnionFieldsDeep
- Create a type with shared fields from a union of object types, deeply traversing nested structures.DistributedOmit
- Omits keys from a type, distributing the operation over a union.DistributedPick
- Picks keys from a type, distributing the operation over a union.And
- Returns a boolean for whether two given types are both true.Or
- Returns a boolean for whether either of two given types are true.NonEmptyTuple
- Matches any non-empty tuple.FindGlobalType
- Tries to find the type of a global with the given name.FindGlobalInstanceType
- Tries to find one or more types from their globally-defined constructors.IsType
vs. IfType
For every IsT
type (e.g. IsAny
), there is an associated IfT
type that can help simplify conditional types. While the IsT
types return a boolean
, the IfT
types act like an If
/Else
- they resolve to the given TypeIfT
or TypeIfNotT
depending on whether IsX
is true
or not. By default, IfT
returns a boolean
:
type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
);
import type {IsAny, IfAny} from 'type-fest';
type ShouldBeTrue = IsAny<any> extends true ? true : false;
//=> true
type ShouldBeFalse = IfAny<'not any'>;
//=> false
type ShouldBeNever = IfAny<'not any', 'not never', 'never'>;
//=> 'never'
IsLiteral
- Returns a boolean for whether the given type is a literal type.IsStringLiteral
- Returns a boolean for whether the given type is a string
literal type.IsNumericLiteral
- Returns a boolean for whether the given type is a number
or bigint
literal type.IsBooleanLiteral
- Returns a boolean for whether the given type is a true
or false
literal type.IsSymbolLiteral
- Returns a boolean for whether the given type is a symbol
literal type.IsAny
- Returns a boolean for whether the given type is any
. (Conditional version: IfAny
)IsNever
- Returns a boolean for whether the given type is never
. (Conditional version: IfNever
)IsUnknown
- Returns a boolean for whether the given type is unknown
. (Conditional version: IfUnknown
)IsEmptyObject
- Returns a boolean for whether the type is strictly equal to an empty plain object, the {}
value. (Conditional version: IfEmptyObject
)IsNull
- Returns a boolean for whether the given type is null
. (Conditional version: IfNull
)Jsonify
- Transform a type to one that is assignable to the JsonValue
type.Jsonifiable
- Matches a value that can be losslessly converted to JSON.JsonPrimitive
- Matches a JSON primitive.JsonObject
- Matches a JSON object.JsonArray
- Matches a JSON array.JsonValue
- Matches any valid JSON value.StructuredCloneable
- Matches a value that can be losslessly cloned using structuredClone
.Promisable
- Create a type that represents either the value or the value wrapped in PromiseLike
.AsyncReturnType
- Unwrap the return type of a function that returns a Promise
.Asyncify
- Create an async version of the given function type.Trim
- Remove leading and trailing spaces from a string.Split
- Represents an array of strings split using a given character or character set.Words
- Represents an array of strings split using a heuristic for detecting words.Replace
- Represents a string with some or all matches replaced by a replacement.StringSlice
- Returns a string slice of a given range, just like String#slice()
.StringRepeat
- Returns a new string which contains the specified number of copies of a given string, just like String#repeat()
.Arrayable
- Create a type that represents either the value or an array of the value.Includes
- Returns a boolean for whether the given array includes the given item.Join
- Join an array of strings and/or numbers using the given string as a delimiter.ArraySlice
- Returns an array slice of a given range, just like Array#slice()
.LastArrayElement
- Extracts the type of the last element of an array.FixedLengthArray
- Create a type that represents an array of the given type and length.MultidimensionalArray
- Create a type that represents a multidimensional array of the given type and dimensions.MultidimensionalReadonlyArray
- Create a type that represents a multidimensional readonly array of the given type and dimensions.ReadonlyTuple
- Create a type that represents a read-only tuple of the given type and length.TupleToUnion
- Convert a tuple/array into a union type of its elements.UnionToTuple
- Convert a union type into an unordered tuple type of its elements.PositiveInfinity
- Matches the hidden Infinity
type.NegativeInfinity
- Matches the hidden -Infinity
type.Finite
- A finite number
.Integer
- A number
that is an integer.Float
- A number
that is not an integer.NegativeFloat
- A negative (-∞ < x < 0
) number
that is not an integer.Negative
- A negative number
/bigint
(-∞ < x < 0
)NonNegative
- A non-negative number
/bigint
(0 <= x < ∞
).NegativeInteger
- A negative (-∞ < x < 0
) number
that is an integer.NonNegativeInteger
- A non-negative (0 <= x < ∞
) number
that is an integer.IsNegative
- Returns a boolean for whether the given number is a negative number.IsFloat
- Returns a boolean for whether the given number is a float, like 1.5
or -1.5
.IsInteger
- Returns a boolean for whether the given number is a integer, like -5
, 1.0
or 100
.GreaterThan
- Returns a boolean for whether a given number is greater than another number.GreaterThanOrEqual
- Returns a boolean for whether a given number is greater than or equal to another number.LessThan
- Returns a boolean for whether a given number is less than another number.LessThanOrEqual
- Returns a boolean for whether a given number is less than or equal to another number.Sum
- Returns the sum of two numbers.Subtract
- Returns the difference between two numbers.CamelCase
- Convert a string literal to camel-case (fooBar
).CamelCasedProperties
- Convert object properties to camel-case (fooBar
).CamelCasedPropertiesDeep
- Convert object properties to camel-case recursively (fooBar
).KebabCase
- Convert a string literal to kebab-case (foo-bar
).KebabCasedProperties
- Convert a object properties to kebab-case recursively (foo-bar
).KebabCasedPropertiesDeep
- Convert object properties to kebab-case (foo-bar
).PascalCase
- Converts a string literal to pascal-case (FooBar
)PascalCasedProperties
- Converts object properties to pascal-case (FooBar
)PascalCasedPropertiesDeep
- Converts object properties to pascal-case (FooBar
)SnakeCase
- Convert a string literal to snake-case (foo_bar
).SnakeCasedProperties
- Convert object properties to snake-case (foo_bar
).SnakeCasedPropertiesDeep
- Convert object properties to snake-case recursively (foo_bar
).ScreamingSnakeCase
- Convert a string literal to screaming-snake-case (FOO_BAR
).DelimiterCase
- Convert a string literal to a custom string delimiter casing.DelimiterCasedProperties
- Convert object properties to a custom string delimiter casing.DelimiterCasedPropertiesDeep
- Convert object properties to a custom string delimiter casing recursively.GlobalThis
- Declare locally scoped properties on globalThis
.PackageJson
- Type for npm's package.json
file. It also includes support for TypeScript Declaration Files.TsConfigJson
- Type for TypeScript's tsconfig.json
file.If we decline a type addition, we will make sure to document the better solution here.
Diff
and Spread
- The pull request 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.ExtractProperties
and ExtractMethods
- The types violate the single responsibility principle. Instead, refine your types into more granular type hierarchies.Url2Json
- Inferring search parameters from a URL string is a cute idea, but not very useful in practice, since search parameters are usually dynamic and defined separately.Nullish
- The type only saves a couple of characters, not everyone knows what "nullish" means, and I'm also trying to get away from null
.TitleCase
- It's not solving a common need and is a better fit for a separate package.ExtendOr
and ExtendAnd
- The benefits don't outweigh having to learn what they mean.PackageJsonExtras
- There are too many possible configurations that can be put into package.json
. If you would like to extend PackageJson
to support an additional configuration in your project, please see the Extending existing types section below.If you know one of our types by a different name, add it here for discovery.
Prettify
- See Simplify
Expand
- See Simplify
PartialBy
- See SetOptional
RecordDeep
- See Schema
Mutable
- See Writable
RequireOnlyOne
, OneOf
- See RequireExactlyOne
AtMostOne
- See RequireOneOrNone
AllKeys
- See KeysOfUnion
Branded
- See Tagged
Opaque
- See Tagged
SetElement
- See IterableElement
SetEntry
- See IterableElement
SetValues
- See IterableElement
PackageJson
- There are a lot of tools that place extra configurations inside the package.json
file. You can extend PackageJson
to support these additional configurations.
import type {PackageJson as BasePackageJson} from 'type-fest';
import type {Linter} from 'eslint';
type PackageJson = BasePackageJson & {eslintConfig?: Linter.Config};
document.querySelector
and document.querySelectorAll
with a template literal type that matches element types returned from an HTML element query selector.Linter.Config
- Definitions for the ESLint configuration schema.There are many advanced types most users don't know about.
Awaited<T>
- Extract the type of a value that a Promise
resolves to.
interface User {
id: number;
name: string;
age: number;
}
class UserApiService {
async fetchUser(userId: number): Promise<User> {
// Fetch the user data from the database.
// The actual implementation might look like this:
// const response = await fetch('/api/user/${userId}');
// const data = response.json();
// return data;
return {
id: 1,
name: 'John Doe',
age: 30
};
}
}
type FetchedUser = Awaited<ReturnType<UserApiService['fetchUser']>>;
async function handleUserData(apiService: UserApiService, userId: number) {
try {
const user: FetchedUser = await apiService.fetchUser(userId);
// After fetching user data, you can perform various actions such as updating the user interface,
// caching the data for future use, or making additional API requests as needed.
} catch (error) {
// Error handling
}
}
const userApiService = new UserApiService();
handleUserData(userApiService, 1);
Partial<T>
- Make all properties in T
optional.
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.
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.
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
.
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
.
// 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
.
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
.
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');
// Government didn't like the fact that you wanted to change your identity.
changePersonData(andrew, ID, uniqueId());
NonNullable<T>
- Exclude null
and undefined
from T
.
strictNullChecks
set to true
.
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.
function shuffle(input: any[]): void {
// Mutate array randomly changing its' elements indexes.
}
function callNTimes<Fn extends (...arguments_: any[]) => any> (func: Fn, callCount: number) {
// Type that represents the type of the received function parameters.
type FunctionParameters = Parameters<Fn>;
return function (...arguments_: FunctionParameters) {
for (let i = 0; i < callCount; i++) {
func(...arguments_);
}
}
}
const shuffleTwice = callNTimes(shuffle, 2);
ConstructorParameters<T>
- Obtain the parameters of a constructor function type in a tuple.
class ArticleModel {
title: string;
content?: string;
constructor(title: string) {
this.title = title;
}
}
class InstanceCache<T extends (new (...arguments_: any[]) => any)> {
private ClassConstructor: T;
private cache: Map<string, InstanceType<T>> = new Map();
constructor (ctr: T) {
this.ClassConstructor = ctr;
}
getInstance (...arguments_: ConstructorParameters<T>): InstanceType<T> {
const hash = this.calculateArgumentsHash(...arguments_);
const existingInstance = this.cache.get(hash);
if (existingInstance !== undefined) {
return existingInstance;
}
return new this.ClassConstructor(...arguments_);
}
private calculateArgumentsHash(...arguments_: any[]): string {
// Calculate hash.
return 'hash';
}
}
const articleCache = new InstanceCache(ArticleModel);
const amazonArticle = articleCache.getInstance('Amazon forests burning!');
ReturnType<T>
- Obtain the return type of a function type.
/** 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.
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(...arguments_: any[]): any;
}
// Keep track how many instances of `Constr` constructor have been created.
function getInstance<
Constr extends Constructor,
Arguments extends ConstructorParameters<Constr>
>(constructor: Constr, ...arguments_: Arguments): InstanceType<Constr> {
let count = instanceCounter.get(constructor) || 0;
const instance = new constructor(...arguments_);
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.
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.
type T = Uppercase<'hello'>; // 'HELLO'
type T2 = Uppercase<'foo' | 'bar'>; // 'FOO' | 'BAR'
type T3<S extends string> = Uppercase<`aB${S}`>;
type T4 = T3<'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.
type T = Lowercase<'HELLO'>; // 'hello'
type T2 = Lowercase<'FOO' | 'BAR'>; // 'foo' | 'bar'
type T3<S extends string> = Lowercase<`aB${S}`>;
type T4 = T3<'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.
type T = Capitalize<'hello'>; // 'Hello'
type T2 = Capitalize<'foo' | 'bar'>; // 'Foo' | 'Bar'
type T3<S extends string> = Capitalize<`aB${S}`>;
type T4 = T3<'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.
type T = Uncapitalize<'Hello'>; // 'hello'
type T2 = Uncapitalize<'Foo' | 'Bar'>; // 'foo' | 'bar'
type T3<S extends string> = Uncapitalize<`AB${S}`>;
type T4 = T3<'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.
SPDX-License-Identifier: (MIT OR CC0-1.0)