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

Evaluate simple template expressions #53907

Merged
merged 2 commits into from
May 15, 2023

Conversation

Andarist
Copy link
Contributor

fixes #53888

This PR builds on top of the simple fix available in #53903 . Since I think that it's not that unlikely that this other PR might be desirable while this one here might not be, I decided to open an extra PR with this change.

I don't think that the case presented in #53888 warrants the change but I can imagine that it's a simplification for the purpose of creating a minimal repro case. A more sane case could look smth like this:

const someCategory = 'main'
const someSubcategory = 'sub'

foo({ d: `${someCategory}-${someSubcategory}`, cb: x => {} });

Given that we are able to "evaluate" some constant values this PR would allow for simple variable reuse and composition of template expressions without losing the ability to discriminate objects etc

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Apr 19, 2023
@sandersn sandersn requested review from weswigham and gabritto May 2, 2023 23:01
@gabritto
Copy link
Member

gabritto commented May 5, 2023

@typescript-bot test this
@typescript-bot test top100
@typescript-bot user test this
@typescript-bot run dt
@typescript-bot perf test this faster
@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

Heya @gabritto, I'm starting to run the abridged perf test suite on this PR at 02b5df0. Hold tight - I'll update this comment with the log link once the build has been queued.

@typescript-bot
Copy link
Collaborator

Heya @gabritto, I'm starting to run the tarball bundle task on this PR at 02b5df0. Hold tight - I'll update this comment with the log link once the build has been queued.

@typescript-bot
Copy link
Collaborator

Heya @gabritto, I'm starting to run the parallelized Definitely Typed test suite on this PR at 02b5df0. Hold tight - I'll update this comment with the log link once the build has been queued.

@typescript-bot
Copy link
Collaborator

Heya @gabritto, I'm starting to run the diff-based user code test suite on this PR at 02b5df0. Hold tight - I'll update this comment with the log link once the build has been queued.

@typescript-bot
Copy link
Collaborator

Heya @gabritto, I'm starting to run the diff-based top-repos suite on this PR at 02b5df0. Hold tight - I'll update this comment with the log link once the build has been queued.

@typescript-bot
Copy link
Collaborator

Heya @gabritto, I'm starting to run the extended test suite on this PR at 02b5df0. Hold tight - I'll update this comment with the log link once the build has been queued.

@gabritto
Copy link
Member

gabritto commented May 5, 2023

I think in theory this is a good change (assuming the tests come back passing), the question is if it's worth the perf cost.

@gabritto
Copy link
Member

gabritto commented May 5, 2023

@typescript-bot test this
@typescript-bot test top100
@typescript-bot user test this
@typescript-bot run dt
@typescript-bot perf test this faster
@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 5, 2023

Heya @gabritto, I've started to run the parallelized Definitely Typed test suite on this PR at 02b5df0. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 5, 2023

Heya @gabritto, I've started to run the tarball bundle task on this PR at 02b5df0. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 5, 2023

Heya @gabritto, I've started to run the diff-based top-repos suite on this PR at 02b5df0. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 5, 2023

Heya @gabritto, I've started to run the diff-based user code test suite on this PR at 02b5df0. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 5, 2023

Heya @gabritto, I've started to run the extended test suite on this PR at 02b5df0. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 5, 2023

Heya @gabritto, I've started to run the abridged perf test suite on this PR at 02b5df0. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 5, 2023

Hey @gabritto, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/153951/artifacts?artifactName=tgz&fileId=DE5A96061A3950803531AF84D9DFCC089114B6A0673013CE79EEC4F7D4BA0BE902&fileName=/typescript-5.1.0-insiders.20230505.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/pr-build@5.1.0-pr-53907-15".;

@typescript-bot
Copy link
Collaborator

Heya @gabritto, I've run the RWC suite on this PR - assuming you're on the TS core team, you can view the resulting diff here.

@gabritto
Copy link
Member

gabritto commented May 5, 2023

I'm now also wondering if someone might be relying on things like const x = `${"a"}` having type string and not type "a". Let's see when the tests finish running, I guess.

@typescript-bot
Copy link
Collaborator

@gabritto Here are the results of running the user test suite comparing main and refs/pull/53907/merge:

There were infrastructure failures potentially unrelated to your change:

  • 1 instance of "Unknown failure"
  • 1 instance of "Package install failed"

Otherwise...

Everything looks good!

@typescript-bot
Copy link
Collaborator

