diff --git a/test/zipObj.test.ts b/test/zipObj.test.ts new file mode 100644 index 0000000..ff0d74f --- /dev/null +++ b/test/zipObj.test.ts @@ -0,0 +1,32 @@ +import { expectType } from 'tsd'; +import { zipObj } from '../types/zipObj'; +import { pipe } from '../types/pipe'; + +const sym = Symbol.for('Symbol'); + +// zipObj(key, values) +expectType<{bool: true, number: 1, null: null, undefined: undefined}>(zipObj(['bool', 'number', 'null', 'undefined'], [true, 1, null, undefined])); +expectType<{1: 1, [sym]: symbol}>(zipObj([1, sym], [1, sym])); +expectType<{bool: boolean, number: number}>(zipObj(['bool', 'number'], [true, 1] as [boolean, number])); +expectType<{[key: string]: boolean}>(zipObj(['a'] as string[], [true, false] as boolean[])); +expectType<{a: boolean}>(zipObj(['a'], [true, false] as boolean[])); +expectType<{[key: string]: boolean}>(zipObj(['a'] as string[], [true, false])); +expectType<{[key: string]: boolean | number | string}>(zipObj(['a', 'b', 'c'] as string[], [true, 1, 'a'] as (string | number | boolean)[])); +expectType<{bool: true, number: 1}>(zipObj(['bool', 'number'], [true, 1, 'string'])); +expectType<{bool: true, number: 1, missing: undefined}>(zipObj(['bool', 'number', 'missing'], [true, 1])); + +// zipObj(key)(values) +expectType<{bool: true, number: 1, null: null, undefined: undefined}>(zipObj(['bool', 'number', 'null', 'undefined'])([true, 1, null, undefined])); +expectType<{1: 1, [sym]: symbol}>(zipObj([1, sym])([1, sym])); +expectType<{bool: boolean, number: number}>(zipObj(['bool', 'number'])([true, 1] as [boolean, number])); +expectType<{[key: string]: boolean}>(zipObj(['a'] as string[])([true, false] as boolean[])); +expectType<{a: boolean}>(zipObj(['a'])([true, false] as boolean[])); +expectType<{[key: string]: boolean}>(zipObj(['a'] as string[])([true, false])); +expectType<{bool: true, number: 1}>(zipObj(['bool', 'number'])([true, 1, 'string'])); +expectType<{bool: true, number: 1, missing: undefined}>(zipObj(['bool', 'number', 'missing'])([true, 1])); + + +expectType<{string: string, number: number}>(pipe( + (a: [string, number]) => a, + zipObj(['string', 'number']) +)(['a', 42])); diff --git a/types/util/zipObj.d.ts b/types/util/zipObj.d.ts new file mode 100644 index 0000000..fd0d828 --- /dev/null +++ b/types/util/zipObj.d.ts @@ -0,0 +1,7 @@ +import * as _ from 'ts-toolbelt'; + +export type _ZipObj = + number extends V['length'] ? + { [T in K[number]]: V[number] } : + number extends K['length'] ? + { [T in K[number]]: V[number] } : _.L.ZipObj; diff --git a/types/zipObj.d.ts b/types/zipObj.d.ts index df5d2f8..6432e0b 100644 --- a/types/zipObj.d.ts +++ b/types/zipObj.d.ts @@ -1,3 +1,9 @@ -export function zipObj(keys: readonly K[]): (values: readonly T[]) => { [P in K]: T }; -export function zipObj(keys: readonly K[], values: readonly T[]): { [P in K]: T }; +import * as _ from 'ts-toolbelt'; +import { _ZipObj } from './util/zipObj'; +export function zipObj(keys: _.F.Narrow): +(values: _.F.Narrow) => +_ZipObj; + +export function zipObj(keys: _.F.Narrow, values: _.F.Narrow): +_ZipObj;