1 | /**
|
2 | 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.
|
3 |
|
4 | @example
|
5 | ```
|
6 | import type {Simplify} from 'type-fest';
|
7 |
|
8 | type PositionProps = {
|
9 | top: number;
|
10 | left: number;
|
11 | };
|
12 |
|
13 | type SizeProps = {
|
14 | width: number;
|
15 | height: number;
|
16 | };
|
17 |
|
18 | // In your editor, hovering over `Props` will show a flattened object with all the properties.
|
19 | type Props = Simplify<PositionProps & SizeProps>;
|
20 | ```
|
21 |
|
22 | Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record<string, unknown>`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface.
|
23 |
|
24 | If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify<SomeInterface> = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify<SomeInterface>` if you can't re-declare the `value`.
|
25 |
|
26 | @example
|
27 | ```
|
28 | import type {Simplify} from 'type-fest';
|
29 |
|
30 | interface SomeInterface {
|
31 | foo: number;
|
32 | bar?: string;
|
33 | baz: number | undefined;
|
34 | }
|
35 |
|
36 | type SomeType = {
|
37 | foo: number;
|
38 | bar?: string;
|
39 | baz: number | undefined;
|
40 | };
|
41 |
|
42 | const literal = {foo: 123, bar: 'hello', baz: 456};
|
43 | const someType: SomeType = literal;
|
44 | const someInterface: SomeInterface = literal;
|
45 |
|
46 | function fn(object: Record<string, unknown>): void {}
|
47 |
|
48 | fn(literal); // Good: literal object type is sealed
|
49 | fn(someType); // Good: type is sealed
|
50 | fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
|
51 | fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
|
52 | ```
|
53 |
|
54 | @link https://github.com/microsoft/TypeScript/issues/15300
|
55 | @see SimplifyDeep
|
56 | @category Object
|
57 | */
|
58 | export type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
|