Skip to content

Design Meeting Notes, 8/17/2022 #50521

Closed
Closed

Description

Declaration Files for Non-JS-Extensioned Files

#50133

  • Lots of tools that have their own module system.
  • One place that we're lacking is support for files with non-JS extensions.
  • Node.js supports .node, .json, .wasm, and people've been able to create handlers for other file types like .graphql, .coffee, .ts, andmore.
  • What's TypeScript's support?
    • Could do path-mapping for *.css - doesn't work for relative imports.
    • You can use declare module "*.css".
    • Also, you can create a file called ./foo.css.d.ts
      • This works for extensionless imports - but not for Node16's mode.
  • Idea:
    • filename.ext

      maps to

      filename.d.ext.ts

  • Would this be flagged?
    • No, it would be done in any mode.
  • Recognized extensions are not
  • Why not filename.ext.d.ts
    • You could theoretically have filename.ext and filename.ext.js side-by-side. filename.ext.d.ts would then be leveraged as a declaration file for both of those.
  • Seems like this solves the individual case - doesn't solve the "all of my .css files are StyleSheet objects" scenarios
  • This seems like a pre-requisite for a world where we allow imports to .ts files.

Records and Tuples

https://github.com/tc39/proposal-record-tuple
#49243
#49243 (comment)

  • [[Overview]]
  • What precisely is the narrowing problem in the comment? Seems like a JS issue, not a TS issue.
    • Users wrote an interface expecting it to only model object types, not records.
    • That's a rethink of TypeScript's structural type system entirely.
  • In some ways things would be easier if everything was a special kind of object (i.e. typeof someRecord === "object")
    • Narrowing would work better.
    • Other stuff gets worse though.
      • Like what?
      • TypeScript should be able to tell you when you're putting a regular object into a record.
        • TypeScript should just always yell at you if you don't have something that's obviously (syntactically) a record being put in a record.
          • What? But then you can never refactor a record out and share it between other records.

            // Pretend /*#*/{ ... } is the notation for a record.
            
            function wrap(rec: { readonly someValue: string }) {
                // This has to fail now because we can't tell that 'rec' is a record?
                return /*#*/{ contents: rec };
            }
            
            let subRecord = /*#*/{ someValue: "hello" };
            wrap(subRecord);
          • Overly-restrictive.

          • Okay, fine, then we need some special way to indicate objects that are records.

            • Uh, so #{ } type notation?
            • How do you narrow those?
            • Seems like this still leads back to new kinds of types in TypeScript itself.
  • Also, a #{ } notation for types would be preferable since the intersection of a record type and a tuple should become vacuous.
    • [[Editor's note]]: uh should they?
      • We revisited this outside of the meeting and because of issues like spreads on generics producing intersections, this becomes possibly questionable.

        // Returns T & U
        function merge<T, U>(x: T, y: U) {
          return { ...x, ...y };
        }
        
        // This should not be 'never'.
        // So then it can't be 'object & record & { abc: number } & { def: number }' if object and record are disjoint.
        // It could be '{ abc: number } & #{ def: number }' if we have '#{}' types, but then how do we juggle these?
        merge({ abc: 123 }, #{ def: 456 });
  • Easy to go back-and-forth on the typeof behavior.
    • Array.isArray as a differentiator?
      • Not on tuples.
      • So much in the wild that might not work.
      • Sure, but lots of stuff that expects an iterable, not an array.
  • Leaning towards two new subtypes in TS that extend unknown
    • [[Editor's note]]: conversation after the meeting kind of went in circles of what works worse after you do this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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