Prevent infering attributes and options from constructor parameters.

Review Request #13629 — Created March 12, 2024 and submitted — Latest diff uploaded

Information

Spina
master

Reviewers

When instantiating a class that uses generics, TypeScript will try to
infer a more specific type for the generics based on the arguments
provided to the constructor.

This can be useful (it's nice to have the proper HTMLElement subclass
for BaseView.el, for example), but it's a problem for model attributes
and for options, because those are usually provided as subset of all
available options.

As an example of where that breaks, if you define an interface of
available attributes for a model, and then instantiate the model with
constructor arguments providing only a subset of those attributes,
TypeScript will consider any other attributes in the interface to be
invalid.

The solution to this is to tell TypeScript not to infer more specific
types for attribute and option arguments. TypeScript 5.4 introduces a
handy NoInfer<T> type for this, but this is also simple enough to
backport into our types, retaining wider compatibility.

We now have type preservation for model attributes and
model/view/router/collection options, while allowing model and DOM
element attributes to be inferred.

Unit tests pass.

Verified this fixed instantiating a model with a subset of attributes
and then trying to access a default attribute.

Commits

Files