Description
import type
Changes
- Can't use
typeof
type queries onimport type
.import type
only imported the type side of things! (as well as the namespace space)
- Now,
import type
imports the value meaning - it imports everything - but we'll report an error on anything whose usage would - Seems like
import type
is a misnomer.- Doesn't just import types!
- We also do
typeof import(...).SomeStuff
which is a special type of way to reference types. - What does Flow do?
- Does what
import type
originally does (only imports types), but the issue was marked as resolved and closed. - Flow has
import typeof
separately.
- Does what
- What about the fact that
import type
will now shadow values? -
import type { Promise } from "bluebird";
- Should have a test case for weird type-directed emit corner case.
- Needs to issue an error, and mark an import as used for values.
- Seems like the PR adds some overhead.
-
3%!?
-
Why? Well, whenever you reference an alias, we need to determine whether a module is transitively marked as
import
/export type
to know whether animport
is used in value position.// ./foo.ts let Foo = 100; export type { Foo }; // ./bar.ts import { Foo } from "./foo.js"; // Need to error here, but this requires deeper resolution. Foo;
-
Had a suggestion that anything that's exporting using
export type
can only be imported usingimport type
. -
Unclear if this is really the bottleneck - maybe several walks.
-
- Implementation stuff
- Could use a
SymbolFlags
and "don't do anything unlessSymbolFlags
is an alias. - Clear that we need to fix the performance issue.
- Could use a
- Conclusion: direction seems good, just need to make sure it's fast.
Optional Chaining with Non-Null Assertions
- What is the intended behavior?
- Depends on the intent?
a?.b!.c
currently means(a?.b!).c
which breaks the optional chain.- Could imagine that
!
is allowed as part of a chain, and is fully erased toa?.b.c
.
- We'd have to change how we parse to allow postfix
!
in a chain.- Both this case and element accesses.
- Weird that parens do something different for other type assertions:
(a?.b as Foo).c
. - Conclusion: approved new behavior - is a breaking change though!
Variance Measurements
- Observing different behaviors between errors reported on concrete types vs. conditional types.
- We measure conditional types as invariant in the
extends
position (the right side of theextends
).- We really don't know at the higher-order what they might do.
- The "right" thing to do is to mark them as unmeasurable.
- Making things "unmeasurable" means you need to do deep comparisons.
- If you did that, and had a
type Foo<T>
, andT
is used in theextends
position (the right side of theextends
), then every instantiation ofFoo
needs to be compared structurally.
- If you did that, and had a
- This means something could cause performance issues.
- Unmeasurable is more accurate, but slower.
- Invariant is less complete, but is faster.
- Will this matter?
- People started hitting similar issues with mapped types, and we fixed it by adding unmeasurable variance markers.
The promised T
Type
-
Why is this needed?
async function foo<T>(x: T) { return await x; } foo(Promise.resolve(100)); // has type 'Promise<Promise<T>>' - wrong!
- If
awaited T
was a thing,foo
would returnawaited T
, and when instantiated, would result inPromise<number>
.
- If
-
We started out talking about this in Adds 'awaited' type to better handle promise resolution and await #17077, but we said that it would be bad to special-case this behavior.
- Said we wanted to make a more generalized construct beyond just
Promise
s - The conditional type approach didn't work.
- Recursion limits.
- Weird issues with
Promise
assimilation. - Assignability doesn't work well.
- Said we wanted to make a more generalized construct beyond just
-
There's now a bunch of PRs that try to model
Promise.all
,Promise.any
, andPromise.allSettled
. -
But this is a whole new other kind of type.
- Also have to describe differences between conditional type relations vs. relations against this type.
-
What's the problem with
Promise.all
?- Today, `Promise.all((null! as Promise, null! as
- (@rbuckton please come back to this)
-
Is this a breaking change?
- An
async function
that returns the element access of a generic type, and we used to return the element type - now it'sawaited T[K]
. - RWC?
- Haven't tried.
- An
-
Why is this urgent?
-
Conclusion: need to assess community impact - RWC and DefinitelyTyped.