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

Design Meeting Notes for 12/4/2015 #5943

Closed
DanielRosenwasser opened this issue Dec 5, 2015 · 1 comment
Closed

Design Meeting Notes for 12/4/2015 #5943

DanielRosenwasser opened this issue Dec 5, 2015 · 1 comment
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

Allow type parameter constraints to reference other type parameters (#2304)

  • Pre 1.0, used to be that we could allow you to write something like class Foo<T extends X, U extends T>

    • Had too many issues with infinitely diving in to types.
    • Disabled it, and so the TypeScript 1.1 rewrite had the same restriction.
    • Need to do some checking up front to avoid these circularities.
    • Though it's not that simple; what's the apparent type of T here?
    class Foo<T extends Foo<T>> {
    }

    though this is solved.

    • Where it gets interesting.
    function bar<T extends Foo<T>>(x: T): T {
    }

    when writing bar(expr), we expect to infer a types of T from expr.
    We then need to check the constraint for T against Foo<T>.

    • How should this work when inference fails?
    • Couldn't we just infer any when we can't resolve things?
      • Anders tried that, but then you end up inferring any for almost every type parameter of this form which is undesirable
    • We could resolve a failed inference for T extends Foo<T> with Foo<{}>
      • But that's not compatible.
      • Kind of weird to allow that.
      • But inference is never supposed to "fail", so what else can we do?
  • Inferring from union types

    function extract<T>(x: T | string): T { /*...*/ }
    
    var x: string | string[];
    var y = extract(x);
    • We decided to adopt the policy that we remove string from the union type and just infer string[] for T.
    • This is because the two types are identical.
    • What if we had a recursive call?
    function extract<T>(x: T | string): T {
        var z = extract(x);
    }
    * Right now we refer the type of `z` to be `{}`.
    * Changes to union type inference will make us infer the type of `z` to be `T`.
    
    • Regression caused by implicit type parameters

      class C {
      
      }
      var x: C;

      is implicitly of like writing

      class C<this> {
      
      }
      var x: C<C>;
      • Internally, C has type flags indicating that it is both a class and a reference (TypeFlags.Class and TypeFlags.Reference).
      • Internally, this is just represented by having 1 extra type argument than the number of type parameters.
      • Caused a regression.
      • Anders fixed it.
      • Did we add it to the real world code suite?
      • No.
      • We should.

Enum compatibility - continued (#1748)

  • Dicsussed it a bit last time.
  • Discussion from last time was inconclusive.
  • We have a request to make enums structurally compatible.
    • Why is this a problem?
    • Two packages that use the same enum from a .d.ts that they depend on.
    • TypeScript has this issue when using its own API as well as TSLint's.
    • Alternative is to consider some form of "tagging".
      • e.g. use some sort of GUID to indicate enums are compatible.
        • Weird - a very "opt-in" behavior.
        • This is often the desired default behavior.
          • If this needs to become common practice, it makes enums awkward and daunting.
        • Easy "gotcha".
    • What makes two enums "compatible"?
      • Same name?
        • That's odd.
        • We don't do that anywhere else.
      • Same property names?
        • Should those matter?
        • But what about when v2 of a library adds enum members to v1?
          • But it seems like those libraries aren't compatible anyway, so the two enums are incompatible.
        • What about when you want to supply a "public" version of your enum?
      • What about just the values?
        • Surprise! People hate that.
      • Being const enums with equivalent values?
        • But that leaves enums out in the rain.
        • Const enums can never have "floating dependency versions".
          • e.g. when writing a library for TypeScript that depends on TypeScript, you need to lock down on the version you compiled against.
          • Regular enums are better for this because you never have to think about this as long as the members still exist due to late binding.
      • If we used property names, we'd need to restrict the assignability of the individual members themselves.
        • What if each enum member had an implicit "parent"?
          • That way when comparing Direction.Right to Moral.Right, we need to check if Direction and Moral are structurally compatible as well.
      • What about directionality?
        • Is the one with fewer members assignable to the enum with more members?
        • What is the motivating example for directionality?
          • When depending on a library that depends on us where we've hidden part of our own API.
          • What if we had "enum merging" to split out public and private portions?
            • Team seems frightened by this, I will never bring this up again.
      • Order?
        • No, ordering is a red herring. Values are really what we're interested in.
      • Let's just get an implementation going so we can make decisions on that.
      • More or less, seems like we're interested in enums needing the same members with identical name/value pairs.
      • Lingering question: do we require the enum declaration name to be identical?
        • You don't want Volume and Weight to be compatible.
        • Weird that we recognize the value of nominal checking, but only want to apply it to enums.
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Dec 5, 2015
@weswigham
Copy link
Member

Team seems frightened by this, I will never bring this up again.

😨

@mhegazy mhegazy mentioned this issue Dec 7, 2015
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

2 participants