Skip to content

Allow super constrains for type parameters #7265

Closed

Description

I'd like to be able to express constraints in a generic function the opposite direction as extends. For example, I'd like to write something like:

class Foo {
    bar: number;
}
function send<T, Foo extends T>(overrides: T) {
}
send({ bar: "hello" }); // this should be a compile error

That is, T cannot have any fields not in Foo.

Activity

  1. RyanCavanaugh commented on Feb 26, 2016

    @RyanCavanaugh
    Member

    Is there a public API that follows this pattern?

  2. mhegazy commented on Feb 26, 2016

    @mhegazy
    Contributor

    This looks similar to #6613, see #7079 (comment)

  3. vsiao commented on Feb 26, 2016

    @vsiao

    Yeah, sounds like React's setState problem:

    class Component<Props, State> {
        setState<T, State extends T>(state: T);
    }
  4. chadaustin commented on Feb 27, 2016

    @chadaustin
    Author

    Indeed, very much like React's setState problem. In my particular case, I have the following function:

    export function make_model_from<T, U extends T>(instance: U, overrides: T) {
      let override_props = {} as any;
      for (let k in overrides) {
        override_props[k] = { enumerable: true, value: overrides[k] };
      }
      let rv = Object.create(instance, override_props);
      Object.freeze(rv);
      return rv;
    }
    

    That works wonderfully.

    But then I have a utility function built on top of make_model_from that allows specification of a constrained set of overrides:

        // I'd like to constrain overrides to so its fields are restricted to a subset of MessageModel.
        // I don't think you can spell that in TypeScript today.
        function send_message(overrides = null) {
          const new_message = make_model_from(message_model, overrides ? overrides : {});
    

    Does that make sense?

  5. mhegazy commented on Mar 28, 2016

    @mhegazy
    Contributor

    looks like what you want is a #6613 (comment)

    so your send_messafe would be something like:

    function send_message<T super typeof message_model>(overrides: T = null) {
       const new_message = make_model_from(message_model, overrides ? overrides : {});
    }
  6. changed the title [-]Constraining type parameter to a set of fields[/-] [+]Allow `super` constrains for type parameters[/+] on Mar 28, 2016
  7. RyanCavanaugh commented on May 9, 2016

    @RyanCavanaugh
    Member

    Tracking the general issue of setState / JSX property modifications at #7004 since these seem to be the same scenario

  8. joewood commented on Jul 27, 2016

    @joewood

    Ryan Cavanaugh (@RyanCavanaugh) not sure if #7004 is the same issue. That seems to be more about reusing the JSX TypeScript feature for Angular Templates.

    Support for optionality of React state (and other scenarios) seems to be close by using f-bounded polymorphism. The support doesn't seem consistent (it works in a function, but not in a method - see here for an example #6613 (comment)). Anders Hejlsberg (@ahejlsberg) suggests that this is by design in #7079, but I don't see how it does work in a regular function and not in a method. As I mention in #6613, this has become more of a pain in Typescript 2.0 because making your state members all optional forces massive code changes when using strict null checks.

  9. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions