-
-
Notifications
You must be signed in to change notification settings - Fork 502
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
- Loading branch information
1 parent
37e2816
commit 7714f57
Showing
5 changed files
with
172 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
type MapKey<BaseType> = BaseType extends Map<infer KeyType, unknown> ? KeyType : never; | ||
type MapValue<BaseType> = BaseType extends Map<unknown, infer ValueType> ? ValueType : never; | ||
|
||
type ArrayEntry<BaseType extends readonly unknown[]> = [number, BaseType[number]]; | ||
type MapEntry<BaseType> = [MapKey<BaseType>, MapValue<BaseType>]; | ||
type ObjectEntry<BaseType> = [keyof BaseType, BaseType[keyof BaseType]]; | ||
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import {Entries} from '../source/entries'; | ||
import {Entry} from '../source/entry'; | ||
import {expectAssignable} from 'tsd'; | ||
|
||
// Objects | ||
const objectExample = {a: 1}; | ||
|
||
const objectEntry: Entry<typeof objectExample> = ['a', 1]; | ||
expectAssignable<[string, number]>(objectEntry); | ||
|
||
const objectEntries: Entries<typeof objectExample> = [objectEntry]; | ||
expectAssignable<Array<[string, number]>>(objectEntries); | ||
|
||
// Maps | ||
const mapExample = new Map([['a', 1]]); | ||
|
||
const mapEntry: Entry<typeof mapExample> = ['a', 1]; | ||
expectAssignable<[string, number]>(mapEntry); | ||
|
||
const mapEntries: Entries<typeof mapExample> = [mapEntry]; | ||
expectAssignable<Array<[string, number]>>(mapEntries); | ||
|
||
// Arrays | ||
const arrayExample = ['a', 1]; | ||
|
||
const arrayEntryString: Entry<typeof arrayExample> = [0, 'a']; | ||
expectAssignable<[number, (string | number)]>(arrayEntryString); | ||
|
||
const arrayEntryNumber: Entry<typeof arrayExample> = [1, 1]; | ||
expectAssignable<[number, (string | number)]>(arrayEntryNumber); | ||
|
||
const arrayEntries: Entries<typeof arrayExample> = [ | ||
arrayEntryString, | ||
arrayEntryNumber | ||
]; | ||
expectAssignable<Array<[number, (string | number)]>>(arrayEntries); | ||
|
||
// Sets | ||
const setExample = new Set(['a', 1]); | ||
|
||
const setEntryString: Entry<typeof setExample> = ['a', 'a']; | ||
expectAssignable<[(string | number), (string | number)]>(setEntryString); | ||
|
||
const setEntryNumber: Entry<typeof setExample> = [1, 1]; | ||
expectAssignable<[(string | number), (string | number)]>(setEntryNumber); | ||
|
||
const setEntries: Entries<typeof setExample> = [ | ||
setEntryString, | ||
setEntryNumber | ||
]; | ||
expectAssignable<Array<[(string | number), (string | number)]>>(setEntries); |