Skip to content

Commit

Permalink
feat(micro-dash): improve the typing of omit()
Browse files Browse the repository at this point in the history
  • Loading branch information
ersimont committed Nov 25, 2020
1 parent a57466a commit 48d267b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
2 changes: 1 addition & 1 deletion projects/micro-dash/src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export type Nil = null | undefined;
/** @hidden */
export type Primitive = boolean | number | string;
/** @hidden */
export type Key = keyof any;
export type Key = keyof any; // TODO: replace with built-in PropertyKey
/** @hidden */
export type Existent = Primitive | object;
/** @hidden */
Expand Down
4 changes: 2 additions & 2 deletions projects/micro-dash/src/lib/object/omit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ describe('omit()', () => {
});

it('should return an empty object when `object` is nullish', () => {
expect(omit<any>(null, 'valueOf')).toEqual({});
expect(omit<any>(undefined, 'valueOf')).toEqual({});
expect(omit<any, any>(null, 'valueOf')).toEqual({});
expect(omit<any, any>(undefined, 'valueOf')).toEqual({});
});

it('should not mutate `object`', () => {
Expand Down
13 changes: 10 additions & 3 deletions projects/micro-dash/src/lib/object/omit.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Nil } from '../interfaces';
import { clone } from '../lang';

/** @hidden */
type RemainingKeys<T, Omits> =
| Exclude<keyof T, Omits>
| Extract<PropertyKey, keyof T>; // always include index properties

/**
* The opposite of `pick`; this method creates an object composed of the own enumerable string properties of object that are not omitted.
*
Expand All @@ -12,10 +17,12 @@ import { clone } from '../lang';
* - Lodash: 15,567 bytes
* - Micro-dash: 155 bytes
*/
export function omit<T extends object | Nil>(
export function omit<T extends object | Nil, O extends Array<keyof T>>(
object: T,
...paths: Array<keyof T>
): Partial<T> {
...paths: O
): {
[K in RemainingKeys<T, O[number]>]: T[K];
} {
const obj: any = clone(object) || {};
for (const path of paths) {
delete obj[path];
Expand Down
44 changes: 44 additions & 0 deletions projects/micro-dash/src/typing-tests/object/omit.dts-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { omit } from '../../lib/object';

declare const str: string;
declare const num: number;

declare const obj: {
a: number;
b: Date;
};
// $ExpectType { a: number; }
omit(obj, 'b');

declare const indexed: {
[k: string]: number;
[k: number]: number;
};
// $ExpectType { [x: string]: number; [x: number]: number; }
omit(indexed, 'hi');
// $ExpectType { [x: string]: number; [x: number]: number; }
omit(indexed, 5);
// $ExpectType { [x: string]: number; [x: number]: number; }
omit(indexed, 'hi', 5);
// $ExpectType { [x: string]: number; [x: number]: number; }
omit(indexed, str);

declare const record: Record<string, number>;
// $ExpectType { [x: string]: number; }
omit(record, str);

declare const composite: {
[k: number]: Date;
a: 'eh';
b: 'bee';
};
// $ExpectType { [x: number]: Date; b: "bee"; }
omit(composite, 'a');
// $ExpectType { [x: number]: Date; }
omit(composite, 'a', 'b');
// $ExpectType { [x: number]: Date; a: "eh"; b: "bee"; }
omit(composite, 1);
// $ExpectType { [x: number]: Date; a: "eh"; b: "bee"; }
omit(composite, num);
// $ExpectType { [x: number]: Date; b: "bee"; }
omit(composite, num, 'a');

0 comments on commit 48d267b

Please sign in to comment.