{"id":15011790,"url":"https://github.com/hotell/rex-tils","last_synced_at":"2025-04-05T17:03:41.966Z","repository":{"id":143046326,"uuid":"144564630","full_name":"Hotell/rex-tils","owner":"Hotell","description":"Type safe utils for redux actions, epics, effects, react/preact default props, various type guards and TypeScript utils, React util components","archived":false,"fork":false,"pushed_at":"2019-12-31T15:25:23.000Z","size":513,"stargazers_count":254,"open_issues_count":5,"forks_count":9,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-05T17:03:26.569Z","etag":null,"topics":["angular","ngrx-effects","preact","react","redux","redux-observable","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hotell.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-13T10:29:17.000Z","updated_at":"2025-03-17T20:39:02.000Z","dependencies_parsed_at":"2023-06-12T12:15:22.866Z","dependency_job_id":null,"html_url":"https://github.com/Hotell/rex-tils","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hotell%2Frex-tils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hotell%2Frex-tils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hotell%2Frex-tils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hotell%2Frex-tils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hotell","download_url":"https://codeload.github.com/Hotell/rex-tils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369953,"owners_count":20927928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","ngrx-effects","preact","react","redux","redux-observable","typescript"],"created_at":"2024-09-24T19:41:42.757Z","updated_at":"2025-04-05T17:03:41.930Z","avatar_url":"https://github.com/Hotell.png","language":"TypeScript","funding_links":["https://paypal.me/martinhochel"],"categories":[],"sub_categories":[],"readme":"# rex-tils 🦖 ⚛ ️🖖\n\n\u003e Type safe utils for redux actions and various guard utils for React and Angular\n\n\u003e **WHY/WHAT? 👉** https://medium.com/@martin_hotell/improved-redux-type-safety-with-typescript-2-8-2c11a8062575\n\n\u003e **Enjoying/Using rex-tils ? 💪✅**\n\u003e\n\u003e \u003cdiv align=\"center\"\u003e\u003ca href=\"https://paypal.me/martinhochel\"\u003eBuy me a ☕️\u003cbr/\u003e\u003cimg src=\"https://img.shields.io/badge/Donate-PayPal-green.svg\" alt=\"donate\"\u003e\u003c/a\u003e\u003c/div\u003e\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/Hotell/rex-tils.svg)](https://greenkeeper.io/)\n\n[![Build Status](https://travis-ci.org/Hotell/rex-tils.svg?branch=master)](https://travis-ci.org/Hotell/rex-tils)\n[![NPM version](https://img.shields.io/npm/v/%40martin_hotell%2Frex-tils.svg)](https://www.npmjs.com/package/@martin_hotell/rex-tils)\n![Downloads](https://img.shields.io/npm/dm/@martin_hotell/rex-tils.svg)\n[![Standard Version](https://img.shields.io/badge/release-standard%20version-brightgreen.svg)](https://github.com/conventional-changelog/standard-version)\n[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\n## Installing\n\n```sh\nyarn add @martin_hotell/rex-tils\n# OR\nnpm install @martin_hotell/rex-tils\n```\n\n\u003e **Note:**\n\u003e\n\u003e 1.  This library supports only `TS \u003e= 3.1` ( because it uses [conditional types](http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#conditional-types) and [generic rest arguments](http://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-1.html#mapped-types-on-tuples-and-arrays) #dealWithIt )\n\u003e 2.  For leveraging Rx `ofType` operator within your Epics/Effects you need to install `rxjs\u003e= 6.x`\n\n## Getting started\n\nLet's demonstrate simple usage with old good Counter example:\n\n[![Edit counter-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/Hotell/rex-tils/tree/master/examples/counter)\n\n1.  Create Type-safe Redux Actions\n\n```tsx\n// actions.ts\nimport { ActionsUnion, createAction } from '@martin_hotell/rex-tils'\n\nexport const INCREMENT = 'INCREMENT'\nexport const DECREMENT = 'DECREMENT'\nexport const INCREMENT_IF_ODD = 'INCREMENT_IF_ODD'\n\nexport const Actions = {\n  increment: () =\u003e createAction(INCREMENT),\n  decrement: () =\u003e createAction(DECREMENT),\n  incrementIfOdd: () =\u003e createAction(INCREMENT_IF_ODD),\n}\n\n// we leverage TypeScript token merging, so our consumer can use `Actions` for both runtime and compile time types 💪\nexport type Actions = ActionsUnion\u003ctypeof Actions\u003e\n```\n\n2.  Use Type-safe Redux Actions within Reducer\n\n```tsx\n// reducer.ts\nimport * as fromActions from './actions'\n\nexport const initialState = 0 as number\nexport type State = typeof initialState\n\nexport const reducer = (\n  state = initialState,\n  action: fromActions.Actions\n): State =\u003e {\n  switch (action.type) {\n    case fromActions.INCREMENT: {\n      // $ExpectType 'INCREMENT'\n      const { type } = action\n\n      return state + 1\n    }\n    case fromActions.DECREMENT: {\n      // $ExpectType 'DECREMENT'\n      const { type } = action\n\n      return state - 1\n    }\n    default:\n      return state\n  }\n}\n```\n\n3.  Use Type-safe Redux Actions within Epics with `ofType` Rx operator\n\n```tsx\n// epics.ts\n\nimport { ofType } from '@martin_hotell/rex-tils'\nimport { ActionsObservable, StateObservable } from 'redux-observable'\nimport { filter, map, withLatestFrom } from 'rxjs/operators'\n\nimport * as fromActions from './actions'\nimport { AppState } from './store'\n\nexport const incrementIfOddEpic = (\n  // provide all our Actions type that can flow through the stream\n  // everything else is gonna be handled by TypeScript so we don't have to provide any explicit type annotations. Behold... top notch DX 👌❤️🦖\n  action$: ActionsObservable\u003cfromActions.Actions\u003e,\n  state$: StateObservable\u003cAppState\u003e\n) =\u003e\n  action$.pipe(\n    ofType(fromActions.INCREMENT_IF_ODD),\n    withLatestFrom(state$),\n    filter(\n      (\n        [action, state] // $ExpectType ['INCREMENT_IF_ODD', {counter:number}]\n      ) =\u003e state.counter % 2 === 1\n    ),\n    map(() =\u003e fromActions.Actions.increment())\n  )\n```\n\n## Examples\n\nGo checkout [examples](./examples) !\n\n## API\n\nrex-tils API is tiny and consist of 2 categories:\n\n1.  Runtime JavaScript helpers\n2.  Compile time TypeScript type helpers\n\n### 1. Runtime javascript helpers\n\n**`createAction\u003cT extends string,P\u003e(type: T,payload?: P): Action\u003cT,P\u003e`**\n\n- use for declaring action creators\n\n**`ofType(...keys:string[]): Observable\u003cAction\u003e`**\n\n- use within Epic/Effect for filtering actions\n\n#### Type guards:\n\n- all following type guards properly narrow your types 💪:\n\n**`isBlank(value:any)`**\n\n- checks if value is null or undefined\n\n**`isPresent(value:any)`**\n\n- checks if value is not null nor undefined\n\n**`isEmpty\u003cT extends string | object\u003e(value:T): Empty\u003cT\u003e`**\n\n- checks if value is empty for string | array | object otherwise it throws an error.\n- also it narrows the type to empty type equivalent\n\n**`isFunction(value:any)`**\n\n**`isBoolean(value:any)`**\n\n**`isString(value:any)`**\n\n**`isNumber(value:any)`**\n\n**`isArray(value:any)`**\n\n**`isObject\u003cT\u003e(value:T): T`**\n\n- normalized check if JS value is an object. That means anything that is not an array, not null/undefined but typeof value equals to 'object'\n- it will also properly narrow type within the branch\n\n```ts\ntype MyMap = { who: string; age: number }\ndeclare const someObj: MyMap | string | number\n\nif (isObject(someObj)) {\n  // $ExpectType MyMap\n  someObj\n} else {\n  // $ExpectType string | number\n  someObj\n}\n```\n\n**`isDate(value:any): value is Date`**\n\n**`isPromise(value:any): value is PromiseLike\u003cany\u003e`**\n\n#### Utils:\n\n**`noop(): void`**\n\n**`identity\u003cT\u003e(value:T):T`**\n\n**`Enum(...tokens:string[]): object`**\n\nAs described in [10 TypeScript Pro tips article](https://medium.com/@martin_hotell/10-typescript-pro-tips-patterns-with-or-without-react-5799488d6680), we don't recommend to use `enum` feature within your codebase. Instead you can leverage this small utility function which comes as both function and type alias to get proper enum object map and type literal, if you really need enums in runtime.\n\n```ts\n// enums.ts\n\n// $ExpectType Readonly\u003c{ No: \"No\"; Yes: \"Yes\"; }\u003e\n export const AnswerResponse = Enum('No', 'Yes')\n // $ExpectType 'No' | 'Yes'\n export type AnswerResponse = Enum(typeof AnswerResponse)\n\n // consumer.ts\n\n import {AnswerResponse} from './enums'\n\n export const respond = (\n   recipient: string,\n   // 1. 👉 enum used as type\n   message: AnswerResponse\n  ) =\u003e { /*...*/}\n\n // usage.ts\n\n import {respond} from './consumer'\n import {AnswerResponse} from './enums'\n\n respond('Johnny 5','Yes')\n respond(\n   'Johnny 5',\n   // 2. 👉  enum used as reference\n   AnswerResponse.No\n   )\n```\n\n**`tuple(...args: T): T`**\n\n- Implicitly create a tuple with proper tuple types instead of widened array of union types\n\n```ts\n// $ExpectType (string | number | boolean)[]\nconst testWidened = ['one', 1, false]\n\n// $ExpectType [string, number, boolean]\nconst testProperTuple = tuple('one', 1, false)\n```\n\n#### React/Preact related helpers:\n\n**`isEmptyChildren( children: ReactNode )`**\n\n- checks if Children.count === 0\n\n**`ChildrenAsFunction\u003cT extends AnyFunction\u003e( children: T ): T`**\n\n- similar to Children.only although checks if children is only a function. Useful for children as a function pattern. If not will throw an error otherwise narrows children type to function and returns it.\n\n```ts\ntype Props = {\n  userId: string\n  children: (props: { data: UserModel }) =\u003e ReactElement\n}\n\ntype State = { data: UserModel | null }\n\nclass UserRenderer extends Component\u003cProps, State\u003e {\n  render() {\n    const { data } = this.state\n    // Will throw on runtime if children is not a function\n    // $ExpectType (props: {data: UserModel}) =\u003e ReactElement\n    const childrenFn = ChildrenAsFunction(children)\n\n    return data ? children(data) : 'Loading...'\n  }\n\n  componentDidMount() {\n    fetch(`api/users/${this.props.userId}`)\n      .json()\n      .then((data) =\u003e this.setState({ data }))\n  }\n}\n\nconst App = () =\u003e (\n  \u003cUserRenderer userId={7}\u003e\n    {({ data }) =\u003e \u003cdiv\u003ename: {data.name}}\u003c/div\u003e}\n  \u003c/UserRenderer\u003e\n)\n```\n\n**`pickWithRest\u003cProps, PickedProps\u003e( props: object, pickProps: keyof PickedProps[] )`**\n\n- use for getting generic ...rest from object ( TS cannot do that by default )\n- you need to explicitly state generic params\n- `Props` generic props intersection\n- `PickedProps` props type from which you wanna pick properties so you get them via destructuring\n\n```tsx\ntype InjectedProps = { one: number; two: boolean }\nfunction test\u003cOriginalProps\u003e(props: OriginalProps) {\n  type Props = OriginalProps \u0026 InjectedProps\n  const {\n    // $ExpectType number\n    one,\n    // $ExpectType OriginalProps\n    rest,\n  } = pickWithRest\u003cProps, InjectedProps\u003e(props, ['one'])\n}\n```\n\n**`DefaultProps\u003cT\u003e(props: T): Readonly\u003cT\u003e`**\n\n- returns frozen object ( useful for default props )\n\n**`createPropsGetter\u003cT\u003e(props: T): T`**\n\n\u003e **Why ?**\n\u003e\n\u003e https://medium.com/@martin_hotell/react-typescript-and-defaultprops-dilemma-ca7f81c661c7\n\n- use for resolving defaultProps within component implementation\n- goes side by side with `DefaultProps` helper/type alias\n- it's just identity function with proper props type resolution\n\n```tsx\n// $ExpectType {onClick: (e: MouseEvent\u003cHTMLElement\u003e) =\u003e void, children: ReactNode, color?:'blue' | 'green' | 'red', type?: 'button' | 'submit'}\ntype Props = {\n  onClick: (e: MouseEvent\u003cHTMLElement\u003e) =\u003e void\n  children: ReactNode\n} \u0026 DefaultProps\u003ctypeof defaultProps\u003e\n\n// $ExpectType Readonly\u003c{color:'blue' | 'green' | 'red', type: 'button' | 'submit'}\u003e\nconst defaultProps = DefaultProps({\n  color: 'blue' as 'blue' | 'green' | 'red',\n  type: 'button' as 'button' | 'submit',\n})\nconst getProps = createPropsGetter(defaultProps)\n\nclass Button extends Component\u003cProps\u003e {\n  static readonly defaultProps = defaultProps\n  render() {\n    const {\n      // $ExpectType (e: MouseEvent\u003cHTMLElement\u003e) =\u003e void\n      onClick: handleClick,\n      // $ExpectType 'blue' | 'green' | 'red'\n      color,\n      // $ExpectType 'button' | 'submit'\n      type,\n      // $ExpectType ReactNode\n      children,\n    } = getProps(this.props)\n\n    return (\n      \u003cbutton onClick={handleClick} type={type} className={color}\u003e\n        {children}\n      \u003c/button\u003e\n    )\n  }\n}\n```\n\n#### React/Preact components:\n\n**`\u003cPre/\u003e`**\n\n- for debugging data within your render\n\n### 2. Compile time TypeScript type helpers\n\n**`ActionsUnion\u003cA extends StringMap\u003cAnyFunction\u003e\u003e = ReturnType\u003cA[keyof A]\u003e`**\n\n- use for getting action types from action creators implementation\n\n```tsx\ntype Actions = ActionsUnion\u003ctypeof Actions\u003e\n```\n\n**`ActionsOfType\u003cActionUnion, ActionType extends string\u003e`**\n\n- helper for getting particular action type from ActionsUnion\n\n```tsx\nconst SET_AGE = '[core] set age'\nconst SET_NAME = '[core] set name'\n\nconst Actions = {\n  setAge: (age: number) =\u003e createAction(SET_AGE, age),\n  setName: (name: string) =\u003e createAction(SET_NAME, name),\n}\n\ntype Actions = ActionsUnion\u003ctypeof Actions\u003e\n\ntype AgeAction = ActionsOfType\u003cActions, typeof SET_AGE\u003e\n\nconst action: AgeAction = {\n  type: '[core] set age',\n  payload: 23,\n}\n```\n\n**`AnyFunction = (...args: any[]) =\u003e any`**\n\n- use this type definition instead of `Function` type constructor\n\n**`StringMap\u003cT\u003e = { [key: string]: T }`**\n\n- simple alias to save you keystrokes when defining JS typed object maps\n\n```tsx\ntype Users = StringMap\u003c{ name: string; email: string }\u003e\n\nconst users: Users = {\n  1: { name: 'Martin', email: 'goo@gl.com' },\n  2: { name: 'John', email: 'doe@john.com' },\n}\n```\n\n**`Constructor\u003cT\u003e`**\n\n- alias for the construct signature that describes a type which can construct objects of the generic type T and whose constructor function accepts an arbitrary number of parameters of any type\n\n**`Omit\u003cT,K\u003e`**\n\n```tsx\ntype Result = Omit\u003c\n  {\n    one: string\n    two: number\n    three: boolean\n  },\n  'two'\n\u003e\n\nconst obj: Result = {\n  one: '123',\n  three: false,\n}\n```\n\n**`Diff\u003cT extends object,K extends object\u003e`**\n\n```tsx\ntype Result = Diff\u003c\n  {\n    one: string\n    two: number\n    three: boolean\n  },\n  {\n    two: number\n  }\n\u003e\n\nconst obj: Result = {\n  one: '123',\n  three: false,\n}\n```\n\n**`Primitive\u003cT\u003e`**\n\n- narrows type to primitive JS value ( boolean, string, number, symbol )\n\n**`NonPrimitive\u003cT\u003e`**\n\n- narrows type to non-primitive JS value ( object, function, array )\n\n**`Nullable\u003cT\u003e`**\n\n- opposite of standard library `NonNullable`\n\n**`Maybe\u003cT\u003e`**\n\n- Maybe types accept the provided type as well as null or undefined\n\n**`InstanceTypes\u003cT\u003e`**\n\n- obtain the return type of a constructor function type within array or object.\n  \u003e Like native lib.d.ts `InstanceType` but for arrays/tuples or objects\n\n```ts\nclass Foo {\n  hello = 'world'\n}\nclass Moo {\n  world = 'hello'\n}\n\nconst arr: [typeof Foo, typeof Moo] = [Foo, Moo]\nconst obj: { foo: typeof Foo; moo: typeof Moo } = { foo: Foo, moo: Moo }\n\n// $ExpectType [Foo, Moo]\ntype TestArr = InstanceTypes\u003ctypeof arr\u003e\n\n// $ExpectType {foo: Foo, moo: Moo}\ntype TestObj = InstanceTypes\u003ctypeof obj\u003e\n```\n\n**`Brand\u003cT,K\u003e`**\n\n- use this mapped typed for creating types for proper nominal type checking\n  \u003e for more info check this excellent [blog post about nominal typing in TypeScript](kudos to https://michalzalecki.com/nominal-typing-in-typescript/#approach-4-intersection-types-and-brands)\n\n```ts\ntype USD = Brand\u003cnumber, 'USD'\u003e\ntype EUR = Brand\u003cnumber, 'EUR'\u003e\n\nconst usd = 10 as USD\nconst eur = 10 as EUR\n\nfunction gross(net: USD, tax: USD): USD {\n  return (net + tax) as USD\n}\n\ngross(usd, usd) // ok\ngross(eur, usd) // Type '\"EUR\"' is not assignable to type '\"USD\"'.\n```\n\n**`UnionFromTuple\u003cT\u003e`**\n\n- extracts union type from tuple\n\n**`FunctionArgsTuple\u003cT\u003e`**\n\n\u003e @DEPRECATED 👉 Instead use standard library `Parameters` mapped type\n\n\u003e This is useful with React's children as a function(render prop) pattern, when implementing HoC\n\n```ts\nconst funcTestOneArgs = (one: number) =\u003e {\n  return\n}\n// $ExpectType [number]\ntype Test = FunctionArgsTuple\u003ctypeof funcTestNoArgs\u003e\n```\n\n**`Values\u003cT\u003e`**\n\n- `Values\u003cT\u003e` represents the union type of all the value types of the enumerable properties in an object Type T.\n\n```tsx\ntype Props = {\n  name: string\n  age: number\n}\n\n// The following two types are equivalent:\n// $ExpectType string | number\ntype Prop$Values = Values\u003cProps\u003e\n\n// $ExpectType string\nconst name: Prop$Values = 'Jon'\n// $ExpectType number\nconst age: Prop$Values = 42\n```\n\n**`Keys\u003cT\u003e`**\n\n- `keyof` doesn't work/distribute on union types. This mapped type fixes this issue\n\n**`KnownKeys\u003cT\u003e`**\n\n- gets proper known keys from object which contains index type `[key:string]: any`\n\n**`RequiredKnownKeys\u003cT\u003e`**\n\n- gets required only known keys from object which contains index type `[key:string]: any`\n\n**`OptionalKnownKeys\u003cT\u003e`**\n\n- gets optional only known keys from object which contains index type `[key:string]: any`\n\n**`PickWithTypeUnion\u003cBase, Condition\u003e`**\n\n- Pick key-values from Base provided by Condition generic type. Generic can be an union.\n\n\u003e **NOTE:**\n\u003e It doesn't work for undefined | null values. for that use `PickWithType`\n\n**`PickWithType\u003cBase, Condition\u003e`**\n\n- Pick key-values from Base provided by Condition generic type. Generic needs to be one type from `null | undefined | object | string | number | boolean`\n\n#### React related types:\n\n**`ElementProps\u003cT\u003e`**\n\nGets the props for a React element type, without preserving the optionality of defaultProps.\nType could be a React class component or a stateless functional component.\nThis type is used for the props property on `React.Element\u003ctypeof Component\u003e`.\n\n\u003e Like `React.Element\u003ctypeof Component\u003e`, Type must be the type of a React component, so you need to use typeof as in `React.ElementProps\u003ctypeof MyComponent\u003e`.\n\n**NOTE:**\nBecause ElementProps does not preserve the optionality of defaultProps, ElementConfig (which does) is more often the right choice, especially for simple props pass-through as with higher-order components.\n\n```tsx\nimport React from 'react'\n\nclass MyComponent extends React.Component\u003c{ foo: number }\u003e {\n  render() {\n    return this.props.foo\n  }\n}\n\n;({ foo: 42 } as ElementProps\u003ctypeof MyComponent\u003e)\n```\n\n**`ElementConfig\u003cT\u003e`**\n\nLike `ElementProps\u003ctypeof Component\u003e` this utility gets the type of a component’s props but preserves the optionality of defaultProps!\n\n\u003e Like React.Element\u003ctypeof Component\u003e, Type must be the type of a React component so you need to use typeof as in React.ElementProps\u003ctypeof MyComponent\u003e.\n\n```tsx\nimport React from 'react'\nclass MyComponent extends React.Component\u003c{ foo: number }\u003e {\n  static defaultProps = { foo: 42 }\n  render() {\n    return this.props.foo\n  }\n}\n\n// `ElementProps\u003c\u003e` requires `foo` even though it has a `defaultProp`.\n;(({ foo: 42 } as ElementProps\u003ctypeof MyComponent\u003e)(\n  // `ElementConfig\u003c\u003e` does not require `foo` since it has a `defaultProp`.\n  {} as ElementConfig\u003ctypeof MyComponent\u003e\n))\n```\n\n```tsx\ntype Props = { who: string }\ntype State = { count: number }\nclass Test extends Component\u003cProps, State\u003e {}\nconst TestFn = (_props: Props) =\u003e null\nconst TestFnViaGeneric: SFC\u003cProps\u003e = (_props) =\u003e null\n\n// $ExpectType {who: string}\ntype PropsFromComponent = GetComponentProps\u003cTest\u003e\n\n// $ExpectType {who: string}\ntype PropsFromFunction = GetComponentProps\u003ctypeof TestFn\u003e\n\n// $ExpectType {who: string}\ntype PropsFromFunction2 = GetComponentProps\u003ctypeof TestFnViaGeneric\u003e\n```\n\n**`ElementState\u003cT\u003e`**\n\nGets Component/PureComponent state type\n\n```tsx\nclass MyComponent extends React.Component\u003c{}, { foo: number }\u003e {\n  state = { foo: 42 }\n  render() {\n    return this.props.foo\n  }\n}\n\n// $ExpectType {foo: number}\ntype State = ElementState\u003ctypeof MyComponent\u003e\n```\n\n**`DefaultProps\u003cT\u003e(props: T): Partial\u003cT\u003e`**\n\n- type alias\n- useful for declaring Component props intersection with defaultProps\n\n## Guides\n\n@TODO\n\n---\n\n## Publishing\n\nExecute `yarn release` which will handle following tasks:\n\n- bump package version and git tag\n- update/(create if it doesn't exist) CHANGELOG.md\n- push to github master branch + push tags\n- publish build packages to npm\n\n\u003e releases are handled by awesome [standard-version](https://github.com/conventional-changelog/standard-version)\n\n### Pre-release\n\n- To get from `1.1.2` to `1.1.2-0`:\n\n`yarn release --prerelease`\n\n- **Alpha**: To get from `1.1.2` to `1.1.2-alpha.0`:\n\n`yarn release --prerelease alpha`\n\n- **Beta**: To get from `1.1.2` to `1.1.2-beta.0`:\n\n`yarn release --prerelease beta`\n\n### Dry run mode\n\nSee what commands would be run, without committing to git or updating files\n\n`yarn release --dry-run`\n\n### Check what files are gonna be published to npm\n\n- `yarn pack` OR `yarn release:preflight` which will create a tarball with everything that would get published to NPM\n\n## Tests\n\nTest are written and run via Jest 💪\n\n```\nyarn test\n# OR\nyarn test:watch\n```\n\n## Style guide\n\nStyle guides are enforced by robots, I meant prettier and tslint of course 🤖 , so they'll let you know if you screwed something, but most of the time, they'll autofix things for you. Magic right ?\n\n### Style guide npm scripts\n\n```sh\n#Format and fix lint errors\nyarn ts:style:fix\n```\n\n## Generate documentation\n\n`yarn docs`\n\n## Commit ( via commitizen )\n\n- this is preferred way how to create conventional-changelog valid commits\n- if you prefer your custom tool we provide a commit hook linter which will error out, it you provide invalid commit message\n- if you are in rush and just wanna skip commit message validation just prefix your message with `WIP: something done` ( if you do this please squash your work when you're done with proper commit message so standard-version can create Changelog and bump version of your library appropriately )\n\n`yarn commit` - will invoke [commitizen CLI](https://github.com/commitizen/cz-cli)\n\n### Troubleshooting\n\n## Licensing\n\n[MIT](./LICENSE.md) as always\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhotell%2Frex-tils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhotell%2Frex-tils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhotell%2Frex-tils/lists"}