Commit b807a4c1 authored by Wolfgang Knopki's avatar Wolfgang Knopki
Browse files

Merge branch 'revert-jul13' into 'testing'

Revert "Merge branch 'MLAB-677' into 'testing'"

See merge request !168
parents 81e73777 08d3a3ba
Pipeline #6895 passed with stage
in 16 seconds
import {ArrayEntry, MapEntry, ObjectEntry, SetEntry} from './entry';
type ArrayEntries<BaseType extends readonly unknown[]> = Array<ArrayEntry<BaseType>>;
type MapEntries<BaseType> = Array<MapEntry<BaseType>>;
type ObjectEntries<BaseType> = Array<ObjectEntry<BaseType>>;
type SetEntries<BaseType extends Set<unknown>> = Array<SetEntry<BaseType>>;
/**
Many collections have an `entries` method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. The `Entries` type will return the type of that collection's entries.
For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable.
@see `Entry` if you want to just access the type of a single entry.
@example
```
import {Entries} from 'type-fest';
interface Example {
someKey: number;
}
const manipulatesEntries = (examples: Entries<Example>) => examples.map(example => [
// Does some arbitrary processing on the key (with type information available)
example[0].toUpperCase(),
// Does some arbitrary processing on the value (with type information available)
example[1].toFixed()
]);
const example: Example = {someKey: 1};
const entries = Object.entries(example) as Entries<Example>;
const output = manipulatesEntries(entries);
// Objects
const objectExample = {a: 1};
const objectEntries: Entries<typeof objectExample> = [['a', 1]];
// Arrays
const arrayExample = ['a', 1];
const arrayEntries: Entries<typeof arrayExample> = [[0, 'a'], [1, 1]];
// Maps
const mapExample = new Map([['a', 1]]);
const mapEntries: Entries<typeof map> = [['a', 1]];
// Sets
const setExample = new Set(['a', 1]);
const setEntries: Entries<typeof setExample> = [['a', 'a'], [1, 1]];
```
*/
export type Entries<BaseType> =
BaseType extends Map<unknown, unknown> ? MapEntries<BaseType>
: BaseType extends Set<unknown> ? SetEntries<BaseType>
: BaseType extends unknown[] ? ArrayEntries<BaseType>
: BaseType extends object ? ObjectEntries<BaseType>
: never;
type MapKey<BaseType> = BaseType extends Map<infer KeyType, unknown> ? KeyType : never;
type MapValue<BaseType> = BaseType extends Map<unknown, infer ValueType> ? ValueType : never;
export type ArrayEntry<BaseType extends readonly unknown[]> = [number, BaseType[number]];
export type MapEntry<BaseType> = [MapKey<BaseType>, MapValue<BaseType>];
export type ObjectEntry<BaseType> = [keyof BaseType, BaseType[keyof BaseType]];
export type SetEntry<BaseType> = BaseType extends Set<infer ItemType> ? [ItemType, ItemType] : never;
/**
Many collections have an `entries` method which returns an array of a given object's own enumerable string-keyed property [key, value] pairs. The `Entry` type will return the type of that collection's entry.
For example the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries|`Object`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries|`Map`}, {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries|`Array`}, and {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries|`Set`} collections all have this method. Note that `WeakMap` and `WeakSet` do not have this method since their entries are not enumerable.
@see `Entries` if you want to just access the type of the array of entries (which is the return of the `.entries()` method).
@example
```
import {Entry} from 'type-fest';
interface Example {
someKey: number;
}
const manipulatesEntry = (example: Entry<Example>) => [
// Does some arbitrary processing on the key (with type information available)
example[0].toUpperCase(),
// Does some arbitrary processing on the value (with type information available)
example[1].toFixed(),
];
const example: Example = {someKey: 1};
const entry = Object.entries(example)[0] as Entry<Example>;
const output = manipulatesEntry(entry);
// Objects
const objectExample = {a: 1};
const objectEntry: Entry<typeof objectExample> = ['a', 1];
// Arrays
const arrayExample = ['a', 1];
const arrayEntryString: Entry<typeof arrayExample> = [0, 'a'];
const arrayEntryNumber: Entry<typeof arrayExample> = [1, 1];
// Maps
const mapExample = new Map([['a', 1]]);
const mapEntry: Entry<typeof map> = ['a', 1];
// Sets
const setExample = new Set(['a', 1]);
const setEntryString: Entry<typeof setExample> = ['a', 'a'];
const setEntryNumber: Entry<typeof setExample> = [1, 1];
```
*/
export type Entry<BaseType> =
BaseType extends Map<unknown, unknown> ? MapEntry<BaseType>
: BaseType extends Set<unknown> ? SetEntry<BaseType>
: BaseType extends unknown[] ? ArrayEntry<BaseType>
: BaseType extends object ? ObjectEntry<BaseType>
: never;
/**
Create a type from an object type without certain keys.
This type is a stricter version of [`Omit`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html#the-omit-helper-type). The `Omit` type does not restrict the omitted keys to be keys present on the given type, while `Except` does. The benefits of a stricter type are avoiding typos and allowing the compiler to pick up on rename refactors automatically.
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/30825) if you want to have the stricter version as a built-in in TypeScript.
@example
```
import {Except} from 'type-fest';
type Foo = {
a: number;
b: string;
c: boolean;
};
type FooWithoutA = Except<Foo, 'a' | 'c'>;
//=> {b: string};
```
*/
export type Except<ObjectType, KeysType extends keyof ObjectType> = Pick<ObjectType, Exclude<keyof ObjectType, KeysType>>;
/**
Methods to exclude.
*/
type ArrayLengthMutationKeys = 'splice' | 'push' | 'pop' | 'shift' | 'unshift';
/**
Create a type that represents an array of the given type and length. The array's length and the `Array` prototype methods that manipulate its length are excluded in the resulting type.
Please participate in [this issue](https://github.com/microsoft/TypeScript/issues/26223) if you want to have a similiar type built into TypeScript.
Use-cases:
- Declaring fixed-length tuples or arrays with a large number of items.
- Creating a range union (for example, `0 | 1 | 2 | 3 | 4` from the keys of such a type) without having to resort to recursive types.
- Creating an array of coordinates with a static length, for example, length of 3 for a 3D vector.
@example
```
import {FixedLengthArray} from 'type-fest';
type FencingTeam = FixedLengthArray<string, 3>;
const guestFencingTeam: FencingTeam = ['Josh', 'Michael', 'Robert'];
const homeFencingTeam: FencingTeam = ['George', 'John'];
//=> error TS2322: Type string[] is not assignable to type 'FencingTeam'
guestFencingTeam.push('Sam');
//=> error TS2339: Property 'push' does not exist on type 'FencingTeam'
```
*/
export type FixedLengthArray<Element, Length extends number, ArrayPrototype = [Element, ...Element[]]> = Pick<
ArrayPrototype,
Exclude<keyof ArrayPrototype, ArrayLengthMutationKeys>
> & {
[index: number]: Element;
[Symbol.iterator]: () => IterableIterator<Element>;
readonly length: Length;
};
/**
Get the element type of an `Iterable`/`AsyncIterable`. For example, an array or a generator.
This can be useful, for example, if you want to get the type that is yielded in a generator function. Often the return type of those functions are not specified.
This type works with both `Iterable`s and `AsyncIterable`s, so it can be use with synchronous and asynchronous generators.
Here is an example of `IterableElement` in action with a generator function:
@example
```
function * iAmGenerator() {
yield 1;
yield 2;
}
type MeNumber = IterableElement<ReturnType<typeof iAmGenerator>>
```
And here is an example with an async generator:
@example
```
async function * iAmGeneratorAsync() {
yield 'hi';
yield true;
}
type MeStringOrBoolean = IterableElement<ReturnType<typeof iAmGeneratorAsync>>
```
Many types in JavaScript/TypeScript are iterables. This type works on all types that implement those interfaces. For example, `Array`, `Set`, `Map`, `stream.Readable`, etc.
An example with an array of strings:
@example
```
type MeString = IterableElement<string[]>
```
*/
export type IterableElement<TargetIterable> =
TargetIterable extends Iterable<infer ElementType> ?
ElementType :
TargetIterable extends AsyncIterable<infer ElementType> ?
ElementType :
never;
import {Primitive} from './basic';
/**
Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union.
Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals.
This type is a workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). It will be removed as soon as it's not needed anymore.
@example
```
import {LiteralUnion} from 'type-fest';
// Before
type Pet = 'dog' | 'cat' | string;
const pet: Pet = '';
// Start typing in your TypeScript-enabled IDE.
// You **will not** get auto-completion for `dog` and `cat` literals.
// After
type Pet2 = LiteralUnion<'dog' | 'cat', string>;
const pet: Pet2 = '';
// You **will** get auto-completion for `dog` and `cat` literals.
```
*/
export type LiteralUnion<
LiteralType,
BaseType extends Primitive
> = LiteralType | (BaseType & {_?: never});
// Helper type. Not useful on its own.
type Without<FirstType, SecondType> = {[KeyType in Exclude<keyof FirstType, keyof SecondType>]?: never};
/**
Create a type that has mutually exclusive keys.
This type was inspired by [this comment](https://github.com/Microsoft/TypeScript/issues/14094#issuecomment-373782604).
This type works with a helper type, called `Without`. `Without<FirstType, SecondType>` produces a type that has only keys from `FirstType` which are not present on `SecondType` and sets the value type for these keys to `never`. This helper type is then used in `MergeExclusive` to remove keys from either `FirstType` or `SecondType`.
@example
```
import {MergeExclusive} from 'type-fest';
interface ExclusiveVariation1 {
exclusive1: boolean;
}
interface ExclusiveVariation2 {
exclusive2: string;
}
type ExclusiveOptions = MergeExclusive<ExclusiveVariation1, ExclusiveVariation2>;
let exclusiveOptions: ExclusiveOptions;
exclusiveOptions = {exclusive1: true};
//=> Works
exclusiveOptions = {exclusive2: 'hi'};
//=> Works
exclusiveOptions = {exclusive1: true, exclusive2: 'hi'};
//=> Error
```
*/
export type MergeExclusive<FirstType, SecondType> =
(FirstType | SecondType) extends object ?
(Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) :
FirstType | SecondType;
import {Except} from './except';
/**
Merge two types into a new type. Keys of the second type overrides keys of the first type.
@example
```
import {Merge} from 'type-fest';
type Foo = {
a: number;
b: string;
};
type Bar = {
b: number;
};
const ab: Merge<Foo, Bar> = {a: 1, b: 2};
```
*/
export type Merge<FirstType, SecondType> = Except<FirstType, Extract<keyof FirstType, keyof SecondType>> & SecondType;
/**
Convert an object with `readonly` keys into a mutable object. Inverse of `Readonly<T>`.
This can be used to [store and mutate options within a class](https://github.com/sindresorhus/pageres/blob/4a5d05fca19a5fbd2f53842cbf3eb7b1b63bddd2/source/index.ts#L72), [edit `readonly` objects within tests](https://stackoverflow.com/questions/50703834), and [construct a `readonly` object within a function](https://github.com/Microsoft/TypeScript/issues/24509).
@example
```
import {Mutable} from 'type-fest';
type Foo = {
readonly a: number;
readonly b: string;
};
const mutableFoo: Mutable<Foo> = {a: 1, b: '2'};
mutableFoo.a = 3;
```
*/
export type Mutable<ObjectType> = {
// For each `Key` in the keys of `ObjectType`, make a mapped type by removing the `readonly` modifier from the key.
-readonly [KeyType in keyof ObjectType]: ObjectType[KeyType];
};
/**
Create an opaque type, which hides its internal details from the public, and can only be created by being used explicitly.
The generic type parameter can be anything. It doesn't have to be an object.
[Read more about opaque types.](https://codemix.com/opaque-types-in-javascript/)
There have been several discussions about adding this feature to TypeScript via the `opaque type` operator, similar to how Flow does it. Unfortunately, nothing has (yet) moved forward:
- [Microsoft/TypeScript#15408](https://github.com/Microsoft/TypeScript/issues/15408)
- [Microsoft/TypeScript#15807](https://github.com/Microsoft/TypeScript/issues/15807)
@example
```
import {Opaque} from 'type-fest';
type AccountNumber = Opaque<number, 'AccountNumber'>;
type AccountBalance = Opaque<number, 'AccountBalance'>;
// The Token parameter allows the compiler to differentiate between types, whereas "unknown" will not. For example, consider the following structures:
type ThingOne = Opaque<string>;
type ThingTwo = Opaque<string>;
// To the compiler, these types are allowed to be cast to each other as they have the same underlying type. They are both `string & { __opaque__: unknown }`.
// To avoid this behaviour, you would instead pass the "Token" parameter, like so.
type NewThingOne = Opaque<string, 'ThingOne'>;
type NewThingTwo = Opaque<string, 'ThingTwo'>;
// Now they're completely separate types, so the following will fail to compile.
function createNewThingOne (): NewThingOne {
// As you can see, casting from a string is still allowed. However, you may not cast NewThingOne to NewThingTwo, and vice versa.
return 'new thing one' as NewThingOne;
}
// This will fail to compile, as they are fundamentally different types.
const thingTwo = createNewThingOne() as NewThingTwo;
// Here's another example of opaque typing.
function createAccountNumber(): AccountNumber {
return 2 as AccountNumber;
}
function getMoneyForAccount(accountNumber: AccountNumber): AccountBalance {
return 4 as AccountBalance;
}
// This will compile successfully.
getMoneyForAccount(createAccountNumber());
// But this won't, because it has to be explicitly passed as an `AccountNumber` type.
getMoneyForAccount(2);
// You can use opaque values like they aren't opaque too.
const accountNumber = createAccountNumber();
// This will not compile successfully.
const newAccountNumber = accountNumber + 2;
// As a side note, you can (and should) use recursive types for your opaque types to make them stronger and hopefully easier to type.
type Person = {
id: Opaque<number, Person>;
name: string;
};
```
*/
export type Opaque<Type, Token = unknown> = Type & {readonly __opaque__: Token};
import {LiteralUnion} from './literal-union';
declare namespace PackageJson {
/**
A person who has been involved in creating or maintaining the package.
*/
export type Person =
| string
| {
name: string;
url?: string;
email?: string;
};
export type BugsLocation =
| string
| {
/**
The URL to the package's issue tracker.
*/
url?: string;
/**
The email address to which issues should be reported.
*/
email?: string;
};
export interface DirectoryLocations {
[directoryType: string]: unknown;
/**
Location for executable scripts. Sugar to generate entries in the `bin` property by walking the folder.
*/
bin?: string;
/**
Location for Markdown files.
*/
doc?: string;
/**
Location for example scripts.
*/
example?: string;
/**
Location for the bulk of the library.
*/
lib?: string;
/**
Location for man pages. Sugar to generate a `man` array by walking the folder.
*/
man?: string;
/**
Location for test files.
*/
test?: string;
}
export type Scripts = {
/**
Run **before** the package is published (Also run on local `npm install` without any arguments).
*/
prepublish?: string;
/**
Run both **before** the package is packed and published, and on local `npm install` without any arguments. This is run **after** `prepublish`, but **before** `prepublishOnly`.
*/
prepare?: string;
/**
Run **before** the package is prepared and packed, **only** on `npm publish`.
*/
prepublishOnly?: string;
/**
Run **before** a tarball is packed (on `npm pack`, `npm publish`, and when installing git dependencies).
*/
prepack?: string;
/**
Run **after** the tarball has been generated and moved to its final destination.
*/
postpack?: string;
/**
Run **after** the package is published.
*/
publish?: string;
/**
Run **after** the package is published.
*/
postpublish?: string;
/**
Run **before** the package is installed.
*/
preinstall?: string;
/**
Run **after** the package is installed.
*/
install?: string;
/**
Run **after** the package is installed and after `install`.
*/
postinstall?: string;
/**
Run **before** the package is uninstalled and before `uninstall`.
*/
preuninstall?: string;
/**
Run **before** the package is uninstalled.
*/
uninstall?: string;
/**
Run **after** the package is uninstalled.
*/
postuninstall?: string;
/**
Run **before** bump the package version and before `version`.
*/
preversion?: string;
/**
Run **before** bump the package version.
*/
version?: string;
/**
Run **after** bump the package version.
*/
postversion?: string;
/**
Run with the `npm test` command, before `test`.
*/
pretest?: string;
/**
Run with the `npm test` command.
*/
test?: string;
/**
Run with the `npm test` command, after `test`.
*/
posttest?: string;
/**
Run with the `npm stop` command, before `stop`.
*/
prestop?: string;
/**
Run with the `npm stop` command.
*/
stop?: string;
/**
Run with the `npm stop` command, after `stop`.
*/
poststop?: string;
/**
Run with the `npm start` command, before `start`.
*/
prestart?: string;
/**
Run with the `npm start` command.
*/
start?: string;
/**
Run with the `npm start` command, after `start`.
*/
poststart?: string;
/**
Run with the `npm restart` command, before `restart`. Note: `npm restart` will run the `stop` and `start` scripts if no `restart` script is provided.
*/
prerestart?: string;
/**
Run with the `npm restart` command. Note: `npm restart` will run the `stop` and `start` scripts if no `restart` script is provided.
*/
restart?: string;
/**
Run with the `npm restart` command, after `restart`. Note: `npm restart` will run the `stop` and `start` scripts if no `restart` script is provided.
*/
postrestart?: string;
} & Record<string, string>;
/**
Dependencies of the package. The version range is a string which has one or more space-separated descriptors. Dependencies can also be identified with a tarball or Git URL.
*/
export type Dependency = Record<string, string>;
/**
Conditions which provide a way to resolve a package entry point based on the environment.
*/
export type ExportCondition = LiteralUnion<
| 'import'
| 'require'
| 'node'
| 'deno'
| 'browser'
| 'electron'
| 'react-native'
| 'default',
string
>;
/**
Entry points of a module, optionally with conditions and subpath exports.
*/
export type Exports =
| string
| {[key in ExportCondition]: Exports}
| {[key: string]: Exports}; // eslint-disable-line @typescript-eslint/consistent-indexed-object-style
export interface NonStandardEntryPoints {
/**
An ECMAScript module ID that is the primary entry point to the program.
*/
module?: string;
/**
A module ID with untranspiled code that is the primary entry point to the program.
*/
esnext?:
| string
| {
[moduleName: string]: string | undefined;
main?: string;
browser?: string;
};
/**
A hint to JavaScript bundlers or component tools when packaging modules for client side use.
*/
browser?:
| string
| Record<string, string | false>;
/**
Denote which files in your project are "pure" and therefore safe for Webpack to prune if unused.
[Read more.](https://webpack.js.org/guides/tree-shaking/)
*/
sideEffects?: boolean | string[];
}
export interface TypeScriptConfiguration {
/**
Location of the bundled TypeScript declaration file.
*/
types?: string;
/**
Location of the bundled TypeScript declaration file. Alias of `types`.
*/
typings?: string;
}
/**
An alternative configuration for Yarn workspaces.
*/
export interface WorkspaceConfig {
/**
An array of workspace pattern strings which contain the workspace packages.
*/
packages?: WorkspacePattern[];
/**
Designed to solve the problem of packages which break when their `node_modules` are moved to the root workspace directory - a process known as hoisting. For these packages, both within your workspace, and also some that have been installed via `node_modules`, it is important to have a mechanism for preventing the default Yarn workspace behavior. By adding workspace pattern strings here, Yarn will resume non-workspace behavior for any package which matches the defined patterns.
[Read more](https://classic.yarnpkg.com/blog/2018/02/15/nohoist/)
*/
nohoist?: WorkspacePattern[];
}
/**
A workspace pattern points to a directory or group of directories which contain packages that should be included in the workspace installation process.
The patterns are handled with [minimatch](https://github.com/isaacs/minimatch).
@example
`docs` → Include the docs directory and install its dependencies.
`packages/*` → Include all nested directories within the packages directory, like `packages/cli` and `packages/core`.
*/
type WorkspacePattern = string;
export interface YarnConfiguration {
/**
Used to configure [Yarn workspaces](https://classic.yarnpkg.com/docs/workspaces/).
Workspaces allow you to manage multiple packages within the same repository in such a way that you only need to run `yarn install` once to install all of them in a single pass.
Please note that the top-level `private` property of `package.json` **must** be set to `true` in order to use workspaces.
*/
workspaces?: WorkspacePattern[] | WorkspaceConfig;
/**
If your package only allows one version of a given dependency, and you’d like to enforce the same behavior as `yarn install --flat` on the command-line, set this to `true`.
Note that if your `package.json` contains `"flat": true` and other packages depend on yours (e.g. you are building a library rather than an app), those other packages will also need `"flat": true` in their `package.json` or be installed with `yarn install --flat` on the command-line.
*/
flat?: boolean;
/**
Selective version resolutions. Allows the definition of custom package versions inside dependencies without manual edits in the `yarn.lock` file.
*/
resolutions?: Dependency;
}
export interface JSPMConfiguration {
/**
JSPM configuration.
*/
jspm?: PackageJson;
}
/**
Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). Containing standard npm properties.
*/
export interface PackageJsonStandard {
/**
The name of the package.
*/
name?: string;
/**
Package version, parseable by [`node-semver`](https://github.com/npm/node-semver).
*/
version?: string;
/**
Package description, listed in `npm search`.
*/
description?: string;
/**
Keywords associated with package, listed in `npm search`.
*/
keywords?: string[];
/**
The URL to the package's homepage.
*/
homepage?: LiteralUnion<'.', string>;
/**
The URL to the package's issue tracker and/or the email address to which issues should be reported.
*/
bugs?: BugsLocation;
/**
The license for the package.
*/
license?: string;
/**
The licenses for the package.
*/
licenses?: Array<{
type?: string;
url?: string;
}>;
author?: Person;
/**
A list of people who contributed to the package.
*/
contributors?: Person[];
/**
A list of people who maintain the package.
*/
maintainers?: Person[];
/**
The files included in the package.
*/
files?: string[];
/**
Resolution algorithm for importing ".js" files from the package's scope.
[Read more.](https://nodejs.org/api/esm.html#esm_package_json_type_field)
*/
type?: 'module' | 'commonjs';
/**
The module ID that is the primary entry point to the program.
*/
main?: string;
/**
Standard entry points of the package, with enhanced support for ECMAScript Modules.
[Read more.](https://nodejs.org/api/esm.html#esm_package_entry_points)
*/
exports?: Exports;
/**
The executable files that should be installed into the `PATH`.
*/
bin?:
| string
| Record<string, string>;
/**
Filenames to put in place for the `man` program to find.
*/
man?: string | string[];
/**
Indicates the structure of the package.
*/
directories?: DirectoryLocations;
/**
Location for the code repository.
*/
repository?:
| string
| {
type: string;
url: string;
/**
Relative path to package.json if it is placed in non-root directory (for example if it is part of a monorepo).
[Read more.](https://github.com/npm/rfcs/blob/latest/implemented/0010-monorepo-subdirectory-declaration.md)
*/
directory?: string;
};
/**
Script commands that are run at various times in the lifecycle of the package. The key is the lifecycle event, and the value is the command to run at that point.
*/
scripts?: Scripts;
/**
Is used to set configuration parameters used in package scripts that persist across upgrades.
*/
config?: Record<string, unknown>;
/**
The dependencies of the package.
*/
dependencies?: Dependency;
/**
Additional tooling dependencies that are not required for the package to work. Usually test, build, or documentation tooling.
*/
devDependencies?: Dependency;
/**
Dependencies that are skipped if they fail to install.
*/
optionalDependencies?: Dependency;
/**
Dependencies that will usually be required by the package user directly or via another dependency.
*/
peerDependencies?: Dependency;
/**
Indicate peer dependencies that are optional.
*/
peerDependenciesMeta?: Record<string, {optional: true}>;
/**
Package names that are bundled when the package is published.
*/
bundledDependencies?: string[];
/**
Alias of `bundledDependencies`.
*/
bundleDependencies?: string[];
/**
Engines that this package runs on.
*/
engines?: {
[EngineName in 'npm' | 'node' | string]: string;
};
/**
@deprecated
*/
engineStrict?: boolean;
/**
Operating systems the module runs on.
*/
os?: Array<LiteralUnion<
| 'aix'
| 'darwin'
| 'freebsd'
| 'linux'
| 'openbsd'
| 'sunos'
| 'win32'
| '!aix'
| '!darwin'
| '!freebsd'
| '!linux'
| '!openbsd'
| '!sunos'
| '!win32',
string
>>;
/**
CPU architectures the module runs on.
*/
cpu?: Array<LiteralUnion<
| 'arm'
| 'arm64'
| 'ia32'
| 'mips'
| 'mipsel'
| 'ppc'
| 'ppc64'
| 's390'
| 's390x'
| 'x32'
| 'x64'
| '!arm'
| '!arm64'
| '!ia32'
| '!mips'
| '!mipsel'
| '!ppc'
| '!ppc64'
| '!s390'
| '!s390x'
| '!x32'
| '!x64',
string
>>;
/**
If set to `true`, a warning will be shown if package is installed locally. Useful if the package is primarily a command-line application that should be installed globally.
@deprecated
*/
preferGlobal?: boolean;
/**
If set to `true`, then npm will refuse to publish it.
*/
private?: boolean;
/**
A set of config values that will be used at publish-time. It's especially handy to set the tag, registry or access, to ensure that a given package is not tagged with 'latest', published to the global public registry or that a scoped module is private by default.
*/
publishConfig?: Record<string, unknown>;
/**
Describes and notifies consumers of a package's monetary support information.
[Read more.](https://github.com/npm/rfcs/blob/latest/accepted/0017-add-funding-support.md)
*/
funding?: string | {
/**
The type of funding.
*/
type?: LiteralUnion<
| 'github'
| 'opencollective'
| 'patreon'
| 'individual'
| 'foundation'
| 'corporation',
string
>;
/**
The URL to the funding page.
*/
url: string;
};
}
}
/**
Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). Also includes types for fields used by other popular projects, like TypeScript and Yarn.
*/
export type PackageJson =
PackageJson.PackageJsonStandard &
PackageJson.NonStandardEntryPoints &
PackageJson.TypeScriptConfiguration &
PackageJson.YarnConfiguration &
PackageJson.JSPMConfiguration;
import {Primitive} from './basic';
/**
Create a type from another type with all keys and nested keys set to optional.
Use-cases:
- Merging a default settings/config object with another object, the second object would be a deep partial of the default object.
- Mocking and testing complex entities, where populating an entire object with its keys would be redundant in terms of the mock or test.
@example
```
import {PartialDeep} from 'type-fest';
const settings: Settings = {
textEditor: {
fontSize: 14;
fontColor: '#000000';
fontWeight: 400;
}
autocomplete: false;
autosave: true;
};
const applySavedSettings = (savedSettings: PartialDeep<Settings>) => {
return {...settings, ...savedSettings};
}
settings = applySavedSettings({textEditor: {fontWeight: 500}});
```
*/
export type PartialDeep<T> = T extends Primitive
? Partial<T>
: T extends Map<infer KeyType, infer ValueType>
? PartialMapDeep<KeyType, ValueType>
: T extends Set<infer ItemType>
? PartialSetDeep<ItemType>
: T extends ReadonlyMap<infer KeyType, infer ValueType>
? PartialReadonlyMapDeep<KeyType, ValueType>
: T extends ReadonlySet<infer ItemType>
? PartialReadonlySetDeep<ItemType>
: T extends ((...arguments: any[]) => unknown)
? T | undefined
: T extends object
? PartialObjectDeep<T>
: unknown;
/**
Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`.
*/
interface PartialMapDeep<KeyType, ValueType> extends Map<PartialDeep<KeyType>, PartialDeep<ValueType>> {}
/**
Same as `PartialDeep`, but accepts only `Set`s as inputs. Internal helper for `PartialDeep`.
*/
interface PartialSetDeep<T> extends Set<PartialDeep<T>> {}
/**
Same as `PartialDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `PartialDeep`.
*/
interface PartialReadonlyMapDeep<KeyType, ValueType> extends ReadonlyMap<PartialDeep<KeyType>, PartialDeep<ValueType>> {}
/**
Same as `PartialDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `PartialDeep`.
*/
interface PartialReadonlySetDeep<T> extends ReadonlySet<PartialDeep<T>> {}
/**
Same as `PartialDeep`, but accepts only `object`s as inputs. Internal helper for `PartialDeep`.
*/
type PartialObjectDeep<ObjectType extends object> = {
[KeyType in keyof ObjectType]?: PartialDeep<ObjectType[KeyType]>
};
/**
Create a type that represents either the value or the value wrapped in `PromiseLike`.
Use-cases:
- A function accepts a callback that may either return a value synchronously or may return a promised value.
- This type could be the return type of `Promise#then()`, `Promise#catch()`, and `Promise#finally()` callbacks.
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/31394) if you want to have this type as a built-in in TypeScript.
@example
```
import {Promisable} from 'type-fest';
async function logger(getLogEntry: () => Promisable<string>): Promise<void> {
const entry = await getLogEntry();
console.log(entry);
}
logger(() => 'foo');
logger(() => Promise.resolve('bar'));
```
*/
export type Promisable<T> = T | PromiseLike<T>;
/**
Returns the type that is wrapped inside a `Promise` type.
If the type is a nested Promise, it is unwrapped recursively until a non-Promise type is obtained.
If the type is not a `Promise`, the type itself is returned.
@example
```
import {PromiseValue} from 'type-fest';
type AsyncData = Promise<string>;
let asyncData: PromiseValue<AsyncData> = Promise.resolve('ABC');
type Data = PromiseValue<AsyncData>;
let data: Data = await asyncData;
// Here's an example that shows how this type reacts to non-Promise types.
type SyncData = PromiseValue<string>;
let syncData: SyncData = getSyncData();
// Here's an example that shows how this type reacts to recursive Promise types.
type RecursiveAsyncData = Promise<Promise<string> >;
let recursiveAsyncData: PromiseValue<RecursiveAsyncData> = Promise.resolve(Promise.resolve('ABC'));
```
*/
export type PromiseValue<PromiseType, Otherwise = PromiseType> = PromiseType extends Promise<infer Value>
? { 0: PromiseValue<Value>; 1: Value }[PromiseType extends Promise<unknown> ? 0 : 1]
: Otherwise;
import {Primitive} from './basic';
/**
Convert `object`s, `Map`s, `Set`s, and `Array`s and all of their keys/elements into immutable structures recursively.
This is useful when a deeply nested structure needs to be exposed as completely immutable, for example, an imported JSON module or when receiving an API response that is passed around.
Please upvote [this issue](https://github.com/microsoft/TypeScript/issues/13923) if you want to have this type as a built-in in TypeScript.
@example
```
// data.json
{
"foo": ["bar"]
}
// main.ts
import {ReadonlyDeep} from 'type-fest';
import dataJson = require('./data.json');
const data: ReadonlyDeep<typeof dataJson> = dataJson;
export default data;
// test.ts
import data from './main';
data.foo.push('bar');
//=> error TS2339: Property 'push' does not exist on type 'readonly string[]'
```
*/
export type ReadonlyDeep<T> = T extends Primitive | ((...arguments: any[]) => unknown)
? T
: T extends ReadonlyMap<infer KeyType, infer ValueType>
? ReadonlyMapDeep<KeyType, ValueType>
: T extends ReadonlySet<infer ItemType>
? ReadonlySetDeep<ItemType>
: T extends object
? ReadonlyObjectDeep<T>
: unknown;
/**
Same as `ReadonlyDeep`, but accepts only `ReadonlyMap`s as inputs. Internal helper for `ReadonlyDeep`.
*/
interface ReadonlyMapDeep<KeyType, ValueType>
extends ReadonlyMap<ReadonlyDeep<KeyType>, ReadonlyDeep<ValueType>> {}
/**
Same as `ReadonlyDeep`, but accepts only `ReadonlySet`s as inputs. Internal helper for `ReadonlyDeep`.
*/
interface ReadonlySetDeep<ItemType>
extends ReadonlySet<ReadonlyDeep<ItemType>> {}
/**
Same as `ReadonlyDeep`, but accepts only `object`s as inputs. Internal helper for `ReadonlyDeep`.
*/
type ReadonlyObjectDeep<ObjectType extends object> = {
readonly [KeyType in keyof ObjectType]: ReadonlyDeep<ObjectType[KeyType]>
};
import {Except} from './except';
/**
Create a type that requires at least one of the given keys. The remaining keys are kept as is.
@example
```
import {RequireAtLeastOne} from 'type-fest';
type Responder = {
text?: () => string;
json?: () => string;
secure?: boolean;
};
const responder: RequireAtLeastOne<Responder, 'text' | 'json'> = {
json: () => '{"message": "ok"}',
secure: true
};
```
*/
export type RequireAtLeastOne<
ObjectType,
KeysType extends keyof ObjectType = keyof ObjectType
> = {
// For each `Key` in `KeysType` make a mapped type:
[Key in KeysType]-?: Required<Pick<ObjectType, Key>> & // 1. Make `Key`'s type required
// 2. Make all other keys in `KeysType` optional
Partial<Pick<ObjectType, Exclude<KeysType, Key>>>;
}[KeysType] &
// 3. Add the remaining keys not in `KeysType`
Except<ObjectType, KeysType>;
// TODO: Remove this when we target TypeScript >=3.5.
type _Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
/**
Create a type that requires exactly one of the given keys and disallows more. The remaining keys are kept as is.
Use-cases:
- Creating interfaces for components that only need one of the keys to display properly.
- Declaring generic keys in a single place for a single use-case that gets narrowed down via `RequireExactlyOne`.
The caveat with `RequireExactlyOne` is that TypeScript doesn't always know at compile time every key that will exist at runtime. Therefore `RequireExactlyOne` can't do anything to prevent extra keys it doesn't know about.
@example
```
import {RequireExactlyOne} from 'type-fest';
type Responder = {
text: () => string;
json: () => string;
secure: boolean;
};
const responder: RequireExactlyOne<Responder, 'text' | 'json'> = {
// Adding a `text` key here would cause a compile error.
json: () => '{"message": "ok"}',
secure: true
};
```
*/
export type RequireExactlyOne<ObjectType, KeysType extends keyof ObjectType = keyof ObjectType> =
{[Key in KeysType]: (
Required<Pick<ObjectType, Key>> &
Partial<Record<Exclude<KeysType, Key>, never>>
)}[KeysType] & _Omit<ObjectType, KeysType>;
import {Except} from './except';
/**
Create a type that makes the given keys optional. The remaining keys are kept as is. The sister of the `SetRequired` type.
Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are optional.
@example
```
import {SetOptional} from 'type-fest';
type Foo = {
a: number;
b?: string;
c: boolean;
}
type SomeOptional = SetOptional<Foo, 'b' | 'c'>;
// type SomeOptional = {
// a: number;
// b?: string; // Was already optional and still is.
// c?: boolean; // Is now optional.
// }
```
*/
export type SetOptional<BaseType, Keys extends keyof BaseType = keyof BaseType> =
// Pick just the keys that are not optional from the base type.
Except<BaseType, Keys> &
// Pick the keys that should be optional from the base type and make them optional.
Partial<Pick<BaseType, Keys>> extends
// If `InferredType` extends the previous, then for each key, use the inferred type key.
infer InferredType
? {[KeyType in keyof InferredType]: InferredType[KeyType]}
: never;
import {Except} from './except';
/**
Create a type that makes the given keys required. The remaining keys are kept as is. The sister of the `SetOptional` type.
Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are required.
@example
```
import {SetRequired} from 'type-fest';
type Foo = {
a?: number;
b: string;
c?: boolean;
}
type SomeRequired = SetRequired<Foo, 'b' | 'c'>;
// type SomeRequired = {
// a?: number;
// b: string; // Was already required and still is.
// c: boolean; // Is now required.
// }
```
*/
export type SetRequired<BaseType, Keys extends keyof BaseType = keyof BaseType> =
// Pick just the keys that are not required from the base type.
Except<BaseType, Keys> &
// Pick the keys that should be required from the base type and make them required.
Required<Pick<BaseType, Keys>> extends
// If `InferredType` extends the previous, then for each key, use the inferred type key.
infer InferredType
? {[KeyType in keyof InferredType]: InferredType[KeyType]}
: never;
type IsAny<T> = 0 extends (1 & T) ? true : false; // https://stackoverflow.com/a/49928360/3406963
type IsNever<T> = [T] extends [never] ? true : false;
type IsUnknown<T> = IsNever<T> extends false ? T extends unknown ? unknown extends T ? IsAny<T> extends false ? true : false : false : false : false;
/**
Create a function type with a return type of your choice and the same parameters as the given function type.
Use-case: You want to define a wrapped function that returns something different while receiving the same parameters. For example, you might want to wrap a function that can throw an error into one that will return `undefined` instead.
@example
```
import {SetReturnType} from 'type-fest';
type MyFunctionThatCanThrow = (foo: SomeType, bar: unknown) => SomeOtherType;
type MyWrappedFunction = SetReturnType<MyFunctionThatCanThrow, SomeOtherType | undefined>;
//=> type MyWrappedFunction = (foo: SomeType, bar: unknown) => SomeOtherType | undefined;
```
*/
export type SetReturnType<Fn extends (...args: any[]) => any, TypeToReturn> =
// Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter.
Fn extends (this: infer ThisArg, ...args: infer Arguments) => any ? (
// If a function did not specify the `this` fake parameter, it will be inferred to `unknown`.
// We want to detect this situation just to display a friendlier type upon hovering on an IntelliSense-powered IDE.
IsUnknown<ThisArg> extends true ? (...args: Arguments) => TypeToReturn : (this: ThisArg, ...args: Arguments) => TypeToReturn
) : (
// This part should be unreachable, but we make it meaningful just in case…
(...args: Parameters<Fn>) => TypeToReturn
);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment