Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design Meeting Notes, 12/1/2023 #56641

Closed
DanielRosenwasser opened this issue Dec 2, 2023 · 0 comments
Closed

Design Meeting Notes, 12/1/2023 #56641

DanielRosenwasser opened this issue Dec 2, 2023 · 0 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Dec 2, 2023

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.
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Dec 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

2 participants