Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow super constrains for type parameters #7265

Closed
chadaustin opened this issue Feb 26, 2016 · 7 comments
Closed

Allow super constrains for type parameters #7265

chadaustin opened this issue Feb 26, 2016 · 7 comments
Labels
Duplicate An existing issue was already created

Comments

@chadaustin
Copy link

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.

@RyanCavanaugh
Copy link
Member

Is there a public API that follows this pattern?

@mhegazy
Copy link
Contributor

mhegazy commented Feb 26, 2016

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

@vsiao
Copy link

vsiao commented Feb 26, 2016

Yeah, sounds like React's setState problem:

class Component<Props, State> {
    setState<T, State extends T>(state: T);
}

@chadaustin
Copy link
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?

@mhegazy
Copy link
Contributor

mhegazy commented Mar 28, 2016

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 : {});
}

@mhegazy mhegazy added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Mar 28, 2016
@mhegazy mhegazy changed the title Constraining type parameter to a set of fields Allow super constrains for type parameters Mar 28, 2016
@RyanCavanaugh RyanCavanaugh added Duplicate An existing issue was already created and removed In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels May 9, 2016
@RyanCavanaugh
Copy link
Member

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

@joewood
Copy link

joewood commented Jul 27, 2016

@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)). @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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants