Skip to content

Commit

Permalink
docs(typescript): update README about type support
Browse files Browse the repository at this point in the history
  • Loading branch information
MunifTanjim committed Mar 3, 2021
1 parent e952712 commit aed912f
Showing 1 changed file with 81 additions and 30 deletions.
111 changes: 81 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

### Singular hook

Recommended for [TypeScript](#typescript)

```js
// instantiate singular hook API
const hook = new Hook.Singular();
Expand Down Expand Up @@ -526,49 +524,102 @@ hookCollection.remove("save", validateRecord);

## TypeScript

This library contains type definitions for TypeScript. When you use TypeScript we highly recommend using the `Hook.Singular` constructor for your hooks as this allows you to pass along type information for the options object. For example:
This library contains type definitions for TypeScript.

### Type support for `Singular`:

```ts
import { Hook } from 'before-after-hook';

import {Hook} from 'before-after-hook'
type O = { foo: string }; // type for options
type R = { bar: number }; // type for result
type E = Error; // type for error

interface Foo {
bar: string
num: number;
}
const hook = new Hook.Singular<O, R, E>();

const hook = new Hook.Singular<Foo>();
hook.before((options) => {
// `options.foo` has `string` type

hook.before(function (foo) {
// not allowed
options.foo = 42;

// typescript will complain about the following mutation attempts
foo.hello = 'world'
foo.bar = 123
// allowed
options.foo = 'Forty-Two';
});

// yet this is valid
foo.bar = 'other-string'
foo.num = 123
})
const hookedMethod = hook(
(options) => {
// `options.foo` has `string` type

const foo = hook(function(foo) {
// handle `foo`
foo.bar = 'another-string'
}, {bar: 'random-string'})
// not allowed, because it does not satisfy the `R` type
return { foo: 42 };

// foo outputs
{
bar: 'another-string',
num: 123
}
// allowed
return { bar: 42 };
},
{ foo: 'Forty-Two' }
);
```

You can choose not to pass the types for options, result or error. So, these are completely valid:

```ts
const hook = new Hook.Singular<O, R>();
const hook = new Hook.Singular<O>();
const hook = new Hook.Singular();
```

In these cases, the omitted types will implicitly be `any`.

### Type support for `Collection`:

`Collection` also has strict type support. You can use it like this:

```ts
import { Hook } from 'before-after-hook';

type HooksType = {
add: { O: { type: string }; R: { id: number }; E: Error };
save: { O: { type: string }; R: { id: number } };
read: { O: { id: number; foo: number } };
destroy: { O: { id: number; foo: string } };
};

const hooks = Hook.Collection<HooksType>();

hooks.before('destroy', (options) => {
// `options.id` has `number` type
});

hooks.error('add', (err, options) => {
// `options.type` has `string` type
// `err` is `instanceof Error`
});

hooks.error('save', (err, options) => {
// `options.type` has `string` type
// `err` has type `any`
});

hooks.after('save', (result, options) => {
// `options.type` has `string` type
// `result.id` has `number` type
});
```

You can choose not to pass the types altogether. In that case, everything will implicitly be `any`:

```ts
const hook = new Hook.Collection();
```

An alternative import:
Alternative imports:

```ts
import { Singular, Collection } from "before-after-hook";
import { Singular, Collection } from 'before-after-hook';

const hook = new Singular<{ foo: string }>();
const hookCollection = new Collection();
const hook = new Singular();
const hooks = new Collection();
```

## Upgrading to 1.4
Expand Down

0 comments on commit aed912f

Please sign in to comment.