reactfire icon indicating copy to clipboard operation
reactfire copied to clipboard

Feature request: enforce generic types when passed to `ReactFireOptions`

Open Zombiefruit opened this issue 4 years ago • 0 comments

Enforce generic types when passed to ReactFireOptions, update various types

Hey guys, will try to keep this short. Right now ReactFireOptions is generic on T but the type of initialData, which should be only of_ type T is of type T | any.

export interface ReactFireOptions<T = unknown> {
  idField?: string;
  initialData?: T | any;
  /**
   * @deprecated use initialData instead
   */
  startWithValue?: T | any;
  suspense?: boolean;
}

The result of this is that the generic parameter is useless, as we don't get any type enforcement on initialData. For example, this is fine:

interface MyInterface {
    thing: string;
}

const foo: ReactFireOptions<MyInterface> = {
    initialData: {
        thing: 2 // no complaints
    }
}

My suggestion is to change ReactFireOptions to this:

export interface ReactFireOptions<T = any> {
  idField?: string;
  initialData?: T;
  /**
   * @deprecated use initialData instead
   */
  startWithValue?: T;
  suspense?: boolean;
}

This still allows users to pass whatever they want to initialData when not supplying a generic type, but will cause Typescript to complain when using a generic type and the value passed to initialData does not match the provided type.

interface MyInterface {
    thing: string;
}

const foo: ReactFireOptions<MyInterface> = {
    initialData: {
        thing: 2 // complains, "Type 'number' is not assignable to type 'string'."
    }
}

Additionally, there are a few places using { [key: string]: unknown }, which can be expressed more clearly with Record<string, unknown>.

I have a branch with the following changes but I can't push it as I don't have permissions. Not sure if I need to ask for them somewhere.

Cheers! Great project, and I'm finding it very useful.

Zombiefruit avatar Jun 06 '21 11:06 Zombiefruit