Flow: Object.assign({}, objOfType) causes `property not found in object literal` error

Created on 18 May 2016  路  12Comments  路  Source: facebook/flow

flow 0.25
node 6.1.0

Is this expected behavior?

type MyType = {
  optional?: string
}

const test = function test(opts?: MyType = {}) {
  return Object.assign({ hi: 1 }, opts) // property `optional` of object type Property not found in object literal
}

Most helpful comment

There's still an issue with the result of Object.assign in this case:

type MyObj = {|
  one: number,
  two: number
|}
var x = { two: 2 }
var a: MyObj = Object.assign({}, { one: 1 }, x)
// object literal Inexact type is incompatible with exact type exact type: object type

All 12 comments

I'm having the same issue. It seems when doing Object.assign flow enforces all source fields to exist in the target, which makes no sense to me. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

+1 馃槩

Still present in 0.30

Strange, a work around for now seems to be:

- return Object.assign({ hi: 1 }, opts)
+ return Object.assign({}, { hi: 1 }, opts)

@thejameskyle That makes it pass, thanks!

We recently ran into this with React, where we use Object.assign on the prototype of an internal component to extend it from internal component.

Object.assign(ReactTestRenderer.prototype, ReactMultiChild);

Not sure if this is the same issue, but running into something similar with Object.assign. Example code:

// @flow
var myObj = { foo: 'blah' }

Object.assign(myObj, { wat: {} });

myObj.wat.bloo = 'blah';

console.log(myObj);

produces the following warning:

flowtest.js:6
  6: myObj.wat.bloo = 'blah';
           ^^^ property `wat`. Property not found in
  6: myObj.wat.bloo = 'blah';
     ^^^^^ object literal

Or is this intended behavior around object sealing?

Yup, this does have to do with object sealing, it's not really a bug.

There's a difference between empty objects and objects with one or more properties.

const obj1 = {}; // unsealed

obj1.foo = 1;       // Works!
obj1.bar = true;    // Works!
obj1.baz = 'three'; // Works!

const obj2 = { foo: 1 }; // sealed

obj2.bar = true;    // Error: Property not found in object literal
obj2.baz = 'three'; // Error: Property not found in object literal

[[Try](https://flowtype.org/try/#0PTAEAEDMBsHsHcBQiDGsB2BnALqWAjAKwEZQBeUAbwF8BuUEUAVywFMBDaVgE2QJIB0kWLHKhi9UFOmMA6rABOAa0wBCRP2ID87BWOwKmrSVLmKV6zdvYAvMQHJsACwWtW9+meVrkaLLn4AJjFKUGFYAC5xUDoGMEwOLl4NIkDrPQoDIxM40ABRBQVFKIAFIoAHVgVsAE9QdFhcYRZuUABLdDwiVhRcaDbsKs4UwjSdOwpHFzcPXIKihVKKqtr6xrDYFvbO-h6+gaHoRCA)]

Closing as this is not actually a bug.

There's still an issue with the result of Object.assign in this case:

type MyObj = {|
  one: number,
  two: number
|}
var x = { two: 2 }
var a: MyObj = Object.assign({}, { one: 1 }, x)
// object literal Inexact type is incompatible with exact type exact type: object type

@kmiyashiro That's a bug with exact types that's a known bug and mentioned in another issue.

Any way to extend this?

https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBjOA7AzgFzAFsBLADxOzAF4wAKAJzjnwC4wB5AIwCsBTDPgCUNAHydeA-ADoAhrlwkA5tkbN8AGjABvMF1kN2dEdXEByfQC8zYAL5CA3Ogwx5uMADFmO1GD9gsPHwGAFdBOAZ6EW1ffzjSClV8AAsSXEdYv1t0OPw+AmMfOLjA3DgYPml4JToUtOl9BmMMuOzsoA

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Macil picture Macil  路  47Comments

cletusw picture cletusw  路  52Comments

opensrcery picture opensrcery  路  88Comments

danvk picture danvk  路  73Comments

TylerEich picture TylerEich  路  49Comments