Skip to content

Commit

Permalink
fix(micro-dash): fix typing for omit() with a nullish object
Browse files Browse the repository at this point in the history
Closes #78
  • Loading branch information
ersimont committed Jul 1, 2022
1 parent 55ed624 commit 4a343c3
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 50 deletions.
1 change: 1 addition & 0 deletions projects/micro-dash/src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export type Nil = null | undefined;
export type Primitive = boolean | number | string;
export type Key = keyof any; // TODO: replace with built-in PropertyKey
export type Existent = Primitive | object;
export type EmptyObject = Record<string, never>;
export type ObjectWith<T> = Record<string, T>;
export type StringifiedKey<T> = Cast<keyof T, string>;

Expand Down
69 changes: 69 additions & 0 deletions projects/micro-dash/src/lib/object/omit.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,75 @@
import { staticTest } from '@s-libs/ng-dev';
import { expectTypeOf } from 'expect-type';
import { EmptyObject } from '../interfaces';
import { omit } from './';

describe('omit()', () => {
it('has fancy typing', () => {
staticTest(() => {
const str = '' as string;
const num = 0 as number;

interface Obj {
a: number;
b: Date;
}
const obj = {} as Obj;
const objOrN = {} as Obj | null;
const objOrU = {} as Obj | undefined;
expectTypeOf(omit(obj, 'b')).toEqualTypeOf<{ a: number }>();
expectTypeOf(omit(objOrN, 'b')).toEqualTypeOf<
{ a: number } | EmptyObject
>();
expectTypeOf(omit(objOrU, 'b')).toEqualTypeOf<
{ a: number } | EmptyObject
>();

const indexed = {} as { [k: string]: number; [k: number]: number };
expectTypeOf(omit(indexed, 'hi')).toEqualTypeOf<{
[x: string]: number;
[x: number]: number;
}>();
expectTypeOf(omit(indexed, 5)).toEqualTypeOf<{
[x: string]: number;
[x: number]: number;
}>();
expectTypeOf(omit(indexed, 'hi', 5)).toEqualTypeOf<{
[x: string]: number;
[x: number]: number;
}>();
expectTypeOf(omit(indexed, str)).toEqualTypeOf<{
[x: string]: number;
[x: number]: number;
}>();

const record = {} as Record<string, number>;
expectTypeOf(omit(record, str)).toEqualTypeOf<Record<string, number>>();

const composite = {} as { [k: number]: Date; a: 'eh'; b: 'bee' };
expectTypeOf(omit(composite, 'a')).toEqualTypeOf<{
[x: number]: Date;
b: 'bee';
}>();
expectTypeOf(omit(composite, 'a', 'b')).toEqualTypeOf<
Record<number, Date>
>();
expectTypeOf(omit(composite, 1)).toEqualTypeOf<{
[x: number]: Date;
a: 'eh';
b: 'bee';
}>();
expectTypeOf(omit(composite, num)).toEqualTypeOf<{
[x: number]: Date;
a: 'eh';
b: 'bee';
}>();
expectTypeOf(omit(composite, num, 'a')).toEqualTypeOf<{
[x: number]: Date;
b: 'bee';
}>();
});
});

//
// stolen from https://github.com/healthiers/mini-dash
//
Expand Down
18 changes: 12 additions & 6 deletions projects/micro-dash/src/lib/object/omit.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Nil } from '../interfaces';
import { EmptyObject, IfCouldBe, Nil } from '../interfaces';
import { clone } from '../lang';

type RemainingKeys<T, Omits> =
Expand All @@ -16,15 +16,21 @@ type RemainingKeys<T, Omits> =
* - Lodash: 16,006 bytes
* - Micro-dash: 170 bytes
*/
export function omit<T extends Nil | object, O extends ReadonlyArray<keyof T>>(
export function omit<
T extends object | Nil,
O extends ReadonlyArray<keyof Exclude<T, Nil>>,
>(
object: T,
...paths: O
): {
[K in RemainingKeys<T, O[number]>]: T[K];
} {
):
| {
[K in RemainingKeys<Exclude<T, Nil>, O[number]>]: Exclude<T, Nil>[K];
}
| IfCouldBe<T, Nil, EmptyObject> {
// TODO: test size of `??`
const obj: any = clone(object) || {};
for (const path of paths) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- well, this is exactly what the user requested, so ...
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete -- this is exactly what the user requested, so ...
delete obj[path];
}
return obj;
Expand Down
44 changes: 0 additions & 44 deletions projects/micro-dash/src/typing-tests/object/omit.dts-spec.ts

This file was deleted.

0 comments on commit 4a343c3

Please sign in to comment.