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, 9/8/2023 #55689

Closed
DanielRosenwasser opened this issue Sep 8, 2023 · 2 comments
Closed

Design Meeting Notes, 9/8/2023 #55689

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

Comments

@DanielRosenwasser
Copy link
Member

Recognizing Symbol.hasInstance in instanceof Narrowing

#55052

  • Previous discussion at Design Meeting Notes, 8/9/2023 #55325
  • TypeScript currently doesn't recognize anything about Symbol.hasInstance when performing an instanceof.
  • PR considers [Symbol.hasInstance]-declared methods that are declared as type guards.
  • When you do this, it changes narrowing very slightly.
    • Kind of merges the behavior of type predicates narrowing and narrowing via derivedness checks.
    • Specific exceptions regarding any.
  • Seems okay, just needs review.

Improve portability of resolution-mode assertions automatically emitted in nodenext

#55579

  • Now seeing /// <reference types="..." /> directives getting generated with resolution-mode="require" in declaration emit.
  • Not everyone is using the same TS version, resolution options.
  • Need to either make TS more lenient or generate these resolution-mode attributes appear less-often.
  • TypeScript will generate these /// <reference types /> directives to ensure broader compatibility for consumers.
  • When TypeScript encounters /// <reference types="chai" /> from an ES module, we try to do an import to chai, not find a . export in chai's package.json, and fall back to the CommonJS types anyway.
  • Could we just support resolution-mode regardless of any settings?
    • Probably, and could even for import type.
  • Very weird that the types compiler option doesn't support this.

Tracking Recursion Identity of Homomorphic Mapped Types Based On Their Target Symbol

#55638

type Id<T> = { [K in keyof T]: Id<T[K]> };

type Foo1 = Id<{ x: { y: { z: { a: { b: { c: number } } } } } }>;
type Foo2 = Id<{ x: { y: { z: { a: { b: { c: string } } } } } }>;

declare const foo1: Foo1;
const foo2: Foo2 = foo1;  // Errors with PR, previously didn't.
  • When tracking if Foo2 is compatible with Foo1, we would say "We saw Id<*Something*> too many times".

    • This was based on using the identity of Id itself when tracking recursive instantiation.
  • Now, if *Something* is a type with a symbol, we use that as the identity.

  • Breaks the raphael package on DefinitelyTyped. Can be fixed with in out.

    • Alternative fix is for these mapped types to be broken up into named types.
  • How does this work for nested mapped types?

    type Expand<T> = {
      [K in keyof T]: Expand<Expand<T[K]>>
    };
    • We drill through to find the identity.
    • Need a test case.
  • Technically you can still hit issues between non-identical mapped types.

Enabling fetch in Node.js

DefinitelyTyped/DefinitelyTyped#60924

  • The DOM has a global fetch function and a few related global classes.
  • As of Node 20, Node.js has a compatible global fetch.
  • They're compatible, but not identical.
  • This is a problem because a lot of users with front-end projects accidentically end up including Node's types - either via misconfiguration or a "rogue" package in node_modules.
  • Two solutions.
    • One is through a level of indirection where the global types extend aliases from Unici. They are conditionally extended from Undici based on whether the global scope includes some amount of information from the DOM.
      • Downside: hard dependency on Undici, which is fairly large as a package. 1MB because it doesn't just include types. Have to worry about versioning.
      • Technically, Undici is shipped within Node.js, but only kinda exposed. Similarly, fs.rm is actually rimraf under the hood. (!)
    • Alternatively, duplicate all the contents of fetch. About 600 lines, so not small.
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Sep 8, 2023
@DanielRosenwasser
Copy link
Member Author

@weswigham do you still have an example of where

Technically you can still hit issues between non-identical mapped types.

applies?

@thw0rted
Copy link

thw0rted commented Sep 11, 2023

This is a problem because a lot of users with front-end projects accidentically end up including Node's types

I don't want to nit-pick at all, but in case the intent of the above sentence is important: a lot of front-end projects intentionally include @types/node (usually transitively), because they want to use TS in build tooling that runs in Node -- think TS-flavored config files for Webpack, Jest, etc. Point being, any proposed solutions should assume that making TS "hide" @types/node in frontend projects will cause other problems.

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

3 participants