Skip to content

Commit 5374588

Browse files
alvissindresorhus
andauthored
Add LiteralToPrimitiveDeep type (#584)
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
1 parent 2e49866 commit 5374588

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export type {Jsonify} from './source/jsonify';
5555
export type {Jsonifiable} from './source/jsonifiable';
5656
export type {Schema} from './source/schema';
5757
export type {LiteralToPrimitive} from './source/literal-to-primitive';
58+
export type {LiteralToPrimitiveDeep} from './source/literal-to-primitive-deep';
5859
export type {
5960
PositiveInfinity,
6061
NegativeInfinity,

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ Click the type names for complete docs.
157157
- [`ConditionalExcept`](source/conditional-except.d.ts) - Like `Omit` except it removes properties from a shape where the values extend the given `Condition` type.
158158
- [`UnionToIntersection`](source/union-to-intersection.d.ts) - Convert a union type to an intersection type.
159159
- [`LiteralToPrimitive`](source/literal-to-primitive.d.ts) - Convert a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) to the [primitive type](source/primitive.d.ts) it belongs to.
160+
- [`LiteralToPrimitiveDeep`](source/literal-to-primitive-deep.d.ts) - Like `LiteralToPrimitive` except it converts literal types inside an object or array deeply.
160161
- [`Stringified`](source/stringified.d.ts) - Create a type with the keys of the given type changed to `string` type.
161162
- [`IterableElement`](source/iterable-element.d.ts) - Get the element type of an `Iterable`/`AsyncIterable`. For example, an array or a generator.
162163
- [`Entry`](source/entry.d.ts) - Create a type that represents the type of an entry of a collection.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type {LiteralToPrimitive} from './literal-to-primitive';
2+
import type {OmitIndexSignature} from './omit-index-signature';
3+
4+
/**
5+
Like `LiteralToPrimitive` except it converts literal types inside an object or array deeply.
6+
7+
For example, given a constant object, it returns a new object type with the same keys but with all the values converted to primitives.
8+
9+
@see LiteralToPrimitive
10+
11+
Use-case: Deal with data that is imported from a JSON file.
12+
13+
@example
14+
```
15+
import type {LiteralToPrimitiveDeep, TsConfigJson} from 'type-fest';
16+
import tsconfig from 'path/to/tsconfig.json';
17+
18+
function doSomethingWithTSConfig(config: LiteralToPrimitiveDeep<TsConfigJson>) { ... }
19+
20+
// No casting is needed to pass the type check
21+
doSomethingWithTSConfig(tsconfig);
22+
23+
// If LiteralToPrimitiveDeep is not used, you need to cast the imported data like this:
24+
doSomethingWithTSConfig(tsconfig as TsConfigJson);
25+
```
26+
27+
@category Type
28+
@category Object
29+
*/
30+
export type LiteralToPrimitiveDeep<T> = T extends object
31+
? T extends Array<infer U>
32+
? Array<LiteralToPrimitiveDeep<U>>
33+
: {
34+
[K in keyof OmitIndexSignature<T>]: LiteralToPrimitiveDeep<T[K]>;
35+
}
36+
: LiteralToPrimitive<T>;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {expectType} from 'tsd';
2+
import type {IsEqual, LiteralToPrimitiveDeep} from '../index';
3+
4+
type LiteralObject = {
5+
a: string;
6+
b: number;
7+
c: boolean;
8+
d: {
9+
e: bigint;
10+
f: symbol;
11+
g: {
12+
h: string[];
13+
i: {
14+
j: boolean;
15+
k: {
16+
l: 1;
17+
m: 'hello';
18+
o: [1, 2, 3];
19+
p: ['a', 'b', 'c'];
20+
q: [1, 'a', true];
21+
};
22+
};
23+
};
24+
};
25+
};
26+
27+
type PrimitiveObject = {
28+
a: string;
29+
b: number;
30+
c: boolean;
31+
d: {
32+
e: bigint;
33+
f: symbol;
34+
g: {
35+
h: string[];
36+
i: {
37+
j: boolean;
38+
k: {
39+
l: number;
40+
m: string;
41+
o: number[];
42+
p: string[];
43+
q: Array<number | string | boolean>;
44+
};
45+
};
46+
};
47+
};
48+
};
49+
50+
const typeEqual: IsEqual<
51+
LiteralToPrimitiveDeep<LiteralObject>,
52+
PrimitiveObject
53+
> = true;
54+
expectType<true>(typeEqual);

0 commit comments

Comments
 (0)