UNPKG

8.13 kBTypeScriptView Raw
1import { ComponentType, ComponentProps } from 'react';
2import { Args, ComponentAnnotations, AnnotatedStoryFn, ArgsStoryFn, ArgsFromMeta, StoryAnnotations, StrictArgs, DecoratorFunction, LoaderFunction, StoryContext as StoryContext$1, ProjectAnnotations } from 'storybook/internal/types';
3import { R as ReactRenderer } from './types-a5624094.js';
4
5declare global {
6 interface SymbolConstructor {
7 readonly observable: symbol;
8 }
9}
10
11/**
12Returns a boolean for whether the two given types are equal.
13
14@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650
15@link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796
16*/
17type IsEqual<T, U> =
18 (<G>() => G extends T ? 1 : 2) extends
19 (<G>() => G extends U ? 1 : 2)
20 ? true
21 : false;
22
23/**
24Filter out keys from an object.
25
26Returns `never` if `Exclude` is strictly equal to `Key`.
27Returns `never` if `Key` extends `Exclude`.
28Returns `Key` otherwise.
29
30@example
31```
32type Filtered = Filter<'foo', 'foo'>;
33//=> never
34```
35
36@example
37```
38type Filtered = Filter<'bar', string>;
39//=> never
40```
41
42@example
43```
44type Filtered = Filter<'bar', 'foo'>;
45//=> 'bar'
46```
47
48@see {Except}
49*/
50type Filter<KeyType, ExcludeType> = IsEqual<KeyType, ExcludeType> extends true ? never : (KeyType extends ExcludeType ? never : KeyType);
51
52/**
53Create a type from an object type without certain keys.
54
55This 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.
56
57This type was proposed to the TypeScript team, which declined it, saying they prefer that libraries implement stricter versions of the built-in types ([microsoft/TypeScript#30825](https://github.com/microsoft/TypeScript/issues/30825#issuecomment-523668235)).
58
59@example
60```
61import type {Except} from 'type-fest';
62
63type Foo = {
64 a: number;
65 b: string;
66 c: boolean;
67};
68
69type FooWithoutA = Except<Foo, 'a' | 'c'>;
70//=> {b: string};
71```
72
73@category Object
74*/
75type Except<ObjectType, KeysType extends keyof ObjectType> = {
76 [KeyType in keyof ObjectType as Filter<KeyType, KeysType>]: ObjectType[KeyType];
77};
78
79/**
80@see Simplify
81*/
82interface SimplifyOptions {
83 /**
84 Do the simplification recursively.
85
86 @default false
87 */
88 deep?: boolean;
89}
90
91// Flatten a type without worrying about the result.
92type Flatten<
93 AnyType,
94 Options extends SimplifyOptions = {},
95> = Options['deep'] extends true
96 ? {[KeyType in keyof AnyType]: Simplify<AnyType[KeyType], Options>}
97 : {[KeyType in keyof AnyType]: AnyType[KeyType]};
98
99/**
100Useful 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.
101
102@example
103```
104import type {Simplify} from 'type-fest';
105
106type PositionProps = {
107 top: number;
108 left: number;
109};
110
111type SizeProps = {
112 width: number;
113 height: number;
114};
115
116// In your editor, hovering over `Props` will show a flattened object with all the properties.
117type Props = Simplify<PositionProps & SizeProps>;
118```
119
120Sometimes 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.
121
122If 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`.
123
124@example
125```
126import type {Simplify} from 'type-fest';
127
128interface SomeInterface {
129 foo: number;
130 bar?: string;
131 baz: number | undefined;
132}
133
134type SomeType = {
135 foo: number;
136 bar?: string;
137 baz: number | undefined;
138};
139
140const literal = {foo: 123, bar: 'hello', baz: 456};
141const someType: SomeType = literal;
142const someInterface: SomeInterface = literal;
143
144function fn(object: Record<string, unknown>): void {}
145
146fn(literal); // Good: literal object type is sealed
147fn(someType); // Good: type is sealed
148fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
149fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
150```
151
152@link https://github.com/microsoft/TypeScript/issues/15300
153
154@category Object
155*/
156type Simplify<
157 AnyType,
158 Options extends SimplifyOptions = {},
159> = Flatten<AnyType> extends AnyType
160 ? Flatten<AnyType, Options>
161 : AnyType;
162
163/**
164Create a type that makes the given keys optional. The remaining keys are kept as is. The sister of the `SetRequired` type.
165
166Use-case: You want to define a single model where the only thing that changes is whether or not some of the keys are optional.
167
168@example
169```
170import type {SetOptional} from 'type-fest';
171
172type Foo = {
173 a: number;
174 b?: string;
175 c: boolean;
176}
177
178type SomeOptional = SetOptional<Foo, 'b' | 'c'>;
179// type SomeOptional = {
180// a: number;
181// b?: string; // Was already optional and still is.
182// c?: boolean; // Is now optional.
183// }
184```
185
186@category Object
187*/
188type SetOptional<BaseType, Keys extends keyof BaseType> =
189 Simplify<
190 // Pick just the keys that are readonly from the base type.
191 Except<BaseType, Keys> &
192 // Pick the keys that should be mutable from the base type and make them mutable.
193 Partial<Pick<BaseType, Keys>>
194 >;
195
196/**
197 * Metadata to configure the stories for a component.
198 *
199 * @see [Default export](https://storybook.js.org/docs/api/csf#default-export)
200 */
201type Meta<TCmpOrArgs = Args> = [TCmpOrArgs] extends [ComponentType<any>] ? ComponentAnnotations<ReactRenderer, ComponentProps<TCmpOrArgs>> : ComponentAnnotations<ReactRenderer, TCmpOrArgs>;
202/**
203 * Story function that represents a CSFv2 component example.
204 *
205 * @see [Named Story exports](https://storybook.js.org/docs/api/csf#named-story-exports)
206 */
207type StoryFn<TCmpOrArgs = Args> = [TCmpOrArgs] extends [ComponentType<any>] ? AnnotatedStoryFn<ReactRenderer, ComponentProps<TCmpOrArgs>> : AnnotatedStoryFn<ReactRenderer, TCmpOrArgs>;
208/**
209 * Story object that represents a CSFv3 component example.
210 *
211 * @see [Named Story exports](https://storybook.js.org/docs/api/csf#named-story-exports)
212 */
213type StoryObj<TMetaOrCmpOrArgs = Args> = [TMetaOrCmpOrArgs] extends [
214 {
215 render?: ArgsStoryFn<ReactRenderer, any>;
216 component?: infer Component;
217 args?: infer DefaultArgs;
218 }
219] ? Simplify<(Component extends ComponentType<any> ? ComponentProps<Component> : unknown) & ArgsFromMeta<ReactRenderer, TMetaOrCmpOrArgs>> extends infer TArgs ? StoryAnnotations<ReactRenderer, AddMocks<TArgs, DefaultArgs>, SetOptional<TArgs, keyof TArgs & keyof DefaultArgs>> : never : TMetaOrCmpOrArgs extends ComponentType<any> ? StoryAnnotations<ReactRenderer, ComponentProps<TMetaOrCmpOrArgs>> : StoryAnnotations<ReactRenderer, TMetaOrCmpOrArgs>;
220type AddMocks<TArgs, DefaultArgs> = Simplify<{
221 [T in keyof TArgs]: T extends keyof DefaultArgs ? DefaultArgs[T] extends (...args: any) => any & {
222 mock: {};
223 } ? DefaultArgs[T] : TArgs[T] : TArgs[T];
224}>;
225type Decorator<TArgs = StrictArgs> = DecoratorFunction<ReactRenderer, TArgs>;
226type Loader<TArgs = StrictArgs> = LoaderFunction<ReactRenderer, TArgs>;
227type StoryContext<TArgs = StrictArgs> = StoryContext$1<ReactRenderer, TArgs>;
228type Preview = ProjectAnnotations<ReactRenderer>;
229
230export { Decorator as D, Loader as L, Meta as M, Preview as P, StoryFn as S, StoryObj as a, StoryContext as b };