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, 3/20/2020 #37501

Closed
DanielRosenwasser opened this issue Mar 20, 2020 · 0 comments
Closed

Design Meeting Notes, 3/20/2020 #37501

DanielRosenwasser opened this issue Mar 20, 2020 · 0 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Mar 20, 2020

Project References with External Build Systems (e.g. Bazel)

Guest Presenter: @alexeagle

#37257
#37378

  • What is Bazel?

    • Incremental build tool
    • Can do things in parallel, distributed, has smart handling for assets
  • Bazel integration is currently very tailored towards what Google used to do.

  • Idea: what if Bazel mostly just dished out to tsc?

  • Does Bazel do file-at-a-time? Someone heard Google did this.

    • No, does a package at a time.
  • Bazel does cross-compiles

    • Can have an outDir that targets a output/mac for builds on Macs.
    • Currenty this is specified via a command-line flag.
    • But TypeScript doesn't know where outputs come from in depenent projects because it doesn't even know where to look for input files when the current projects' files import from its dependency's outputs.
  • What about a tsconfig.mac.json that inherits from a tsconfig.base.json

    • We do this for release builds on TypeScript.
    • But that would add 6 tsconfig.jsons for each project.
    • These are just workarounds.
  • Current ideas?

    • "Environment variables" in tsconfig.json?
      • "outDir": "${BAZEL_OUT_DIR}"
        • Probably not gonna work, need to have things work well in the editor.
      • Maybe just allow users to turn off the incremental setting so that TypeScript
        • But you're still not going to find the respective input files based on the outputs.
          • That's the core problem.
  • Is this just a matter of running tsc against this and not doing a rebuild?

    • No
  • Have we considered adding configuration variables to tsconfig for different configurations? Something like this:

    // tsconfig.base.json
    {
      "vars": {
        "$default": "mac",
        "mac": {"out: "mac"},
        "win32": {"out": "win32"}
      },
      // ...
    }
    // lib/tsconfig.json
    {
      "base": "../tsconfig.base",
      "compilerOptions": {
        "outDir": "../out/${out}/lib"
      }
    }
    // app/tsconfig.json
    {
      "base": "../tsconfig.base",
      "compilerOptions": {
          "outDir": "../out/${out}/app"
      },
      "references": [
        { "path": "../lib" }
      ]
    }
    // cmd
    tsc -p app --vars mac
    tsc -p app --vars win32
    • React Native people might like this too?
  • Conclusion: Discuss whether this fits the bill and is in scope or it needs to be something else altogether

Update on awaited and strictAwaitedTypes

#35998

  • Made a couple of changes.
    • VS Code codebase uncovered inference issues.
  • Switched T | PromiseLike<T> from onfullfilled's return type.
    • Because of issues where inference is confused

      declare const p1: Promise<string>;
      declare const p2: Promise<number>;
      
      // inference fails
      p1.then(str => Math.random() < 0.5 ? str : p2);
    • Removing this had issues with compatibility with other Promises.

    • One solution is to add an overload back to the original type.

    • The other is a new inference strategy when inferring from awaited T to U | PromiseLike<U>.

      • This fixes most, if not all, of the breaks in custom promise implementations.
      • Is this like saying U | PromiseLike<U> collapses to U?
        • Only during inference.
        • More like saying it collapses to awaited (U | PromiseLike<U>) when inferring from awaited T.
      • Generally feels fine, but maybe the code could be changed.
        • Does this work for boolean?
        • Currently matches EXACTLY on T | PromiseLike<T>, fails on wider unions.
  • Also introduces strictAwaitedTypes which helps with a number of errors in user tests (e.g. fp-ts) and Promise-like implementations.
    • Problem is that await (null as any as Promise<T>) has the type awaited T, but a lot of existing code expects it to be T.
    • This is very very pedantic, and users were never able to say a generic definitely wasn't a PromiseLike in the first place so... they didn't, and not giving them an out would be very annoying.
    • We could also ship without the flag but leave things unsound.
  • We could ship the flag and have it not be part of --strict until the next release.
    • Lots of people in the room feel that if it has strict in the name, it should be under--strict
  • We want to know what the breakage is and not bother people.
  • If we had negated types, none of this would be an issue, but negated types would have cascading awfulness.
  • Conclusion: ship it without a flag in the beta, re-evaluate for the RC if the breaks are that bad.
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Mar 20, 2020
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