Better Type Inference Self-Referential Values
const Category = z.object({
get subcategories() {
// ~~~~~~~~~~~~~
// Subcategory implicitly has type 'any' because of circular
// resolution.
return z.array(Category);
}
});
- Zod and similar libraries are motivation here.
- While processing the object literal, we normally defer return types for
get accessors.
- But when validating the constraint, we start pulling on those very types.
- One idea: when we try to resolve a call that is already undergoing resolution, we say "don't check constraints".
- Why don't we disable constraint checking for all calls and do it in another pass?
- We're not always interested in just generating an error, we're often trying to grab the constraint for other information (e.g. if there's no candidates, we have to fix to the constraint).
- How does this affect overloads? Because this would affect how we choose overloads, right?
- Could we just return the original uninstantiated type parameter from the call when you detect this circularity?
- How would that work? Isn't that a type parameter leak?
- Yes, but the idea is there's an "outer" call and an "inner" call. The inner call would leak a type parameter (e.g.
T) and the outer call would instantiate it after inference.
- Scary, but maybe!
- Outstanding PRs are likely not quite what we're looking for, but may have a PR prototyping these ideas soon.
Better Type Inference Self-Referential Values
getaccessors.T) and the outer call would instantiate it after inference.