facebook / flow

Adds static typing to JavaScript to improve developer productivity and code quality.
https://flow.org/
MIT License
22.07k stars 1.85k forks source link

Partial type does not accept plain empty object literal as a default #9069

Open insonifi opened 1 year ago

insonifi commented 1 year ago

Flow version: 214

Expected behavior

The partial type also accepts object literal as a default value since it is an extreme case where all properties were omitted <T>(Partial<T> = {}) => {}

Actual behavior

Flow throws an incompatible type error because the object literal is incompatible with {...T}. It can be circumvented by casting an any type to the object.

<T>(Partial<T> = ({}: any)) => {}

Flow try demo

gkz commented 1 year ago

Technically you can pass in empty as the type argument, and Partial<empty> is empty, and {} is not a valid value for empty

insonifi commented 1 year ago

The documentation:

This utility converts all of an object or interface's named fields to be optional, while maintaining all the object's other properties (e.g. exactness, variance).

I understand that there could only be an indexed type. Hence empty cannot be used for a partial type.

gkz commented 1 year ago

empty is a subtype of all types including interface {}

I agree what you are doing is what seems intuitive however

insonifi commented 1 year ago

What do you think is the idiomatic way to handle it, then?

gkz commented 1 year ago

There is no way to do that currently. What I'm saying is that what we are currently doing is technically correct and safe, however it obviously doesn't align with what people intuitively think should happen, so we should think about it.