Closed
Description
Narrowing & Combining Higher Order Types
#21182
#15643
#19469
#14967
#15376
#18902
- We've been somewhat inconsistent about narrowing.
- "Well, we're consistent, but we don't narrow constraints."
- But sometimes we do intersections, sometimes we narrow unions, etc.
Today:
function f<T>(x: T) {
if (typeof x === "string") {
// 1: 'x' has type 'T & string' here.
}
if (x != null) {
// 2: nothing happens here
}
}
- At
1
, treating this as an intersection here is likely correct.- But the problem is that we're not sure that, when performing instantiation, you really want to absorb more general types to their more derived types (e.g.
number & 100
becomes100
) because this can affect contextual types, etc.- It seems like it's ostensibly okay for intersections; not necessarily for unions.
- You are strictly losing types from unions.
- It seems like it's ostensibly okay for intersections; not necessarily for unions.
- But the problem is that we're not sure that, when performing instantiation, you really want to absorb more general types to their more derived types (e.g.
- At
2
, you want to find a way to removenull
andundefined
.- Can use the
NonNullable
type helper within the compiler. - In fact, can use a lot of more general machinery
- Use lib conditional types for type facts if possible #22348
- Definitely worth experimenting with.
- Can use the
- Conclusion: not a 2.8-bound change, but let's experiment with using the user-land type operators.
Should we allow indexed access types on nullable
- Current PR allows you to access any branch in a union.
- Currently, you'll get different behavior if you index into a generic type parameter vs. its instantiation.
- Well, yeah.
- Maybe we should just give people a
!
type operator since that's what people originally asked for. - Conclusion?
- We have a solution now anyway; less change in the type system itself is more desirable.
- Hold off.
Type imports at arbitrary locations
// import * as _foo from "./foo";
// let x: typeof _foo;
let x: import("./foo");
// import { Foo } from "./foo";
// let y: Foo;
let y: import("./foo").Foo;
- What about confusion with the
import
operator that returns aPromise
?- Probably not that confusing.
- What about
esModuleInterop
.- Sounds like you're doomed to the same problems.
import("foo").default
forexport =
.
- Sounds like you're doomed to the same problems.
JSDoc type imports
- Just have people use
typedef
s with the new syntax.
/**
* @typedef {import("foo").default}
*/
- Hold off on any new syntax.
Generics in JSX
- Parsing is fine.
- Let's do this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment