Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinigami92 authored Apr 30, 2022
2 parents 303369e + 36cd461 commit 7f9447d
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 159 deletions.
13 changes: 6 additions & 7 deletions src/finance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class Finance {
* faker.finance.currencyCode() // 'USD'
*/
currencyCode(): string {
return this.faker.random.objectElement(
return this.faker.helpers.objectValue(
this.faker.definitions.finance.currency
)['code'];
}
Expand All @@ -183,10 +183,9 @@ export class Finance {
* faker.finance.currencyName() // 'US Dollar'
*/
currencyName(): string {
return this.faker.random.objectElement(
this.faker.definitions.finance.currency,
'key'
);
return this.faker.helpers.objectKey(
this.faker.definitions.finance.currency
) as string;
}

/**
Expand All @@ -198,7 +197,7 @@ export class Finance {
currencySymbol(): string {
let symbol: string;
while (!symbol) {
symbol = this.faker.random.objectElement(
symbol = this.faker.helpers.objectValue(
this.faker.definitions.finance.currency
)['symbol'];
}
Expand Down Expand Up @@ -265,7 +264,7 @@ export class Finance {
} else {
// Choose a random issuer
// Credit cards are in an object structure
const formats = this.faker.random.objectElement(localeFormat, 'value'); // There could be multiple formats
const formats = this.faker.helpers.objectValue(localeFormat); // There could be multiple formats
format = this.faker.random.arrayElement(formats);
}
format = format.replace(/\//g, '');
Expand Down
35 changes: 31 additions & 4 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ export interface Transaction {
}

/**
* Module with various helper methods that don't fit in a particular category.
* Module with various helper methods that transform the method input rather than returning values from locales.
* The transformation process may call methods that use the locale data.
*/
export class Helpers {
constructor(private readonly faker: Faker) {
Expand Down Expand Up @@ -701,9 +702,9 @@ export class Helpers {
* @param options.probability The probability (`[0.00, 1.00]`) of the callback being invoked. Defaults to `0.5`.
*
* @example
* faker.random.maybe(() => 'Hello World!') // 'Hello World!'
* faker.random.maybe(() => 'Hello World!', { probability: 0.1 }) // undefined
* faker.random.maybe(() => 'Hello World!', { probability: 0.9 }) // 'Hello World!'
* faker.helpers.maybe(() => 'Hello World!') // 'Hello World!'
* faker.helpers.maybe(() => 'Hello World!', { probability: 0.1 }) // undefined
* faker.helpers.maybe(() => 'Hello World!', { probability: 0.9 }) // 'Hello World!'
*/
maybe<T>(
callback: () => T,
Expand All @@ -715,4 +716,30 @@ export class Helpers {
}
return undefined;
}

/**
* Returns a random key from given object.
*
* @param object The object to be used.
*
* @example
* faker.helpers.objectKey({ myProperty: 'myValue' }) // 'myProperty'
*/
objectKey<T extends Record<string, unknown>>(object: T): keyof T {
const array: Array<keyof T> = Object.keys(object);
return this.faker.random.arrayElement(array);
}

/**
* Returns a random value from given object.
*
* @param object The object to be used.
*
* @example
* faker.helpers.objectValue({ myProperty: 'myValue' }) // 'myValue'
*/
objectValue<T extends Record<string, unknown>>(object: T): T[keyof T] {
const key = this.faker.helpers.objectKey(object);
return object[key];
}
}
3 changes: 2 additions & 1 deletion src/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Faker } from '.';
import { LoremPicsum } from './image_providers/lorempicsum';
import { Lorempixel } from './image_providers/lorempixel';
import { Unsplash } from './image_providers/unsplash';
import type { MethodsOf } from './utils/types';

/**
* Module to generate placeholder images.
Expand Down Expand Up @@ -40,7 +41,7 @@ export class Image {
* faker.image.image(1234, 2345, true) // 'http://loremflickr.com/1234/2345/nature?56789'
*/
image(width?: number, height?: number, randomize?: boolean): string {
const categories = [
const categories: MethodsOf<Image, Image['image']> = [
'abstract',
'animals',
'business',
Expand Down
3 changes: 2 additions & 1 deletion src/image_providers/lorempixel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Faker } from '..';
import type { MethodsOf } from '../utils/types';

/**
* Module to generate links to random images on `https://lorempixel.com/`.
Expand All @@ -14,7 +15,7 @@ export class Lorempixel {
* @param randomize Whether to append a seed to the url. Defaults to `false`.
*/
image(width?: number, height?: number, randomize?: boolean): string {
const categories = [
const categories: MethodsOf<Lorempixel, Lorempixel['image']> = [
'abstract',
'animals',
'business',
Expand Down
75 changes: 62 additions & 13 deletions src/random.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,25 +161,42 @@ export class Random {
}

/**
* Returns a random key or value from given object.
* Returns a random key from given object.
*
* @template T The type of `Record` to pick from.
* @template K The keys of `T`.
* @param object The object to get the keys or values from.
* @param object The object to get the keys from.
* @param field If this is set to `'key'`, this method will a return a random key of the given instance.
* If this is set to `'value'`, this method will a return a random value of the given instance.
* Defaults to `'value'`.
*
* @see faker.helpers.objectKey()
*
* @example
* const object = { keyA: 'valueA', keyB: 42 };
* faker.random.objectElement(object) // 42
* faker.random.objectElement(object, 'key') // 'keyB'
* faker.random.objectElement(object, 'value') // 'valueA'
*
* @deprecated
*/
objectElement<T extends Record<string, unknown>, K extends keyof T>(
object: T,
field: 'key'
): K;
/**
* Returns a random value from given object.
*
* @template T The type of `Record` to pick from.
* @template K The keys of `T`.
* @param object The object to get the values from.
* @param field If this is set to `'value'`, this method will a return a random value of the given instance.
*
* @see faker.helpers.objectValue()
*
* @example
* const object = { keyA: 'valueA', keyB: 42 };
* faker.random.objectElement(object) // 42
* faker.random.objectElement(object, 'value') // 'valueA'
*
* @deprecated
*/
objectElement<T extends Record<string, unknown>, K extends keyof T>(
object: T,
field?: unknown
Expand All @@ -194,24 +211,56 @@ export class Random {
* If this is set to `'value'`, this method will a return a random value of the given instance.
* Defaults to `'value'`.
*
* @see faker.helpers.objectKey()
* @see faker.helpers.objectValue()
*
* @example
* const object = { keyA: 'valueA', keyB: 42 };
* faker.random.objectElement(object) // 42
* faker.random.objectElement(object, 'key') // 'keyB'
* faker.random.objectElement(object, 'value') // 'valueA'
*
* @deprecated
*/
objectElement<T extends Record<string, unknown>, K extends keyof T>(
object: T,
object?: T,
field?: 'key' | 'value'
): K | T[K];
/**
* Returns a random key or value from given object.
*
* @template T The type of `Record` to pick from.
* @template K The keys of `T`.
* @param object The object to get the keys or values from.
* @param field If this is set to `'key'`, this method will a return a random key of the given instance.
* If this is set to `'value'`, this method will a return a random value of the given instance.
* Defaults to `'value'`.
*
* @see faker.helpers.objectKey()
* @see faker.helpers.objectValue()
*
* @example
* const object = { keyA: 'valueA', keyB: 42 };
* faker.random.objectElement(object) // 42
* faker.random.objectElement(object, 'key') // 'keyB'
* faker.random.objectElement(object, 'value') // 'valueA'
*
* @deprecated
*/
objectElement<T extends Record<string, unknown>, K extends keyof T>(
object = { foo: 'bar', too: 'car' } as unknown as T,
field = 'value'
object: T = { foo: 'bar', too: 'car' } as unknown as T,
field: 'key' | 'value' = 'value'
): K | T[K] {
const array: Array<keyof T> = Object.keys(object);
const key = this.arrayElement(array);

return field === 'key' ? (key as K) : (object[key] as T[K]);
const useKey = field === 'key';
deprecated({
deprecated: `faker.random.objectElement(${useKey ? "obj, 'key'" : ''})`,
proposed: `faker.helpers.object${useKey ? 'Key' : 'Value'}()`,
since: 'v6.3.0',
until: 'v7.0.0',
});
return field === 'key'
? (this.faker.helpers.objectKey(object) as K)
: (this.faker.helpers.objectValue(object) as T[K]);
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Type that represents a single method/function name of the given type.
*/
export type MethodOf<
ObjectType,
Signature extends (...args) => unknown = (...args) => unknown
> = {
[Key in keyof ObjectType]: ObjectType[Key] extends Signature ? Key : never;
}[keyof ObjectType];

/**
* Type that represents all method/function names of the given type.
*/
export type MethodsOf<
ObjectType,
Signature extends (...args) => unknown = (...args) => unknown
> = ReadonlyArray<MethodOf<ObjectType, Signature>>;
Loading

0 comments on commit 7f9447d

Please sign in to comment.