Skip to content

Commit

Permalink
refactor(ValuesType): Re-organize and add docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
Axure committed Sep 8, 2019
1 parent 83ebf5b commit 426355a
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 90 deletions.
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ Issues can be funded by anyone and the money will be transparently distributed t
* [`Subtract<T, T1>`](#subtractt-t1)
* [`Overwrite<T, U>`](#overwritet-u)
* [`Assign<T, U>`](#assignt-u)
* [`ValuesType<T>`](#valuestypet)

## Special operators

Expand Down Expand Up @@ -586,6 +587,34 @@ type ExtendedProps = Assign<Props, NewProps>;

[⇧ back to top](#table-of-contents)

### `ValuesType<T>`

Get the union type of all the values in an object, tuple, array or array-like type `T`.

**Usage:**

```ts
import { ValuesType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string | number | boolean
type PropsValues = $ValuesType<Props>;

type NumberArray = number[];
// Expect: number
type NumberItems = $ValuesType<NumberArray>;

type ReadonlyNumberTuple = readonly [1, 2];
// Expect: 1 | 2
type AnotherNumberUnion = $ValuesType<NumberTuple>;

type BinaryArray = Uint8Array;
// Expect: number
type BinaryItems = $ValuesType<BinaryArray>;
```

[⇧ back to top](#table-of-contents)

### `Partial<T>`

Make all properties of object type optional
Expand Down
18 changes: 18 additions & 0 deletions src/__snapshots__/mapped-types.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,22 @@ exports[`SymmetricDifference testType<SymmetricDifference<'1' | '2' | '3', '2' |
exports[`Unionize testType<Unionize<Props>>() 1`] = `"{ name: string; } | { age: number; } | { visible: boolean; }"`;
exports[`ValuesType testType<ValuesType<[1, 2]>>() 1`] = `"1 | 2"`;
exports[`ValuesType testType<ValuesType<Props>>() 1`] = `"string | number | boolean"`;
exports[`ValuesType testType<ValuesType<ReadonlyArray<string>>>() 1`] = `"string"`;
exports[`ValuesType testType<ValuesType<Uint8Array>>() 1`] = `"number"`;
exports[`ValuesType testType<ValuesType<Uint16Array>>() 1`] = `"number"`;
exports[`ValuesType testType<ValuesType<Uint32Array>>() 1`] = `"number"`;
exports[`ValuesType testType<ValuesType<number[]>>() 1`] = `"number"`;
exports[`ValuesType testType<ValuesType<readonly [1, 2]>>() 1`] = `"1 | 2"`;
exports[`ValuesType testType<ValuesType<readonly symbol[]>>() 1`] = `"symbol"`;
exports[`WritableKeys testType<WritableKeys<ReadWriteProps>>() 1`] = `"\\"b\\""`;
18 changes: 0 additions & 18 deletions src/__snapshots__/utility-types.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,6 @@ exports[`$Shape testType<$Shape<Props>>() 1`] = `"Partial<Props>"`;
exports[`$Values testType<$Values<Props>>() 1`] = `"string | number | boolean"`;
exports[`$ValuesType testType<$ValuesType<Props>>() 1`] = `"string | number | boolean"`;
exports[`$ValuesType testType<$ValuesType<number[]>>() 1`] = `"number"`;
exports[`$ValuesType testType<$ValuesType<ReadonlyArray<string>>>() 1`] = `"string"`;
exports[`$ValuesType testType<$ValuesType<readonly symbol[]>>() 1`] = `"symbol"`;
exports[`$ValuesType testType<$ValuesType<[1, 2]>>() 1`] = `"1 | 2"`;
exports[`$ValuesType testType<$ValuesType<readonly [1, 2]>>() 1`] = `"1 | 2"`;
exports[`$ValuesType testType<$ValuesType<Uint8Array>>() 1`] = `"number"`;
exports[`$ValuesType testType<$ValuesType<Uint16Array>>() 1`] = `"number"`;
exports[`$ValuesType testType<$ValuesType<Uint32Array>>() 1`] = `"number"`;
exports[`Class testType<Class<Foo>>() 1`] = `"Class<Foo>"`;
exports[`mixed testType<mixed>() 1`] = `"unknown"`;
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export {
$ReadOnly,
$Shape,
$Values,
$ValuesType,
Class,
} from './utility-types';

Expand Down Expand Up @@ -49,6 +48,7 @@ export {
Subtract,
SymmetricDifference,
Unionize,
ValuesType,
WritableKeys,
} from './mapped-types';

Expand Down
26 changes: 26 additions & 0 deletions src/mapped-types.spec.snap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
PickByValueExact,
OmitByValueExact,
Optional,
ValuesType,
} from './mapped-types';

/**
Expand Down Expand Up @@ -501,3 +502,28 @@ type RequiredOptionalProps = {
// @dts-jest:pass:snap -> Optional<Props, "age" | "visible">
testType<Optional<Props, 'age' | 'visible'>>({ name: 'Yolo', age: 99 });
}

// @dts-jest:group ValuesType
{
// @dts-jest:pass:snap -> string | number | boolean
testType<ValuesType<Props>>();

// @dts-jest:pass:snap -> number
testType<ValuesType<number[]>>();
// @dts-jest:pass:snap -> symbol
testType<ValuesType<readonly symbol[]>>();
// @dts-jest:pass:snap -> string
testType<ValuesType<ReadonlyArray<string>>>();

// @dts-jest:pass:snap -> 1 | 2
testType<ValuesType<[1, 2]>>();
// @dts-jest:pass:snap -> 1 | 2
testType<ValuesType<readonly [1, 2]>>();

// @dts-jest:pass:snap -> number
testType<ValuesType<Uint8Array>>();
// @dts-jest:pass:snap -> number
testType<ValuesType<Uint16Array>>();
// @dts-jest:pass:snap -> number
testType<ValuesType<Uint32Array>>();
}
26 changes: 26 additions & 0 deletions src/mapped-types.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
PickByValueExact,
OmitByValueExact,
Optional,
ValuesType,
} from './mapped-types';

/**
Expand Down Expand Up @@ -501,3 +502,28 @@ type RequiredOptionalProps = {
// @dts-jest:pass:snap
testType<Optional<Props, 'age' | 'visible'>>({ name: 'Yolo', age: 99 });
}

// @dts-jest:group ValuesType
{
// @dts-jest:pass:snap
testType<ValuesType<Props>>();

// @dts-jest:pass:snap
testType<ValuesType<number[]>>();
// @dts-jest:pass:snap
testType<ValuesType<readonly symbol[]>>();
// @dts-jest:pass:snap
testType<ValuesType<ReadonlyArray<string>>>();

// @dts-jest:pass:snap
testType<ValuesType<[1, 2]>>();
// @dts-jest:pass:snap
testType<ValuesType<readonly [1, 2]>>();

// @dts-jest:pass:snap
testType<ValuesType<Uint8Array>>();
// @dts-jest:pass:snap
testType<ValuesType<Uint16Array>>();
// @dts-jest:pass:snap
testType<ValuesType<Uint32Array>>();
}
38 changes: 38 additions & 0 deletions src/mapped-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,3 +576,41 @@ export type Optional<T extends object, K extends keyof T = keyof T> = Omit<
K
> &
Partial<Pick<T, K>>;

/**
* $ValuesType
* @desc get the union type of all the values in an object, array or array-like type `T`
* @example
* type Props = { name: string; age: number; visible: boolean };
* // Expect: string | number | boolean
* type PropsValues = $ValuesType<Props>;
*
* type NumberArray = number[];
* // Expect: number
* type NumberItems = $ValuesType<NumberArray>;
*
* type ReadonlySymbolArray = readonly symbol[];
* // Expect: symbol
* type SymbolItems = $ValuesType<ReadonlySymbolArray>;
*
* type NumberTuple = [1, 2];
* // Expect: 1 | 2
* type NumberUnion = $ValuesType<NumberTuple>;
*
* type ReadonlyNumberTuple = readonly [1, 2];
* // Expect: 1 | 2
* type AnotherNumberUnion = $ValuesType<NumberTuple>;
*
* type BinaryArray = Uint8Array;
* // Expect: number
* type BinaryItems = $ValuesType<BinaryArray>;
*/
export type ValuesType<
T extends ReadonlyArray<any> | ArrayLike<any> | Record<any, any>
> = T extends ReadonlyArray<any>
? T[number]
: T extends ArrayLike<any>
? T[number]
: T extends object
? T[keyof T]
: never;
26 changes: 0 additions & 26 deletions src/utility-types.spec.snap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
$Call,
$Keys,
$Values,
$ValuesType,
$ReadOnly,
$Diff,
$PropertyType,
Expand Down Expand Up @@ -39,31 +38,6 @@ it('$Values', () => {
testType<$Values<Props>>();
});

// @dts-jest:group $ValuesType
it('$ValuesType', () => {
// @dts-jest:pass:snap -> string | number | boolean
testType<$ValuesType<Props>>();

// @dts-jest:pass:snap -> number
testType<$ValuesType<number[]>>();
// @dts-jest:pass:snap -> symbol
testType<$ValuesType<readonly symbol[]>>();
// @dts-jest:pass:snap -> string
testType<$ValuesType<ReadonlyArray<string>>>();

// @dts-jest:pass:snap -> 1 | 2
testType<$ValuesType<[1, 2]>>();
// @dts-jest:pass:snap -> 1 | 2
testType<$ValuesType<readonly [1, 2]>>();

// @dts-jest:pass:snap -> number
testType<$ValuesType<Uint8Array>>();
// @dts-jest:pass:snap -> number
testType<$ValuesType<Uint16Array>>();
// @dts-jest:pass:snap -> number
testType<$ValuesType<Uint32Array>>();
});

// @dts-jest:group $ReadOnly
it('$ReadOnly', () => {
// @dts-jest:pass:snap -> _DeepReadonlyObject<Props>
Expand Down
26 changes: 0 additions & 26 deletions src/utility-types.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
$Call,
$Keys,
$Values,
$ValuesType,
$ReadOnly,
$Diff,
$PropertyType,
Expand Down Expand Up @@ -39,31 +38,6 @@ it('$Values', () => {
testType<$Values<Props>>();
});

// @dts-jest:group $ValuesType
it('$ValuesType', () => {
// @dts-jest:pass:snap
testType<$ValuesType<Props>>();

// @dts-jest:pass:snap
testType<$ValuesType<number[]>>();
// @dts-jest:pass:snap
testType<$ValuesType<readonly symbol[]>>();
// @dts-jest:pass:snap
testType<$ValuesType<ReadonlyArray<string>>>();

// @dts-jest:pass:snap
testType<$ValuesType<[1, 2]>>();
// @dts-jest:pass:snap
testType<$ValuesType<readonly [1, 2]>>();

// @dts-jest:pass:snap
testType<$ValuesType<Uint8Array>>();
// @dts-jest:pass:snap
testType<$ValuesType<Uint16Array>>();
// @dts-jest:pass:snap
testType<$ValuesType<Uint32Array>>();
});

// @dts-jest:group $ReadOnly
it('$ReadOnly', () => {
// @dts-jest:pass:snap
Expand Down
19 changes: 0 additions & 19 deletions src/utility-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,6 @@ export type $Keys<T extends object> = keyof T;
*/
export type $Values<T extends object> = T[keyof T];

/**
* $ValuesType
* @desc get the union type of all the values in an object, array or array-like type `T`
* @example
* type Props = { name: string; age: number; visible: boolean };
*
* // Expect: string | number | boolean
* type PropsValues = $ValuesType<Props>;
*/
export type $ValuesType<
T extends ReadonlyArray<any> | ArrayLike<any> | Record<any, any>
> = T extends ReadonlyArray<any>
? T[number]
: T extends ArrayLike<any>
? T[number]
: T extends object
? T[keyof T]
: never;

/**
* $ReadOnly
* @desc get the read-only version of a given object type `T` (it works on nested data structure)
Expand Down

0 comments on commit 426355a

Please sign in to comment.