Skip to content

Design Meeting Notes, 9/8/2023 #55689

Closed
Closed
@DanielRosenwasser

Description

@DanielRosenwasser

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design NotesNotes from our design meetings

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions