0

Say I have a helper function to create text data in my fixture. The test data has a type definition of:

type Locomotive = {
  name: string;
  serialNumber: string;
  engine: Engine;
  model: Model;
  gauge: number;
};

type Engine = {
  fuel:  'COAL' | 'DIESEL' | 'ELECTRIC';
  size: number;
}

enum Model {
  BOMBADIER = 'Bombardier Transportation',
  FFESTINOG = 'Ffestiniog Railway',
  HORNBY = 'Hornby'
}

And my fixture generating function, using https://fakerjs.dev is:

import { faker } from '@faker-js/faker';

const getTrains = (count: number, defaultValues?: MockLocomotive): Locomotive[] =>
[...Array(count).keys()].map(index => {
  const { engine, ...otherDefaults } = defaultValues ?? {};
  return {
    name: faker.person.fullName(),
    serialNumber: `train${index}`,
    engine: {
      fuel: faker.helpers.arrayElement(['COAL', 'DIESEL', 'ELECTRIC']),
      size: faker.number.int({ min: 10, max: 99 }),
      ...engine,
    },
    model: faker.helpers.enumValue(Model),
    gauge: faker.number.int({ min: 100, max: 120 }),
  ...otherDefaults
  };
});

console.log(getTrains(2, {engine: {fuel: 'COAL'}}))

I've tried making the type of defaultValues:

interface MockLocomotive extends Omit<Partial<Locomotive>, 'engine | name'> {
 engine?: Partial<Engine>,
 name?: string,
}

When I try to debug using this playground setup, I get this error on MockLocomotive:

Interface 'MockLocomotive' incorrectly extends interface 'Omit<Partial<Locomotive>, "engine | name">'.
  Types of property 'engine' are incompatible.
    Type 'Partial<Engine> | undefined' is not assignable to type 'Engine | undefined'.
      Type 'Partial<Engine>' is not assignable to type 'Engine'.
        Types of property 'fuel' are incompatible.
          Type '"COAL" | "DIESEL" | "ELECTRIC" | undefined' is not assignable to type '"COAL" | "DIESEL" | "ELECTRIC"'.
            Type 'undefined' is not assignable to type '"COAL" | "DIESEL" | "ELECTRIC"'.

I don't know if this is exactly the same issue as in my real scenario, but it seems close enough that someone might be able to help. Of note, is the fact that if I don't omit 'name' I don't get the error...

AncientSwordRage
  • 7,086
  • 19
  • 90
  • 173
  • Should this be tagged with faker.js? If not then could you change your example not to depend on it? Also, it's kind of weird to have a code example that explicitly does not reproduce the problem. If you can't share your actual code, maybe you should spend more effort producing an actual [mre]? Otherwise I'm not sure how to help; I don't want to waste either of our time making random guesses about what could be wrong with something I can't see. – jcalz May 30 '23 at 14:33
  • @jcalz yeah it's weird... Initially I didn't have the playground link, then I decided to make one to check... and it's not errored...? – AncientSwordRage May 30 '23 at 14:48
  • @jcalz I managed to recreate the error. – AncientSwordRage May 30 '23 at 14:52
  • `'engine | name'` ≠ `'engine' | 'name'` – jcalz May 30 '23 at 14:54
  • So is that the actual underlying issue or is your playground link not reflective of your proprietary/encumbered code problem? – jcalz May 30 '23 at 15:03
  • 1
    @jcalz that was the issue – AncientSwordRage May 30 '23 at 15:24

0 Answers0