@gabritto Here are the results of running the top-repos suite comparing main and refs/pull/53907/merge:

Everything looks good!

@typescript-bot
Copy link
Collaborator

Hey @gabritto, the results of running the DT tests are ready.
Everything looks the same!
You can check the log here.

@typescript-bot
Copy link
Collaborator

@gabritto
The results of the perf run you requested are in!

Here they are:

Comparison Report - main..53907

Metric main 53907 Delta Best Worst p-value
Angular - node (v16.17.1, x64)
Memory used 365,241k (± 0.01%) 365,297k (± 0.02%) +56k (+ 0.02%) 365,251k 365,399k p=0.020 n=6
Parse Time 3.54s (± 0.31%) 3.55s (± 0.66%) ~ 3.53s 3.59s p=0.366 n=6
Bind Time 1.18s (± 0.47%) 1.18s (± 0.64%) ~ 1.17s 1.19s p=0.137 n=6
Check Time 9.61s (± 0.22%) 9.60s (± 0.45%) ~ 9.53s 9.65s p=0.936 n=6
Emit Time 7.94s (± 0.88%) 8.01s (± 0.80%) ~ 7.92s 8.08s p=0.077 n=6
Total Time 22.26s (± 0.32%) 22.34s (± 0.49%) ~ 22.21s 22.47s p=0.126 n=6
Compiler-Unions - node (v16.17.1, x64)
Memory used 192,825k (± 0.03%) 192,762k (± 0.03%) ~ 192,691k 192,849k p=0.128 n=6
Parse Time 1.60s (± 1.52%) 1.61s (± 0.75%) ~ 1.59s 1.62s p=0.615 n=6
Bind Time 0.83s (± 0.66%) 0.83s (± 1.41%) ~ 0.82s 0.85s p=0.859 n=6
Check Time 10.31s (± 0.48%) 10.32s (± 0.54%) ~ 10.25s 10.40s p=0.629 n=6
Emit Time 3.02s (± 0.96%) 3.01s (± 0.59%) ~ 2.99s 3.04s p=0.683 n=6
Total Time 15.75s (± 0.23%) 15.77s (± 0.42%) ~ 15.68s 15.85s p=0.419 n=6
Monaco - node (v16.17.1, x64)
Memory used 345,869k (± 0.01%) 345,861k (± 0.01%) ~ 345,832k 345,890k p=0.378 n=6
Parse Time 2.73s (± 0.28%) 2.74s (± 0.58%) ~ 2.71s 2.76s p=0.196 n=6
Bind Time 1.09s (± 0.00%) 1.09s (± 0.37%) ~ 1.09s 1.10s p=0.405 n=6
Check Time 7.87s (± 0.39%) 7.89s (± 0.42%) ~ 7.85s 7.93s p=0.470 n=6
Emit Time 4.49s (± 0.59%) 4.51s (± 0.66%) ~ 4.47s 4.55s p=0.517 n=6
Total Time 16.18s (± 0.29%) 16.23s (± 0.30%) ~ 16.16s 16.28s p=0.169 n=6
TFS - node (v16.17.1, x64)
Memory used 300,114k (± 0.01%) 300,091k (± 0.01%) ~ 300,062k 300,129k p=0.173 n=6
Parse Time 2.16s (± 0.70%) 2.16s (± 0.76%) ~ 2.14s 2.18s p=0.325 n=6
Bind Time 1.23s (± 1.22%) 1.23s (± 1.22%) ~ 1.22s 1.26s p=1.000 n=6
Check Time 7.29s (± 0.52%) 7.30s (± 0.24%) ~ 7.27s 7.32s p=0.805 n=6
Emit Time 4.38s (± 0.55%) 4.39s (± 1.02%) ~ 4.34s 4.45s p=0.747 n=6
Total Time 15.07s (± 0.35%) 15.08s (± 0.40%) ~ 15.01s 15.15s p=0.420 n=6
material-ui - node (v16.17.1, x64)
Memory used 481,569k (± 0.01%) 481,649k (± 0.01%) +81k (+ 0.02%) 481,563k 481,702k p=0.031 n=6
Parse Time 3.24s (± 0.44%) 3.25s (± 0.56%) ~ 3.23s 3.28s p=0.324 n=6
Bind Time 0.94s (± 0.43%) 0.93s (± 0.55%) ~ 0.93s 0.94s p=0.112 n=6
Check Time 17.82s (± 0.43%) 17.90s (± 0.61%) ~ 17.75s 18.02s p=0.199 n=6
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) ~ 0.00s 0.00s p=1.000 n=6
Total Time 22.00s (± 0.39%) 22.08s (± 0.54%) ~ 21.92s 22.23s p=0.173 n=6
xstate - node (v16.17.1, x64)
Memory used 560,435k (± 0.02%) 560,369k (± 0.01%) ~ 560,320k 560,428k p=0.575 n=6
Parse Time 4.00s (± 0.32%) 4.03s (± 0.45%) +0.03s (+ 0.79%) 4.00s 4.05s p=0.023 n=6
Bind Time 1.76s (± 0.51%) 1.76s (± 0.31%) ~ 1.76s 1.77s p=0.341 n=6
Check Time 3.06s (± 0.70%) 3.08s (± 0.57%) ~ 3.06s 3.11s p=0.104 n=6
Emit Time 0.09s (± 0.00%) 0.09s (± 0.00%) ~ 0.09s 0.09s p=1.000 n=6
Total Time 8.91s (± 0.27%) 8.97s (± 0.24%) +0.06s (+ 0.64%) 8.94s 9.00s p=0.008 n=6
System
Machine Namets-ci-ubuntu
Platformlinux 5.4.0-148-generic
Architecturex64
Available Memory16 GB
Available Memory15 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v16.17.1, x64)
Scenarios
  • Angular - node (v16.17.1, x64)
  • Compiler-Unions - node (v16.17.1, x64)
  • Monaco - node (v16.17.1, x64)
  • TFS - node (v16.17.1, x64)
  • material-ui - node (v16.17.1, x64)
  • xstate - node (v16.17.1, x64)
