Mobx-state-tree: Using types.optional(Model, {}) with typescript will throw an error

Created on 11 Mar 2019  路  34Comments  路  Source: mobxjs/mobx-state-tree


_Question_

  • [] I've checked documentation and searched for existing issues
  • [] I tried the spectrum channel


I have a parent store. This parent store contains two child stores. I use types.optional(Model, {}) to set two child stores. Typescript will throw an error, as shown below.
image
image

Version
mobx: "4.9.2"
mobx-react: "5.4.3"
mobx-state-tree: "3.11.0"
typescript: "3.3.3333"

I use "cast" method or "castToSnapshot" method has no effect, the same will throw an #error.

Typescript never-stale question

Most helpful comment

I am having the same problem, this bug was introduced in v3.11.0.

const State = t
  .model('State', {
    ui: t.optional(UI, {}),
  })

const state = State.create({})

It says

Property 'ui' is missing in type '{}' but required in type

image

My tsconfig.json

{
  "compilerOptions": {
    // ...
    "strict": true,
    "strictNullChecks": false,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "skipLibCheck": true,
  },
}

It works fine with 3.10.2

All 34 comments

{} isn't a CustomSkillsModel, so you need a constructor for CustomSkillsModel there (or have actual static one. The solution you are likely looking for is () => CustomSkillsModel.create({}), but I don't know the rest of your codebase.

@ksjogo
The same problem, as shown below
image

The following picture is the details of the child store
image

and what is PagerModel

The following picture is the PagerModel @xaviergonz
image

image

no errors for me
do you have all strict checks enabled in your tsconfig.json?

Thanks very much! @xaviergonz

I have a question yet.
image
image

@xaviergonz property "skills" will throw an error

This worked for me:

test("", () => {
    const CustomSkillsModel = types.compose(
        types.model({
            pageNo: 1,
            pageSize: 15,
            totalCount: 0,            
        }), 
        types.model({
            skills: types.array(types.null)
        })
    )
    const MySkillModel = types.model({
        customSkill: types.optional(CustomSkillsModel, {})
    }).views(self => ({
        get isCustomAndPreEmtpy() {
            return self.customSkill.skills.length <= 0; // no errors here
        }
    }))
})

the (maybe) relevant part of my tsconfig.json

        "strict": true,
        "strictNullChecks": true,
        "strictFunctionTypes": true,
        "noImplicitAny": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,

I am having the same problem, this bug was introduced in v3.11.0.

const State = t
  .model('State', {
    ui: t.optional(UI, {}),
  })

const state = State.create({})

It says

Property 'ui' is missing in type '{}' but required in type

image

My tsconfig.json

{
  "compilerOptions": {
    // ...
    "strict": true,
    "strictNullChecks": false,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "skipLibCheck": true,
  },
}

It works fine with 3.10.2

Same here, mobx-state-tree version 3.12.1.

const MyDiagram = types
  .model('MyDiagram', {
    zoomFactor: types.optional(types.number, 50)
  });
MyDiagram.create({});  // <--- TS2345: ... Property 'zoomFactor' is missing in type '{}' ...
    "mobx": "^5.9.0",
    "mobx-state-tree": "^3.12.0",
    "typescript": "^3.3.3333"

image

and
image

Previous version

    "mobx": "^5.8.0",
    "mobx-state-tree": "^3.9.0",
    "typescript": "3.3.3"

image
image

Upgrade to version 3.12.2 just fine. great!

Upgrade to version 3.12.2 just fine. great!

Not so sure. I still have the same issue.

I'd enable strict null checks

This issue has been automatically marked as stale because it has not had recent activity in the last 10 days. It will be closed in 4 days if no further activity occurs. Thank you for your contributions.

bug is still present! stale bot is way too strict

This issue has been automatically unmarked as stale. Please disregard previous warnings.

I have the same problem. Very simple repro:


const Foo  = types.model({
    foo: types.maybe(types.string)
});

Foo.create({});
react/router/Router.tsx:154:12 - error TS2345: Argument of type '{}' is not assignable to parameter of type 'ExtractCFromProps<Pick<ModelPropertiesDeclarationToProperties<{ foo: IMaybe<ISimpleType<string>>; }>, "foo"> & Partial<Pick<ModelPropertiesDeclarationToProperties<{ foo: IMaybe<ISimpleType<string>>; }>, never>>>'.
  Property 'foo' is missing in type '{}' but required in type 'ExtractCFromProps<Pick<ModelPropertiesDeclarationToProperties<{ foo: IMaybe<ISimpleType<string>>; }>, "foo"> & Partial<Pick<ModelPropertiesDeclarationToProperties<{ foo: IMaybe<ISimpleType<string>>; }>, never>>>'.

154 Foo.create({});
               ~~

  react/router/Router.tsx:151:5
    151     foo: types.maybe(types.string)
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    'foo' is declared here.

It will be fixed after this pr is merged
https://github.com/mobxjs/mobx-state-tree/pull/1251

Well actually it depends on the tsconfig you have

@xaviergonz which compiler option breaks it?

The source of this bug is usually strict null checks being disabled (or some other strict option being disabled)

Anyway try v3.14.0, it removed create trying to be too smart to guess if the snapshot parameter should be present or not

Still seeing this in 3.14.0 and TS 3.4.2 with strict true and no other strict option specified.

Can you upload some repo project to github?

To be more specific, the type throw an error please check src/index.ts
https://codesandbox.io/s/ppqj7rmn37
image

That particular error is because IOptional now takes an array of values that are turned into the default value (usually [undefined])

@xaviergonz yes, fixed by adding [undefined] eg: IOptionalIType<ISimpleType<string>>, [undefined]> Not much an issue. Just wonder if second param should be optional?

Tried 3.14.0 one more round, still failing. strictNullChecks = false. Enabling that breaks a lot of other stuff in the project so cannot enable it.

Same for me, I don't think MST should depend on the user's compilerOptions to work correctly.

This issue has been automatically marked as stale because it has not had recent activity in the last 10 days. It will be closed in 4 days if no further activity occurs. Thank you for your contributions.

not again stale bot

This issue has been automatically unmarked as stale. Please disregard previous warnings.

this works for me in typescript:

accountStore: types.optional(AccountStoreModel, {} as typeof AccountStoreModel.Type),

note the "as typeof AccountStoreModel.Type" after {}

This worked for me:

test("", () => {
    const CustomSkillsModel = types.compose(
        types.model({
            pageNo: 1,
            pageSize: 15,
            totalCount: 0,            
        }), 
        types.model({
            skills: types.array(types.null)
        })
    )
    const MySkillModel = types.model({
        customSkill: types.optional(CustomSkillsModel, {})
    }).views(self => ({
        get isCustomAndPreEmtpy() {
            return self.customSkill.skills.length <= 0; // no errors here
        }
    }))
})

the (maybe) relevant part of my tsconfig.json

        "strict": true,
        "strictNullChecks": true,
        "strictFunctionTypes": true,
        "noImplicitAny": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,

I solved it after change the tsconfig.json. It worked!

Was this page helpful?
0 / 5 - 0 ratings