-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathkeyOf.ts
31 lines (26 loc) · 889 Bytes
/
keyOf.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { pipe } from 'fp-ts/function';
import * as RE from 'fp-ts/ReaderEither';
import { ask, validate, VariableDecoder } from './VariableDecoder';
const oneOf = (xs: string[]): string =>
xs
.slice(0, -1)
.map((x) => `'${x}'`)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.join(', ') + `, or '${xs[xs.length - 1]!}'`;
/**
* Decodes a string that is a key of the given object.
*
* @example
* const logLevelD = keyOf({
* debug: null,
* info: null,
* warn: null,
* error: null,
* });
*/
const keyOf = <Keys extends string>(record: Readonly<{ [Key in Keys]: unknown }>): VariableDecoder<Keys> => {
const keys = Object.keys(record);
const included = (x: string): x is Keys => keys.includes(x);
return pipe(ask(), RE.chain(validate(included, `must be one of ${oneOf(keys)}`)));
};
export { keyOf };