Skip to content

Commit

Permalink
chore: kill Keys<T> in favor of keyof T
Browse files Browse the repository at this point in the history
BREAKING CHANGE: No longer exporting Keys<T> either. This alias is too
opinionated stylistically and doesn't support good TS practices. If
using it, it would be best to include in a per-project basis. Besides,
it isn't difficult to write or come up with (`type Keys<T> = keyof T;`),
so is outside the scope of this project.
  • Loading branch information
andnp committed Mar 11, 2019
1 parent 0464a62 commit c8daf48
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 43 deletions.
4 changes: 2 additions & 2 deletions src/impl/objects.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DeepReadonly, Keys, TaggedObject, ObjectKeys } from '../types/objects';
import { DeepReadonly, TaggedObject } from '../types/objects';

/**
* Type guard for any key, `k`.
Expand All @@ -17,7 +17,7 @@ export function isKeyOf<T extends object>(obj: T, k: ObjectKeys): k is keyof T {
* @returns an array of keys from `obj`
*/
export function objectKeys<T extends object>(obj: T) {
return Object.keys(obj) as Array<Keys<T>>;
return Object.keys(obj) as Array<keyof T>;
}

/**
Expand Down
38 changes: 16 additions & 22 deletions src/types/objects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type PlainObject = Record<string, any>;
* @returns An object formed by the key, value pairs of T
*/
export type ObjectType<T> = {
[k in Keys<T>]: T[k];
[k in keyof T]: T[k];
};
/**
* Takes two objects and returns their intersection.
Expand All @@ -34,7 +34,7 @@ export type CombineObjects<T extends object, U extends object> = ObjectType<T &
* @param K Key to query object for value
* @returns `T[K]` if the key exists, `never` otherwise
*/
export type GetKey<T, K extends ObjectKeys> = K extends Keys<T> ? T[K] : never;
export type GetKey<T, K extends keyof any> = K extends keyof T ? T[K] : never;

// ----
// Keys
Expand All @@ -55,51 +55,45 @@ export type ObjectKeys = keyof any;
* @param T type from which to get keys
* @returns keys of `T` that extend `string`
*/
export type StringKeys<T> = Exclude<Keys<T>, number | symbol>;
/**
* No different than `keyof`, but can look a bit nicer when nesting many types deep.
* @param T type from which to get keys
* @returns keys of `T` that extend `string | number | symbol`
*/
export type Keys<T> = keyof T;
export type StringKeys<T> = Exclude<keyof T, number | symbol>;
/**
* When an object has optional or readonly keys, that information is contained within the key.
* When using optional/readonly keys in another object, they will retain optional/readonly status.
* `PureKeys` will remove the optional/readonly status modifiers from keys.
* @param T type from which to get keys
* @returns keys of `T` without status modifiers (readonly/optional)
*/
export type PureKeys<T> = Record<Keys<T>, Keys<T>>[Keys<T>];
export type PureKeys<T> = Record<keyof T, keyof T>[keyof T];
/**
* Gets all of the keys that are shared between two objects.
* @param T first type from which keys will be pulled
* @param U second type from which keys will be pulled
* @returns the keys that both `T` and `U` have in common.
*/
export type SharedKeys<T, U> = Keys<T> & Keys<U>;
export type SharedKeys<T, U> = keyof T & keyof U;
/**
* Gets all keys between two objects.
* @param T first type from which keys will be pulled
* @param U second type from which keys will be pulled
* @returns the keys of `T` in addition to the keys of `U`
*/
export type AllKeys<T, U> = Keys<T> | Keys<U>;
export type AllKeys<T, U> = keyof T | keyof U;
/**
* Gets all of the keys that are different between two objects.
* This is a set difference between `Keys<T>` and `Keys<U>`.
* This is a set difference between `keyof T` and `keyof U`.
* Note that calling this with arguments reversed will have different results.
* @param T first type from which keys will be pulled
* @param U second type from which keys will be pulled
* @returns keys of `T` minus the keys of `U`
*/
export type DiffKeys<T, U> = Exclude<Keys<T>, Keys<U>>;
export type DiffKeys<T, U> = Exclude<keyof T, keyof U>;
/**
* Returns `True` if a key, `K`, is present in a type, `T`, else `False`.
* @param T type to check for existence of key `K`.
* @param K key to query `T` for
* @returns `True` if `K` is a key of `T`. Else `False`.
*/
export type HasKey<T, K extends ObjectKeys> = K extends Keys<T> ? True : False;
export type HasKey<T, K extends keyof any> = K extends keyof T ? True : False;

