skip to Main Content

This Options class has a factory function that returns a custom instance of the class. This is it:

export class Options {
  quadrant?: 1 | 2 | 3 | 4 = 1;
  static factory(options: Partial<Options>): Options {
    const defaults: Options = new Options();
    return {
      ...defaults,
      ...options,
    };
  }
}

And I’m trying to pass in an factory function argument that modifies the quadrant like this:

export const defaults = {
  quadrant: 2,
};

const responsive: Options = Options.factory({
  ...defaults,
});

And it produces this error:

Argument of type '{ quadrant: number; }' is not assignable to parameter of type 'Partial<Options>'.
  Types of property 'quadrant' are incompatible.
    Type 'number' is not assignable to type '1 | 2 | 3 | 4'.(2345)

Is there way to fix this?

2

Answers


  1. You can use a const assertion when initializing defaults so that the type checker infers a more specific type for it: in particular, the type of the quadrant property will be inferred as the literal type 2 instead of the wider number type:

    export const defaults = {
        quadrant: 2,
    } as const;
    /* const defaults: {
        readonly quadrant: 2;
    } */
    

    Which is enough to make your Options.factory() call work as expected:

    const responsive: Options = Options.factory({
        ...defaults,
    }); // okay
    

    Playground link to code

    Login or Signup to reply.
  2. If you hover over the defaults, you will see that the inferred type is number – you’ll see something like this:

    const defaults: { quadrant: number };
    

    There are 2 ways to deal with this issue. You can either cast the defaults as const, meaning the type will be as follows:

    export const defaults = { quadrant: 2 } as const;
    // the type is "defaults: { readonly quadrant: 2 }"
    

    The other way you can achieve what you want is actually type the defaults object so it’s not inferred:

    export const defaults = <Options>{ quadrant: 2 };
    // or
    export const defaults: Options = { quadrant: 2 };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search