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.
We did make some changes to inferences for type parameters that occur in co/contravariant positions.
- Make error reporting a bit better.
declarefunctioninvoke<T>(f: (x: T)=>T,x: T): T;declarefunctionbar(s: string): string;declareconstfoo: "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.
Typed
call/bind/apply#27028
Idea here is that ~4 years ago, someone complained about
call/bind/applynot being typed.Didn't want to build it directly into the type.
Could have added this into the
Functioninterface, except that a lot of people were usingFunctionas 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
CallFunctionandNewableFunctionif something has a call signature or a construct signature.Should we be calling it
ConstructableFunctioninstead? It's more fitting given conventions andConstructableFunctionorConstructorFunctionmight conflict.thisis often a little bit funky though withbind.this, but they don't have an implicitthisparameter.strictThisPR from a while back.thisor not.this, but we can't easily make that assumption now that we're 5 years in.Despite all our expressiveness, we still need an "overload ladder" for
bind.thisbeing bound, with at most 1 parameter.bindtaking up to 4 arguments.(...args: T[]) => any).If you call
bindon an arrow function, what happens if you pass the first parameter.We did make some changes to inferences for type parameters that occur in co/contravariant positions.
Boolean literal freshness
#27042
booleannow becomes 4 different typestrueand freshfalse)trueand regularfalse)readonlydeclarations propagatereadonly foo = truein.d.tsfiles.Recursive Types
#14174
#26980