/**
* @param T the union to get the keys of
Expand All @@ -118,15 +112,15 @@ export type UnionKeys<T>
* @param T the object whose property values will be unionized
* @returns a union of the right-side values of `T`
*/
export type UnionizeProperties<T extends object> = T[Keys<T>];
export type UnionizeProperties<T extends object> = T[keyof T];
/**
* Gives back an object with listed keys removed.
* This is the opposite of `Pick`.
* @param T the object whose properties will be removed
* @param K the union of keys to remove from `T`
* @returns `T` with the keys `K` removed
*/
export type Omit<T extends object, K extends Keys<T>> = Pick<T, Exclude<Keys<T>, K>>;
export type Omit<T extends object, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
/**
* Returns only the shared properties between two objects.
* All shared properties must be the same type.
Expand Down Expand Up @@ -159,8 +153,8 @@ export type Merge<T extends object, U extends object> = Overwrite<T, U> & U;
* @param Key the key to add to each inner object as the tag property
* @returns a record where each key of the record is now the `Key` property of the inner object
*/
export type TaggedObject<T extends Record<ObjectKeys, object>, Key extends ObjectKeys> = {
[K in Keys<T>]: T[K] & Record<Key, K>;
export type TaggedObject<T extends Record<keyof any, object>, Key extends keyof any> = {
[K in keyof T]: T[K] & Record<Key, K>;
};

// ---------
Expand All @@ -185,15 +179,15 @@ export type DeepPartial<T> = Partial<{
* @returns `T` with all fields marked required
*/
export type AllRequired<T extends object> = {
[K in Keys<T>]-?: NonNullable<T[K]>
[K in keyof T]-?: NonNullable<T[K]>
};
/**
* Mark specific keys, `K`, of `T` as required.
* @param T object whose keys will be marked required
* @param K keys of `T` that will be marked required
* @returns `T` with keys, `K`, marked as required
*/
export type Required<T extends object, K extends Keys<T>> = CombineObjects<
export type Required<T extends object, K extends keyof T> = CombineObjects<
{[k in K]-?: NonNullable<T[k]> },
Omit<T, K>
>;
Expand All @@ -203,7 +197,7 @@ export type Required<T extends object, K extends Keys<T>> = CombineObjects<
* @param K keys of `T` that will be marked optional
* @returns `T` with keys, `K`, marked as optional
*/
export type Optional<T extends object, K extends Keys<T>> = CombineObjects<
export type Optional<T extends object, K extends keyof T> = CombineObjects<
{[k in K]?: T[k] | undefined },
Omit<T, K>
>;
Expand Down
11 changes: 5 additions & 6 deletions src/types/predicates.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { False, True, And, Or, Not } from './conditionals';
import { Keys } from './objects';
import { AnyFunc } from './functions';

/** no-doc */
export type KnownProblemPrototypeKeys = 'toString' | 'toLocaleString' | 'hasOwnProperty' | 'isPrototypeOf' | 'propertyIsEnumerable' | 'constructor' | 'valueOf';
/** no-doc */
export type ArrayPrototypeKeys = keyof unknown[];
/** no-doc */
export type NumberPrototypeKeys = Keys<number>;
export type NumberPrototypeKeys = keyof number;
/** no-doc */
export type BooleanPrototypeKeys = Keys<false>;
export type BooleanPrototypeKeys = keyof false;
/** no-doc */
export type StringPrototypeKeys = Keys<string>;
export type StringPrototypeKeys = keyof string;
/** no-doc */
export type ObjectPrototypeKeys = Keys<Object>; // tslint:disable-line
export type ObjectPrototypeKeys = keyof Object; // tslint:disable-line
/** no-doc */
export type FunctionPrototypeKeys = Keys<Function>; // tslint:disable-line
export type FunctionPrototypeKeys = keyof Function; // tslint:disable-line

export type IsNever<S extends string> = Not<(Record<S, True> & Record<string, False>)[S]>;
export type IsType<T, X> = X extends T ? True : False;
Expand Down
13 changes: 0 additions & 13 deletions test/objects/Keys.test.ts

This file was deleted.

0 comments on commit c8daf48

Please sign in to comment.