Ignoring undefined/null types fed into keyof
#51331
-
Intersections of undefined and object types get evaporated away.
type Foo = { x: string } | undefined;
type Bar = { y: string };
type FooAndBar = Foo & Bar;
// ^? { x: string } & Bar
// No `undefined` because `undefined & Bar` is `never`
-
Okay, what's the problem?
type Foo = { x: string } | undefined;
type Bar = { y: string };
type KF = keyof Foo;
type KB = keyof Bar;
type K1 = keyof (Foo & Bar);
// ^? "x" | "y"
type K2 = keyof Foo | keyof Bar;
// ^? "x"
-
Uh oh.
-
Could make the argument that keyof (T | undefined) should probably just be keyof T - if you have a type like keyof (T | undefined), being able to actually index into a T depends on actually being able to do something with the T itself.
-
You can already write (T | undefined)[keyof T] in type space without any issues. So the idea of (T | undefined)[keyof (T | undefined)] being allowed makes sense.
-
Are we sure we're not saving someone from a mistake?
- Feels like as long as you're preventing the indexing in the value space, that's where the value is.
-
Seems reasonable, we'd like to experiment with that.
-
[[Revisiting - the getProp function actually doesn't make enough guarantees for us to do this safely.]]
function getProp<T, K extends keyof T>(obj: T, key: K) {
return obj[key]; // allowed!
}
let obj: { foo: string } | undefined
getProp(obj, "foo"); // uh oh!
Node.js module interop changes
nodejs/node#50981
nodejs/node#50096
- Prologue directive to specify to Node what named exports a CommonJS provides.
- Node can't do the same analyses that bundlers perform, so this directive is intended to help here.
- Gives CJS modules a path forward for compat.
- Maybe not too bad because we serialize
__esModule markers.
- For our emit, specifying these when given as inputs would "just work" because we preserve all prologue directives.
- The fact that this is in a JavaScript file complicates things for us. We would need to see some sort of marker in the
.d.ts file.
- Or we would need to resolve the JavaScript file and scan prologue directives.
- Apart from the complications, we are not a big fan of adding more and more and more and more to try to fix CJS/ESM interop. Every fix is another edge case for devs. It continues to complicate the options and configuration people need to manage.
Ignoring
undefined/nulltypes fed intokeyof#51331
Intersections of undefined and object types get evaporated away.
Okay, what's the problem?
Uh oh.
Could make the argument that
keyof (T | undefined)should probably just bekeyof T- if you have a type likekeyof (T | undefined), being able to actually index into aTdepends on actually being able to do something with theTitself.You can already write
(T | undefined)[keyof T]in type space without any issues. So the idea of(T | undefined)[keyof (T | undefined)]being allowed makes sense.Are we sure we're not saving someone from a mistake?
Seems reasonable, we'd like to experiment with that.
[[Revisiting - the
getPropfunction actually doesn't make enough guarantees for us to do this safely.]]Node.js module interop changes
nodejs/node#50981
nodejs/node#50096
__esModulemarkers..d.tsfile.