mobxjs / mobx-state-tree

Full-featured reactive state management without the boilerplate
https://mobx-state-tree.js.org/
MIT License
6.94k stars 640 forks source link

[Need TypeScript help] Type inference with types.maybe doesn't make property optional #1970

Closed jamonholmgren closed 1 year ago

jamonholmgren commented 1 year ago

With this model definition:

const SomeStore = types.model("SomeStore", {
  someData: types.maybe(types.frozen())
});

interface SomeStoreType extends Instance<typeof SomeStore> {}

... someData should be optional when using the inferred type, but, but isn't.

const store: SomeStoreType = {
  // why do we need someData here
};

CodeSandbox

TypeScript Playground of minimal repro

This PR adds a test that demonstrates the issue. If we find a fix, we'll add it to this PR.

adamkovalsky commented 1 year ago

@jamonholmgren you could wrap the Instance type with a type mapper which makes all fields in the model which accept undefined optional, something like this:

type UndefinedIsOptional<Type> =
    & {
        [Prop in keyof Type as (undefined extends Type[Prop] ? Prop : never)]?: Type[Prop];
    }
    & {
        [Prop in keyof Type as (undefined extends Type[Prop] ? never : Prop)]: Type[Prop];
    }

type Model = {
    foo: number | undefined;
    bar: number;
};

const obj: UndefinedIsOptional<Model> = {
    bar: 5
};
coolsoftwaretyler commented 1 year ago

Hey folks, this PR is almost a year old and still just a failing test. I'm gonna go ahead and close it out to clean up our repo.

Happy to review a new PR that builds on this work and resolves it.

Thanks!