Skip to content

Design Meeting Notes, 9/14/2018 #27102

Closed
Closed
@DanielRosenwasser

Description

@DanielRosenwasser

Typed call/bind/apply

#27028

  • Idea here is that ~4 years ago, someone complained about call/bind/apply not being typed.

  • Didn't want to build it directly into the type.

  • Could have added this into the Function interface, except that a lot of people were using Function as a catch-all for function types, so things were relatively breaky.

  • Now, when we check for the "apparent type" of something (i.e. what members it has), we jump to CallFunction and NewableFunction if something has a call signature or a construct signature.

  • Should we be calling it ConstructableFunction instead? It's more fitting given conventions and

    • We were afraid that ConstructableFunction or ConstructorFunction might conflict.
    • We should check BigTSQuery.
  • this is often a little bit funky though with bind.

    • Methods in classes have a strongly-typed this, but they don't have an implicit this parameter.
    • We had a strictThis PR from a while back.
      • However, it ends up being a big break for interfaces where it's not clear if a given member uses this or not.
        • Maybe method syntax could hint that functions use this, but we can't easily make that assumption now that we're 5 years in.
        • If we could rewind time, we might change this.
      • We also saw a speed drop as a result of this - effectively, every type becomes generic if it uses method syntax.
  • Despite all our expressiveness, we still need an "overload ladder" for bind.

    • We usually see only this being bound, with at most 1 parameter.
    • Currently we have bind taking up to 4 arguments.
    • We also give one special overload for functions with single rest parameters (e.g. (...args: T[]) => any).
  • If you call bind on an arrow function, what happens if you pass the first parameter.

    • It just gets ignored.
  • We did make some changes to inferences for type parameters that occur in co/contravariant positions.

    • Make error reporting a bit better.
declare function invoke<T>(f: (x: T) => T, x: T): T;

declare function bar(s: string): string;

declare const foo: "a";

invoke(bar, foo);

invoke(bar, 100);

Boolean literal freshness

#27042

  • boolean now becomes 4 different types
    • 2 "fresh" Boolean types (fresh true and fresh false)
    • 2 regular Boolean types (regular true and regular false)
  • Means readonly declarations propagate readonly foo = true in .d.ts files.
    • Note that this is actually a breaking change. Now the declaration files may not work in 3.1.
  • Conclusion: Let's do this.

Recursive Types

#14174
#26980

  • The intuition is not possible to form object graphs with circularities unless you defer somehow (either via laziness or state).
  • Really there's no way to know if any arbitrary type will terminate.
  • We can have limited types of recursion in the compiler, but the problem isn't whether or not the type terminates, it's how computationally intensive and memory heavy the resolution is.
  • We have a meta-question: do we want people writing code like this?
    • The motivating scenarios that people have are legitimate, but achieving them with these types is not necessarily going to work well for library consumers.
  • Conclusion: we're not quite ready for this sort of thing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design NotesNotes from our design meetings

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions