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, 9/25/2017 #18894

Closed
DanielRosenwasser opened this issue Oct 2, 2017 · 0 comments
Closed

Design Meeting Notes, 9/25/2017 #18894

DanielRosenwasser opened this issue Oct 2, 2017 · 0 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

Strict Function Types

  • When we have a generic object type (e.g. interface Foo<T, U> {}, we've made the assumption that T and U are covariant with respect to Foo.

    • We based this on the fact that when comparing parameter types in functions, we do a bivariant comparison.
    • Given this, relating type arguments covariantly should provide true positives, and we can fall back to a structural check when the check doesn't succeed.
  • However, now we are trying to introduce rules where parameters are (usually) strictly compared in a contravariant manner.

    • This means we can no longer make that assumption.
    • So what we do is we introduce two internal types, one which is a subtype of the other, and create two instantiations with each for each type parameter. We then do a structural comparison to see what the variance is based on relatability using each direction.
  • But there are places where this doesn't work out all that well.

    interface Event<T> {
      target: T;
    }
    interface Base {
      onChange(ev: Event<Base>): void;
    }
    interface Derived extends Base {
      onChange(ev: Event<Derived>): void;
    }
    • But this is not safe!
    • So you could do one of two things:
      • Say it's illegal, or declare these as readonly.
        interface Event<T> {
          target: T;
        }
        interface Base {
          writeonly onChange(ev: Event<Base>): void;
        }
        interface Derived extends Base {
          writeonly onChange(ev: Event<Derived>): void;
        }
  • Current working proposal is that under strictFunctionTypes, the only types that get stricter are ones declared using

    • Arrow-style function types (() => T)
    • Arrow-style constructor types (new () => T)
    • Function expressions (arrow or classic-style)
    • Function declarations
  • However that means that () => T will no longer be equivalent to { (): T } under these rules.

  • How plausible is it to turn this on by default?

    • Not. Only under --strict.
  • We will definitely have to go over DefinitelyTyped to make sure this works okay.

  • For our declaration emitter, we need to make sure we emit the correct types.

Different diagnostic severities for noUnusedLocals/noUnusedParameters

#15953

  • Want to be able to get warnings for these errors.
  • These features are anti-features anyway. These should be in a linter.
    • Too late, we're arguably in lint-like territory and are already doing this.
  • What about the info diagnostic?
    • One step at a time.
  • So type errors become warnings, and warnAsError on by default?
  • Out of time.
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

1 participant