Search code examples
node.jstypescriptfaker.js

Using Faker to get and set gender for all following data


I'm using Faker with TypeScript and am struggling to figure out how to capture the returned gender from Faker in a way that I can then use in subsequent calls. This is what I'd like to do:

const gender = faker.name.gender(true);  // <-- returns a string
const firstName = faker.name.firstName(gender);  
const middleName = faker.name.middleName(gender);  

Unfortunately, Faker's faker.name.firstName(gender) takes a GenderType enum value, not a string, even though you can use it like faker.name.firstName('male'). That works, but using the variable gender doesn't work.

Am I missing something here?


Solution

  • faker.name.firstName has the type (gender?: GenderType) => string, where type GenderType = 'female' | 'male' | 0 | 1;*.

    However, faker.name.gender has the type (binary?: boolean = false) => string. It can return quite a broad range of values:

    > faker.name.gender()
    'T* woman'
    > faker.name.gender()
    'Intersex'
    > faker.name.gender()
    'Cis'
    

    Unhelpfully, even if you set binary to true, what it returns is "Female" or "Male", neither of which is actually a GenderType:

    > faker.name.gender(true)
    'Male'
    > faker.name.gender(true)
    'Female'
    

    although there is some normalisation, so this works in JavaScript (but not TypeScript):

    > faker.name.firstName("Male")
    'Ilene'
    

    To make this work you'd have to add some type assertions, for example:

    import { faker, GenderType } from "@faker-js/faker";
    const gender = faker.name.gender(true).toLowerCase() as GenderType;
                                                      // ^ we know this will be true
    const name = faker.name.firstName(gender);
    

    or, if you want to work with the capitalised version, using the intrinisic string manipulation types:

    const gender = faker.name.gender(true) as "Female" | "Male";
                                        // ^ we know this will be true
    
    // ...
    
    const name = faker.name.firstName(gender.toLowerCase() as Lowercase<typeof gender>);
                                                        // ^ this is obviously true
                                                        //   (if ugly...)
    

    These seem awkward enough that I've opened a bug to explore whether it can be fixed upstream.

    (Also it looks like the string case typing is being explored in TypeScript, so maybe the as Lowercase won't be needed at some point.)


    * The numerical values are deprecated:

    > faker.name.firstName(0)
    [@faker-js/faker]: name.firstName(number) is deprecated since v6.1.0 and will be removed in v7.0.0. Please use 'female' or 'male' instead.
    'Forrest'