Repository navigation
Loss of type inference converting to named parameters object #29791
Description
Activity
DanielRosenwasser commented
on Feb 7, 2019 MemberMore actionsSo it's late and I haven't played around with this deeply, but I think this is likely because we defer contextual typing on "contextually sensitive" arguments to get better inferences from non-sensitive arguments. In your first example, that non-sensitive argument is usually passed in for the
stateparameter.In your refactored version, there's no other argument to try first for better inferences. Any callback for
mutationswill pull on the type ofState, causing inference to fix that type parameter - basically freezing the inference process for aStateand going with whatever it's inferred so far. Since no inference candidates have been found, it goes with the constraint ofState({}by default, as you're seeing here).But in short, we can no longer utilize this concept of "contextually sensitive arguments" with named parameter patterns. I wonder if there's a world where you could imagine contextually sensitive properties?
Reacted by SlurpTheoDanielRosenwasser commented
on Feb 7, 2019 MemberMore actionsWe've run into this issue before. It works with discrete parameters because we specifically arrange to allow inferences from previous parameters to be fixed and applied in subsequent parameters in a left-to-right manner. Once you convert to a single parameter there is no longer a left-to-right phasing of the inferences. We could explore some sort of one-property-at-a-time scheme for object literals, but it gets complicated because they can be arbitrarily nested. Furthermore, it seems somewhat more suspect to have a left-to-right ordering dependency in object literals since there really isn't a way (nor should there be) for an API to indicate such a requirement.
Reacted by Nurbol Alpysbayev and SlurpTheoThank you both for the insights. So if I change the order of the parameters in
separateParamsthen it behaves just likenamedParamsObj, with impaired type inference (playground link).I take it this left-to-right order-dependence exists to simplify tsc's implementation? Because order shouldn't matter for type inference in principle, right?
Reacted by SlurpTheo- addedDesign LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixed
on Feb 14, 2019 RyanCavanaugh commented
on Feb 14, 2019 MemberMore actionsTroy Gerwien (@yortus) order matters in the absence of a full unification algorithm. Consider something like this, where the type parameters create a full circular dependency graph but we're still able to do the right thing:
function chain<I, R1, R2>(arg: I, f1: (arg: I) => R1, f2: (r: R1) => R2, f3: (r: R2) => I): I { return f3(f2(f1(arg))); } chain( new Date(), p => p.toString(), s => s.length, n => new Date(n));
Reacted by SlurpTheo- added a commit that references this issue
on Jan 10, 2020
Working on a strongly-typed wrapper for vuex modules, I've encountered an issue where I can't get type inference to work if I use a named parameters object, but it works perfectly if I use separate parameters.
The following is a cut-down repro showing two functions that are identical apart from how they take their parameters. I'd really prefer to use the named parameters object approach but no matter what I've tried, I can't get the type inference to work like it does with separate parameters. So for now I'm just having to pass separate parameters with comment labels (as shown below), which is far from ideal.
I'd like to know whether this is a bug, or I'm failing to understand some subtlety that accounts for the different treatment of tsc of separate parameters vs named parameter objects. If this behaviour is intended, is there any way to use named parameter objects without losing type inference?
TypeScript Version: 3.4.0-dev.20190206
Search Terms: named parameters object
Code
Expected behavior:
Same type inference for both
separateParamsandnamedParamsObj.Actual behavior:
separateParamsis perfectly typed. But type inference is much less useful innamedParamsObjdespite its almost identical looking declaration.Playground Link: here
Related Issues: