Skip to content

Commit

Permalink
Typescript (#72)
Browse files Browse the repository at this point in the history
Converting to Typescript
  • Loading branch information
alexreardon authored Aug 21, 2019
1 parent 2fdb284 commit 354cc77
Show file tree
Hide file tree
Showing 40 changed files with 1,727 additions and 8,422 deletions.
9 changes: 0 additions & 9 deletions .babelrc

This file was deleted.

22 changes: 7 additions & 15 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
module.exports = {
extends: [
'prettier',
'eslint:recommended',
'plugin:flowtype/recommended',
'prettier/flowtype',
],
parser: 'babel-eslint',
plugins: ['prettier', 'jest', 'flowtype'],
extends: ['prettier', 'plugin:@typescript-eslint/recommended', 'eslint:recommended'],
parser: '@typescript-eslint/parser',
plugins: ['prettier', 'jest', '@typescript-eslint'],
env: {
node: true,
browser: true,
Expand All @@ -25,7 +20,7 @@ module.exports = {
// use `invariant` and `warning`
'no-console': ['error'],

// Opting out of prefer destructuring (nicer with flow in lots of cases)
// Opting out of prefer destructuring (nicer with types in lots of cases)
'prefer-destructuring': 'off',

// Disallowing the use of variables starting with `_` unless it called on `this`.
Expand All @@ -39,11 +34,8 @@ module.exports = {
// Allowing ++ on numbers
'no-plusplus': 'off',

// Require // @flow at the top of files
'flowtype/require-valid-file-annotation': [
'error',
'always',
{ annotationStyle: 'line' },
],
'@typescript-eslint/no-inferrable-types': 'off',

'@typescript-eslint/ban-ts-ignore': 'off',
},
};
5 changes: 0 additions & 5 deletions .flowconfig

This file was deleted.

3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"semi": true,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true
"singleQuote": true,
"printWidth": 100
}
50 changes: 17 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ A memoization library that only caches the result of the most recent arguments.

[![Build Status](https://travis-ci.org/alexreardon/memoize-one.svg?branch=master)](https://travis-ci.org/alexreardon/memoize-one)
[![npm](https://img.shields.io/npm/v/memoize-one.svg)](https://www.npmjs.com/package/memoize-one)
![types](https://img.shields.io/badge/types-typescript%20%7C%20flow-blueviolet)
[![dependencies](https://david-dm.org/alexreardon/memoize-one.svg)](https://david-dm.org/alexreardon/memoize-one)
[![Downloads per month](https://img.shields.io/npm/dm/memoize-one.svg)](https://www.npmjs.com/package/memoize-one)
[![min](https://img.shields.io/bundlephobia/min/memoize-one.svg)](https://www.npmjs.com/package/memoize-one)
[![minzip](https://img.shields.io/bundlephobia/minzip/memoize-one.svg)](https://www.npmjs.com/package/memoize-one)
[![Downloads per month](https://img.shields.io/npm/dm/memoize-one.svg)](https://www.npmjs.com/package/memoize-one)

## Rationale

Unlike other memoization libraries, `memoize-one` only remembers the latest arguments and result. No need to worry about cache busting mechanisms such as `maxAge`, `maxSize`, `exclusions` and so on which can be prone to memory leaks. `memoize-one` simply remembers the last arguments, and if the function is next called with the same arguments then it returns the previous result.

## Usage

### Standard usage

```js
import memoizeOne from 'memoize-one';

Expand Down Expand Up @@ -50,46 +48,32 @@ yarn add memoize-one
npm install memoize-one --save
```

## Module usage
## Custom equality function

### ES6 module
You can also pass in a custom function for checking the equality of two sets of arguments

```js
import memoizeOne from 'memoize-one';
const memoized = memoizeOne(fn, isEqual);
```

### CommonJS
The equality function needs to conform to this `type`:

If you are in a CommonJS environment (eg [Node](https://nodejs.org)), then **you will need to add `.default` to your import**:
```ts
type EqualityFn = (newArgs: readonly unknown[], lastArgs: readonly unknown[]) => boolean;

```js
const memoizeOne = require('memoize-one').default;
```
// You can import this type from memoize-one if you like

## Custom equality function

You can also pass in a custom function for checking the equality of two sets of arguments
// typescript
import { EqualityFn } from 'memoize-one';

```js
const memoized = memoizeOne(fn, isEqual);
type EqualityFn = (newArgs: mixed[], oldArgs: mixed[]) => boolean;
// flow
import type { EqualityFn } from 'memoize-one';
```

An equality function should return `true` if the arguments are equal. If `true` is returned then the wrapped function will not be called.

The default equality function is a shallow equal check of all arguments (each argument is compared with `===`). If the `length` of arguments change, then the default equality function makes no shallow equality checks. You are welcome to decide if you want to return `false` if the `length` of the arguments is not equal

```js
const simpleIsEqual: EqualityFn = (
newArgs: mixed[],
lastArgs: mixed[],
): boolean =>
newArgs.length === lastArgs.length &&
newArgs.every((newArg: mixed, index: number): boolean =>
shallowEqual(newArg, lastArgs[index]),
);
```

A custom equality function needs to compare `Arrays`. The `newArgs` array will be a new reference every time so a simple `newArgs === lastArgs` will always return `false`.

Equality functions are not called if the `this` context of the function has changed (see below).
Expand Down Expand Up @@ -204,7 +188,7 @@ console.log(value1 === value3);
// console.log => true
```

## Performance :rocket:
## Performance 🚀

### Tiny

Expand All @@ -221,11 +205,11 @@ console.log(value1 === value3);

The comparisons are not exhaustive and are primarily to show that `memoize-one` accomplishes remembering the latest invocation really fast. The benchmarks do not take into account the differences in feature sets, library sizes, parse time, and so on.

## Code health :thumbsup:
## Code health 👍

- Tested with all built in [JavaScript types](https://github.com/getify/You-Dont-Know-JS/blob/master/types%20%26%20grammar/ch1.md).
- 100% code coverage
- [Continuous integration](https://travis-ci.org/alexreardon/memoize-one) to run tests and type checks.
- [`Flow` types](http://flowtype.org) for safer internal execution and external consumption. Also allows for editor autocompletion.
- Follows [Semantic versioning (2.0)](http://semver.org/) for safer consumption.
- Written in `Typescript`
- Correct typing for `Typescript` and `flow` type systems
- No dependencies
19 changes: 10 additions & 9 deletions benchmarks/shallowEqual.js → benchmarks/shallow-equal.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/* eslint-disable flowtype/require-valid-file-annotation */

// @ts-nocheck
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Benchmark = require('benchmark');

const suite = new Benchmark.Suite();

function shallowEvery(a, b) {
function shallowEvery(a, b): boolean {
if (a.length !== b.length) {
return false;
}

return a.every((e, i) => b[i] === e);
}

function shallowFor(a, b) {
function shallowFor(a, b): boolean {
if (a.length !== b.length) {
return false;
}
Expand All @@ -25,11 +25,11 @@ function shallowFor(a, b) {
return true;
}

let a = {};
let b = {};
const a = {};
const b = {};

let listA = [a, b, {}, {}];
let listB = [a, b, {}, {}];
const listA = [a, b, {}, {}];
const listB = [a, b, {}, {}];

suite.add('shallowEvery with identical lists', () => {
shallowEvery(listA, listA);
Expand All @@ -47,6 +47,7 @@ suite.add('shallowFor with half-identical lists', () => {
shallowFor(listA, listB);
});

suite.on('cycle', e => console.log(String(e.target)));
// eslint-disable-next-line no-console
suite.on('cycle', (e: any) => console.log(String(e.target)));

suite.run({ async: true });
Loading

0 comments on commit 354cc77

Please sign in to comment.