Benchmark Name Iterations
Current 53907 6
Baseline main 6

Developer Information:

Download Benchmark

@gabritto
Copy link
Member

gabritto commented May 9, 2023

@weswigham do we have concerns with merging this?

@gabritto gabritto merged commit cb88998 into microsoft:main May 15, 2023
@Andarist Andarist deleted the evaluate-template-expressions branch May 15, 2023 22:23
@DanielRosenwasser
Copy link
Member

@Andarist
Copy link
Contributor Author

This PR is much smaller in scope. It doesn't infer template literal types for template literal expressions. Only string literals can be inferred from template literal expressions. If the evaluation ends up being impossible then evaluation just returns undefined and every code that follows that continues to work as before.

I looked through all the linked issues/PRs and I think that most of the concerns raised there were about template literal types.

For example, second bullet point from the bottom in #42416:

const x = `somestring`; // this is a literal type
const str = "string";
const y = `some${str}`; // and this is too! (but wasn't)

Inferring a template literal type here wouldn't be OK since it's not uncommon to push new items to the resulting array:

declare var srcSvgData: SvgData[];
interface SvgData {
  fileName: string;
  iconName: string;
}

const c = srcSvgData.map(
  (svgData) =>
    `<a href="./svg/${svgData.fileName}"><svg><use href="#${svgData.iconName}" xlink:href="#${svgData.iconName}"/></svg></a>`
);

// https://github.com/ionic-team/ionicons/blob/1543daa0103c9065805f7075b5dc6abd1c2dd9c1/scripts/build.ts#L262
c.push("somestring"); // should be ok

And the last one:

function usePxValue(px: `${string}px`) {}

let a = 12;
const lit = `${a}px`;
usePxValue(lit); // error, this makes sense though since `a` is mutable binding with a `number` type


const b = 12;
const lit2 = `${b}px`;
usePxValue(lit2); // this works though, it seems like a good thing

There is also an argument about makePx - that it would behave differently. This is true but then the argument wouldn't be generic so the input type wouldn't be preserved. Even if we make it generic - the return type would still be string since the generic signature can't determine how it will evaluate and if literal types are the only inputs given to this function.

This works though since the programmer encoded the specific intent for the return type and the argument is generic:

function makePx1<T extends string>(a: T) {
  return `${a}px` as const;
}

Maybe there is an argument to be made here that constness could propagate to this return expression automatically:

function makePx2<const T extends string>(a: T) {
  return `${a}px`; // this isn't const
}

I'm not precluding that there might be some edge cases here around widening but I don't know all of its intricate/delicate rules so it's hard for me to comment on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Contextual typing fails when discriminant is an interpolated template literal
5 participants