Skip to content

Commit

Permalink
feat(zipObj): stricter types, add test
Browse files Browse the repository at this point in the history
  • Loading branch information
GerkinDev committed Jan 27, 2024
1 parent 4d4f2ea commit 4e84243
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
24 changes: 24 additions & 0 deletions test/zipObj.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { expectType } from 'tsd';
import { zipObj } from '../types/zipObj';

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<{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]));
15 changes: 13 additions & 2 deletions types/zipObj.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
export function zipObj<K extends PropertyKey>(keys: readonly K[]): <T>(values: readonly T[]) => { [P in K]: T };
export function zipObj<T, K extends PropertyKey>(keys: readonly K[], values: readonly T[]): { [P in K]: T };
import * as _ from 'ts-toolbelt';

export type _ZipObj<K extends readonly PropertyKey[], V extends {[key in keyof K]: unknown} | readonly unknown[]> =
number extends V['length'] ?
{ [T in K[number]]: V[number] } :
number extends K['length'] ?
{ [T in K[number]]: V[number] } : _.L.ZipObj<K, V>;

export function zipObj<K extends readonly PropertyKey[]>(keys: _.F.Narrow<K>):
<V extends {[key in keyof K]: unknown} | readonly unknown[]>(values: _.F.Narrow<V>) =>
_ZipObj<K, V>;

export function zipObj<K extends readonly PropertyKey[], V extends {[key in keyof K]: unknown} | readonly unknown[]>(keys: _.F.Narrow<K>, values: _.F.Narrow<V>):
_ZipObj<K, V>;

0 comments on commit 4e84243

Please sign in to comment.