UNPKG

@appello/common

Version:

Common package with many useful features for web and mobile development

1,469 lines (1,042 loc) 34 kB
# Common frontend library of components for web and mobile environmental ## How to use it Install package from npm: #### `npm i @appello/common` Import modules you need in your code: #### `import { useInterval, isNill } from '@appello/common';` ## Development guide ### For developers Each new functionality must be added to the folder and exported from the root! This is necessary to simplify the import of the necessary functionality: #### `import { useInterval, isFunction, ... } from '@appello/common';` If you need to create a new module, remember to add index.ts with exports. ## Hooks ### useCodeTimer #### `import { useCodeTimer } from '@appello/common';` Ready-made hook for setting a timer when sending SMS again. #### API: ```tsx import { useCodeTimer } from "@appello/common"; const Component = () => { const { seconds, inProgress, sendCode } = useCodeTimer(); return ( <div> ... { inProgress && ( <span>{seconds}</span> ) } <button type="button" onClick={sendCode} /> ... </div> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------------:|:------------------------------------:|:--------:|:-------:| | defaultSeconds | Countdown time in seconds. Optional. | `number` | 59 | #### Return: | Property | Description | Type | |:----------:|:--------------------------------------:|:---------:| | seconds | Amount of time in seconds. | `number` | | inProgress | Syntactic sugar. Is the timer running? | `boolean` | | sendCode | Method that starts the timer. | `void` | --- ### useCombinedRef #### `import { useCombinedRef } from '@appello/common';` Hook for combining refs. #### API: ```tsx import { useCombinedRef } from '@appello/common'; const Component = () => { const firstRef = useRef<number>(0); const secondRef = useRef<number>(0); const combinedRef = useCombinedRef(firstRef, secondRef); combinedRef(5); } ``` #### Params: | Property | Description | Type | Default | |:----------:|:-------------:|-------|-------------------| | listOfRefs | List of refs. | `Ref` | `One of required` | #### Return: | Property | Description | Type | |:-----------:|:-------------:|:-----:| | combinedRef | Combined ref. | `Ref` | --- ### useStep #### `import { useStep } from '@appello/common';` React state hook that tracks a numeric value. #### API: ```tsx import { useStep } from '@appello/common'; const Component = () => { const { count, setCount, increment, decrement, reset } = useStep(0) return ( <div> <p>Count is {count}</p> <button onClick={increment}>Increment</button> <button onClick={decrement}>Decrement</button> <button onClick={reset}>Reset</button> <button onClick={() => setCount((x) => x * 2)}>Multiply by 2</button> </div> ) } ``` #### Params: | Property | Description | Type | Default | |:------------:|:----------------------------------:|----------|---------| | initialValue | The initial value for the counter. | `number` | `0` | #### Return: | Property | Description | Type | |:---------:|:----------------:|:-------------------------:| | count | Current count. | `number` | | increment | Increment count. | `() => void` | | decrement | Decrement count. | `() => void` | | reset | Reset count. | `() => void` | | setCount | Set count. | `(count: number) => void` | --- ### useDebounceCallback #### `import { useDebounceCallback } from '@appello/common';` A hook that deal with the debounced function. #### API: ```tsx import { useDebounceCallback } from '@appello/common'; const Component = () => { const [value, setValue] = useState(0); const { debounce } = useDebounceCallback( () => { setValue(value + 1); }, ); return ( <button type="button" onClick={debounce}> Click </button> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:----------------------------------------------------------:|:-----------------:|:----------:| | fn | Callback for the debounce. | `AnyFuction` | `Required` | | options | [Lodash options](https://lodash.com/docs/4.17.15#debounce) | `DebounceOptions` | `Optional` | #### `DebounceOptions`: ```typescript export interface DebounceOptions { wait?: number; leading?: boolean; trailing?: boolean; maxWait?: number; } ``` #### Return: | Property | Description | Type | |:--------:|:------------------------------------------------------:|:------------:| | debounce | Invoke and pass parameters to fn. | `AnyFuction` | | cancel | Cancel the invocation of currently debounced function. | `() => void` | | flush | Immediately invoke currently debounced function. | `() => void` | --- ### useDebounceEffect #### `import { useDebounceEffect } from '@appello/common';` An effect with debouncing #### API: ```tsx import { useDebounceEffect } from '@appello/common'; const Component = () => { const [value, setValue] = useState('hello'); const [records, setRecords] = useState<string[]>([]); useDebounceEffect( () => { setRecords((val) => [...val, value]); }, [value], ); return ( <> <input value={value} onChange={(e) => setValue(e.target.value)} placeholder="Write text" /> <ul> {records.map((record, index) => ( <li key={index}>{record}</li> ))} </ul> </> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:-----------------------------------------------------------------------------:|:-----------------:|:-----------:| | effect | The effect callback. | `EffectCallback` | `Required` | | deps | The dependencies list. | `DependencyList` | `undefined` | | options | Config for the debounce behaviors. See the Options section below for details. | `DebounceOptions` | `undefined` | #### `DebounceOptions`: ```typescript export interface DebounceOptions { wait?: number; leading?: boolean; trailing?: boolean; maxWait?: number; } ``` --- ### useDefault #### `import { useDefault } from '@appello/common';` React state hook that returns the default value when state is null or undefined. #### API: ```tsx import { useDefault } from '@appello/common'; const Component = () => { const [user, setUser] = useDefault({ name: 'Mathers' }, { name: 'Marshall' }); return ( <div> <div>User: {user.name}</div> <input onChange={e => setUser({ name: e.target.value })} /> <button onClick={() => setUser(null)}>Set to null</button> </div> ) }; ``` #### Params: | Property | Description | Type | Default | |:------------:|:--------------:|-------|------------| | defaultValue | Default value. | `any` | `Required` | | initialValue | Initial value. | `any` | `Required` | #### Return: | Property | Description | Type | |:---------:|:--------------------:|:--------------------------------------:| | state | State and set state. | `[any, Dispatch<SetStateAction<any>>]` | --- ### useFirstMountState #### `import { useFirstMountState } from '@appello/common';` A hook that returns the first rendering #### API: ```tsx import { useFirstMountState } from '@appello/common'; const Component = () => { const isFirstMount = useFirstMountState(); return ( <div> {isFirstMount} </div> ) }; ``` #### Return: | Property | Description | Type | |:------------:|:-------------------:|:---------:| | isFirstMount | Return first render | `bollean` | --- ### useHookFormPersist #### `import { useHookFormPersist } from '@appello/common';` A hook for save temporary data from React hook form inside storage (LocalStorage / SessionStorage / AsyncStorage). #### API: ```tsx import { useHookFormPersist } from "@appello/common"; import { Controller } from 'react-hook-form'; import AsyncStorage from '@react-native-async-storage/async-storage'; type FormType = { name: string; email: string; } const Component = () => { const { syncFromStorage, syncToStorage } = useHookFormPersist<FormType>({ key: 'StorageKey', storage: AsyncStorage, }); const { control, submit, watch, formState: { defaultValues }, } = useForm<FormType>({ defaultValues: () => { // Sync data form storage (you can select sync-policy) return syncFromStorage({ defaultValues: { name: '', email: '' }, }); }, }) // Sync to storage syncToStorage(watch()); return ( <div> <Controller control={control} name="name" render={({ field: { value, onChange } }) => ( <input type="text" value={value} onChange={onChange} /> )} /> </div> ); }; ``` #### Params: | Property | Description | Type | Default | |:-------------:|:------------------------------------------------:|:----------:|:----------:| | key | Key for storage | `string` | `Required` | | storage | Object Storage | `Storage` | `Required` | | excludeFields | Fields that should not be saved and synchronized | `string[]` | `Optional` | | includeFields | fields that should be saved and synchronized | `string[]` | `Optional` | #### Return: | Property | Description | Type | |:---------------:|:-------------------------:|:---------------------------------------------------------------------------------------------------------------:| | syncFromStorage | Sync values from storage. | `({ defaultValues?: UseFormProps<FieldValues>['defaultValues']; syncPolicy?: CachePolicyLiteral; }) => Promise` | | syncToStorage | Sync values to storage. | `(watchedValues: FieldValues) => void` | | clear | Clear storage by key. | `() => void` | --- ### useInterval #### `import { useInterval } from '@appello/common';` A hook that allows you to call a callback function in a time interval #### API: ```tsx import { useInterval } from '@appello/common'; const Component = () => { const { start } = useInterval({ fn: () => { console.log('Hello') }, }); return ( <button type="button" onClick={start}> Start timer </button> ) }; ``` #### Params: | Property | Description | Type | Default | |:---------------:|:-----------------------------------------------------------------------:|:----------------:|:-----------:| | fn | Callback function, a function that will be called with a certain delay. | `EffectCallback` | `Required` | | delay | Delay time. | `number` | 1000 ms | | immediateStart | Starts immediately. | `bollean` | `undefined` | | immediateCallFn | Is it necessary to call a callback immediately before the timer starts. | `bollean` | `undefined` | | onStop | A callback that will be called after the timer stops. | `() => void` | `undefined` | #### Return: | Property | Description | Type | |:--------:|:------------------------------------------------:|:----------------------:| | start | Function for starting timer. | `() => void` | | stop | Function for stopping timer. | `() => void` | | setState | Method for change state of an interval manually. | `(v: bollean) => void` | --- ### useIsClient #### `import { useIsClient } from '@appello/common';` This hook can be useful in an SSR environment to wait until be in a browser to execution some functions. #### API: ```tsx import { useIsClient } from '@appello/common'; const Component = () => { const isClient = useIsClient() return <div>{isClient ? 'Client' : 'server'}</div> }; ``` #### Return: | Property | Description | Type | |:--------:|:----------------:|:---------:| | value | Value is boolean | `boolean` | --- ### useIsMounted #### `import { useIsMounted } from '@appello/common';` This hook can be useful for checking is mount component. #### API: ```tsx import { useIsMounted } from '@appello/common'; const Component = () => { const isMounted = useIsMounted() return <div>{isMounted() && 'Component is mount'}</div> }; ``` #### Return: | Property | Description | Type | |:--------:|:----------------:|:---------:| | value | Value is boolean | `boolean` | --- ### useLatest #### `import { useLatest } from '@appello/common';` A Hook that returns the latest value, effectively avoiding the closure problem. #### API: ```tsx import { useLatest } from "@appello/common"; const Component = () => { const [count, setCount] = useState(0); const latestCountRef = useLatest(count); useEffect(() => { const interval = setInterval(() => { setCount(latestCountRef.current + 1); }, 1000); return () => clearInterval(interval); }, []); return ( <> <p>count: {count}</p> </> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:----------------------------------------------------------:|:-----:|:----------:| | value | Function, ref or any type value for get last active value. | `any` | `Required` | #### Return: | Property | Description | Type | |:-----------:|:-------------:|:-----:| | resultValue | Latest value. | `any` | --- ### useManualUpdate #### `import { useManualUpdate } from '@appello/common';` A hook that can be used to manually update a component. #### API: ```tsx import { useManualUpdate } from '@appello/common'; const Component = () => { const update = useManualUpdate(); return ( <> <div>Time: {Date.now()}</div> <button type="button" onClick={update}> Update </button> </> ); }; ``` #### Return: | Property | Description | Type | |:--------:|:------------------------------:|:------------:| | update | Callback for update component. | `() => void` | --- ### useMemoCallback #### `import { useMemoCallback } from '@appello/common';` Hooks for persistent functions. In theory, useMemoizedFn can be used instead of useCallback. In some scenarios, we need to use useCallback to cache a function, but when the second parameter deps changes, the function will be regenerated, causing the function reference to change. #### API: ```tsx import { useMemoCallback } from '@appello/common'; const Component = () => { const [count, setCount] = useState(0); const memoCallback = useMemoCallback(() => { message.info(`Current count is ${count}`); }); return ( <> <p>count: {count}</p> <button type="button" onClick={() => setCount((v) => v + 1)} > Add Count </button> <button type="button" onClick={memoCallback}> Call </button> </> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:----------------------:|:-------------:|:----------:| | callback | Callback for memorize. | `AnyFunction` | `Required` | #### Return: | Property | Description | Type | |:--------:|:----------------------------------:|:-------------:| | callback | Function that require persistence. | `AnyFunction` | --- ### useMountEffect #### `import { useMountEffect } from '@appello/common';` A hook that executes a function after the component is mounted. #### API: ```tsx import { useMountEffect } from '@appello/common'; const Component = () => { useMountEffect(() => { console.log("Mount") }) return ( <span>component</span> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:------------------------------------------------------:|:-------------:|:----------:| | callback | Callback that is called when the component is mounted. | `AnyFunction` | `Required` | --- ### usePrevious #### `import { usePrevious } from '@appello/common';` A Hook to return to the previous state. #### API: ```tsx import { usePrevious } from '@appello/common'; const Component = () => { const [count, setCount] = useState(0); const previous = usePrevious(count); return ( <> <div>counter current value: {count}</div> <div>counter previous value: {previous}</div> <button type="button" onClick={() => setCount((c) => c + 1)}> increase </button> <button type="button" onClick={() => setCount((c) => c - 1)}> decrease </button> </> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:-----------------------------:|:-----:|:----------:| | value | Any value that will be saved. | `any` | `Required` | #### Return: | Property | Description | Type | |:--------:|:---------------------:|:-----:| | value | Any value that saved. | `any` | --- ### useQueryParamsBuilder #### `import { useQueryParamsBuilder } from '@appello/common';` A Hook for manager query params with debounced time. #### API: ```tsx import { useQueryParamsBuilder } from '@appello/common'; const Component = () => { const [getService, { data }] = useAnyRequest(); const { updateQueryParams } = useQueryParamsBuilder({ requestCb: params => getService(params), defaultParams: { categoryId, search: '', }, }); return ( <></> ); }; ``` #### Params: | Property | Description | Type | Default | |:-------------:|:----------------------------------------------------------:|:--------------------:|:----------:| | requestCb | Any request function | `() => Promise<any>` | `Required` | | defaultParams | Any object. | `AnyObject` | `Required` | | options | [Lodash options](https://lodash.com/docs/4.17.15#debounce) | `DebounceOptions` | `Optional` | #### Return: | Property | Description | Type | |:-----------------:|:-------------------------------------:|:----------------------------------------------------:| | loading | Loading promise. | `boolean` | | queryParams | Object with query params. | `AnyObject` | | updateQueryParams | Update query params with. | `(params: Partial<T>, withDebounce = false) => void` | | reset | Reset query params object. | `() => void` | --- ### useSelectOptions #### `import { useSelectOptions } from '@appello/common';` Converts dictionaries for picker to structure: ```ts [ { value: 1, label: 'Select 1' }, { value: 2, label: 'Select 2' } ] ``` #### API: ```tsx import { useSelectOptions } from '@appello/common'; const Component = () => { const convertedOptions = useSelectOptions([ { val: 1, text: 'Select 1', }, { val: 2, text: 'Select 2', }, ], { label: 'text', value: 'val', }) return ( <span>{JSON.stringify(convertedOptions)}</span> ); }; ``` #### Params: | Property | Description | Type | Default | |:----------:|:--------------------------------------:|:--------------------------------:|:----------:| | collection | Collection of objects to be converted. | `AnyObject[]` | `Required` | | object | Key Matching Object. | `{label: string, value: string}` | `Required` | #### Return: | Property | Description | Type | |:-------------:|:---------------------:|:----------------------------------:| | newCollection | Converted collection. | `{label: string, value: string}[]` | --- ### useStateObject #### `import { useStateObject } from '@appello/common';` Hook with state for working with objects. #### API: ```tsx import { useStateObject } from "@appello/common"; import { setState } from "jest-circus"; const Component = () => { const [state, setState] = useStateObject({ name: "Test", lastName: "Jest", age: 21 }); return ( <> <span>{JSON.stringify(state)}</span> <button type="button" onClick={() => { setState(prev => ({ age: prev.age + 25 })); }} > Update using callback </button> <button type="button" onClick={() => { setState({ name: "New", lastName: "Test" }); }} > Update using object </button> </> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:---------------:|:-----------:|:----------:| | object | Default object. | `AnyObject` | `Required` | #### Return: | Property | Description | Type | |:--------:|:------------------------------------------------------:|:--------------------------------------------------:| | state | Returns a stateful value, and a function to update it. | `[AnyObject, Dispatch<SetStateAction<AnyObject>>]` | --- ### useStep #### `import { useStep } from '@appello/common';` Custom hook that manages steps in a multistep process. #### API: ```tsx import { useStep } from "@appello/common"; const Component = () => { const { step, increment, decrement } = useStep(0); return ( <> <p>Current step: {step}</p> <p> <button type="button" onClick={increment}> Increment </button> <button type="button" onClick={decrement} style={{ margin: "0 8px" }}> Decrement </button> </p> </> ); }; ``` #### Params: | Property | Description | Type | Default | |:------------:|:--------------:|:---------:|:-------:| | initialValue | Initial value. | `boolean` | `0` | #### Return: | Property | Description | Type | |:---------:|:-----------------------------:|:----------------------------------:| | step | Current step. | `number` | | increment | Increase the step by one. | `() => void` | | decrement | Reduce the pitch by one. | `() => void` | | reset | Reset steps to default value. | `() => void` | | setStep | Set step manually. | `Dispatch<SetStateAction<number>>` | --- ### useSwitchValue #### `import { useSwitchValue } from '@appello/common';` A hook that toggle states. #### API: ```tsx import { useSwitchValue } from "@appello/common"; const Component = () => { const { value, on, off, toggle } = useSwitchValue(false); return ( <> <p>{`${value}`}</p> <p> <button type="button" onClick={on}> On </button> <button type="button" onClick={off} style={{ margin: "0 8px" }}> Off </button> <button type="button" onClick={toggle}> Toggle </button> </p> </> ); }; ``` #### Params: | Property | Description | Type | Default | |:------------:|:--------------:|:---------:|:----------:| | defaultValue | Default value. | `boolean` | `Required` | #### Return: | Property | Description | Type | |----------|:-------------------:|:-----------------------------------:| | value | Switching value. | `boolean` | | on | Set value `true`. | `() => void` | | off | Set value `false`. | `() => void` | | toggle | Toggle value. | `() => void` | | set | Set value manually. | `Dispatch<SetStateAction<boolean>>` | --- ### useUnmountEffect #### `import { useUnmountEffect } from '@appello/common';` A hook that executes the function right before the component is unmounted. #### API: ```tsx import { useUnmountEffect } from "@appello/common"; const Component = () => { useUnmountEffect(() => { console.log('Unmount'); }); return <p>Hello World!</p>; }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:--------------------------------------------------------:|:------------:|:----------:| | callback | Callback that is called when the component is unmounted. | `() => void` | `Required` | --- ### useUpdateEffect #### `import { useUpdateEffect } from '@appello/common';` A hook alike `useEffect` but skips running the effect for the first time. #### API: ```tsx import { useUpdateEffect } from "@appello/common"; const Component = () => { const [count, setCount] = useState(0); const [updateEffectCount, setUpdateEffectCount] = useState(0); useUpdateEffect(() => { setUpdateEffectCount((c) => c + 1); }, [count]); return ( <div> <p>updateEffectCount: {updateEffectCount}</p> <button type="button" onClick={() => setCount((c) => c + 1)}> reRender </button> </div> ); }; ``` #### Params: | Property | Description | Type | Default | |:--------:|:------------------------------------------------------:|:----------------:|:-----------:| | effect | Callback that is called when the component is updated. | `() => void` | `Required` | | deps | The dependencies list. | `DependencyList` | `undefined` | --- ## Types: ### ElementType #### `import { ElementType } from '@appello/common';` The type returns any HTML element. #### Usage: ```tsx import { ElementType } from '@appello/common'; const target: ElementType = document.getElementById('#user'); ``` --- ### Nullable #### `import { Nullable } from '@appello/common';` The type returns either null or generic. #### Usage: ```tsx import { Nullable } from '@appello/common'; type User = { name: string; lastName: string; } const user: Nullable<User> = null; ``` --- ### Nillable #### `import { Nillable } from '@appello/common';` The type returns either null or undefined or generic. #### Usage: ```tsx import { Nillable } from '@appello/common'; type User = { name: string; lastName: string; } const user: Nillable<User> = null; const user2: Nillable<User> = undefined; ``` --- ### NotNullable #### `import { NotNullable } from '@appello/common';` Prohibits the type from being null, only generic. #### Usage: ```tsx import { NotNullable } from '@appello/common'; type User = { name: string; lastName: string; } const user: NotNullable<User> = { name: string, lastName: string, }; ``` --- ### NotNillable #### `import { NotNillable } from '@appello/common';` Prohibits the type from being null or undefined, only generic. #### Usage: ```tsx import { NotNillable } from '@appello/common'; type User = { name: string; lastName: string; } const user: NotNillable<User> = { name: string, lastName: string, }; ``` --- ### Unidentifiable #### `import { Unidentifiable } from '@appello/common';` The type returns either undefined or generic. #### Usage: ```tsx import { Unidentifiable } from '@appello/common'; type User = { name: string; lastName: string; } const user: Unidentifiable<User> = undefined; ``` --- ### Negative #### `import { Negative } from '@appello/common';` Entity can match undefined, null, false or generic. #### Usage: ```tsx import { Negative } from '@appello/common'; type User = { name: string; lastName: string; } const user: Negative<User> = undefined; const user1: Negative<User> = null; const user2: Negative<User> = false; const user3: Negative<User> = { name: string, lastName: string, }; ``` --- ### ValueOf #### `import { ValueOf } from '@appello/common';` Get values from any type. #### Usage: ```tsx import { ValueOf } from '@appello/common'; type User = { name: string; age: number; } const userName: ValueOf<User> = 'User'; const userAge: ValueOf<User> = 22; ``` --- ### AnyObject #### `import { AnyObject } from '@appello/common';` Common type for objects if we don't know an object type. #### Usage: ```tsx import { AnyObject } from '@appello/common'; const user: AnyObject = { name: 'User', age: 123, lastName: 'User 2', } ``` --- ### AnyPromise #### `import { AnyPromise } from '@appello/common';` Can be used for any promises. #### Usage: ```tsx import { AnyPromise } from '@appello/common'; const getUser: AnyPromise = Promise.resolve('User'); ``` --- ### PartialRecord #### `import { PartialRecord } from '@appello/common';` It can be used to create a type that represents a partial object. #### Usage: ```tsx import { PartialRecord } from '@appello/common'; type Keys = 'name' | 'age' | 'address'; type Value = string; type PartialPerson = PartialRecord<Keys, Value>; const person1: PartialPerson = {}; const person2: PartialPerson = { name: 'John' }; const person3: PartialPerson = { age: '30', address: '123 Main St' }; ``` --- ### PartialDeep #### `import { PartialDeep } from '@appello/common';` This type allows you to create partial versions of nested objects. #### Usage: ```tsx import { PartialDeep } from '@appello/common'; interface User { name: string; address: { city: string; country: string; }; } const user: PartialDeep<User> = { address: { city: 'New York' } }; ``` --- ### ResponseErrors #### `import { ResponseErrors } from '@appello/common';` Type for object where the key is a string, and the value is also a string. #### Usage: ```tsx import { ResponseErrors } from '@appello/common'; const error: ResponseErrors = { text: 'Something was wrong', }; ``` --- ### UnknownFunction #### `import { UnknownFunction } from '@appello/common';` Type for an unknown function with unknown parameters. #### Usage: ```tsx import { UnknownFunction } from '@appello/common'; const unknownFunction: UnknownFunction = props => { console.log(props); }; ``` --- ### AnyFunction #### `import { AnyFunction } from '@appello/common';` Type for any function (best to avoid this). #### Usage: ```tsx import { AnyFunction } from '@appello/common'; const anyFunction: AnyFunction = props => { console.log(props); }; ``` --- ### PromiseType #### `import { PromiseType } from '@appello/common';` This type extracts the value type from the Promise. #### Usage: ```tsx import { PromiseType } from '@appello/common'; type User = { id: number; name: string } async function fetchUser(): Promise<> { return { id: 1, name: 'John' }; } type UserType = PromiseType<ReturnType<typeof fetchUser>>; ``` --- ### RequiredKeys / OptionalKeys #### `import { RequiredKeys, OptionalKeys } from '@appello/common';` This type separates mandatory and optional object keys. #### Usage: ```tsx import { RequiredKeys, OptionalKeys } from '@appello/common'; type User = { id: number; name?: string; email?: string; } type UserRequiredKeys = RequiredKeys<User>; // "id" type UserOptionalKeys = OptionalKeys<User>; // "name" | "email" ``` --- ### Merge #### `import { Merge } from '@appello/common';` This type combines two types, where properties of first type override properties of a second type. #### Usage: ```tsx import { Merge } from '@appello/common'; type User = { name: string; age: number; } type Admin = { isAdmin: boolean; } type UserAdmin = Merge<A, B>; const user1: UserAdmin = { name: 'hello', age: 12, isAdmin: true, }; ``` --- ### AsyncReturnType #### `import { AsyncReturnType } from '@appello/common';` This type retrieves the return type of asynchronous function. #### Usage: ```tsx import { AsyncReturnType } from '@appello/common'; async function getUser() { return { id: 1, name: 'John' }; } type UserType = AsyncReturnType<typeof getUser>; ``` --- ### FirstArgument #### `import { FirstArgument } from '@appello/common';` This type retrieves the type of the function's first argument. #### Usage: ```tsx import { FirstArgument } from '@appello/common'; function logUser(user: { id: number; name: string }) { console.log(user); } type UserArg = FirstArgument<typeof logUser>; ``` ---