Closed
Description
This is a proposal for #4889 and a variety of other issues.
Use Cases
Many libraries, notably React, have a method which takes an object and updates corresponding fields on some other object on a per-key basis. It looks like this
function setState<T>(target: T, settings: ??T??) {
// ...
}
let obj = { a: 2, b: "ok", c: [1] };
setState(obj, { a: 4 }); // Desired OK
setState(obj, { a: "nope"}); // Desired error
setState(obj, { b: "OK", c: [] }); // Desired OK
setState(obj, { a: 1, d: 100 }); // Desired error
setState(obj, window); // Desired error
Observations
- The update is rarely recursive (an exception is Mongo's
query
); this is a "shallow" operation - It's not desirable to allow "new" properties to appear
- We're not looking for a supertype of some type (due to the non-recursive nature)
Unary partial T
operator
A type partial T
behaves as follows:
- Its properties are the same as the properties of
T
, except that those properties are now optional - A
S
type is only assignable to typepartial T
ifS
has at least one property in common withT
- Otherwise regular structural subtype/assignability rules apply
- The type
partial (T | U)
is equivalent to(partial T) | (partial U)
- The type
partial (T & U)
does not expand (this would interact poorly with rule 2) - Any type
T
is always a subtype ofpartial T
- The type
partial T
is equivalent toT
ifT
isany
,never
,null
, orundefined
More thoughts to come later, likely