• 
      

    Prevent infering attributes and options from constructor parameters.

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

    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.

    Summary ID
    Prevent infering attributes and options from constructor parameters.
    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.
    c739a6462288347b58235e70090322eee98f1a04
    maubin
    1. Ship It!
    2. 
        
    david
    1. Ship It!
    2. 
        
    chipx86
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to master (1052872)