Skip to content

Template literal types for template literal expressions - #41891

Merged
ahejlsberg merged 11 commits into
masterfrom
fix41631
Dec 12, 2020
Merged

Template literal types for template literal expressions#41891
ahejlsberg merged 11 commits into
masterfrom
fix41631

Conversation

@ahejlsberg

@ahejlsbergahejlsberg commented Dec 9, 2020

Copy link
Copy Markdown
Member

With this PR we infer template literal types for template literal expressions. The PR adheres to the same principles as those of literal types in #10676 and widening vs. non-widening literal types in #11126. For example:

constn: number=123;consts1=`${n}px`;// `${number}px`consts2: `${number}px` =s1;consts3: `${number}pt` =s1;// Errorletv1=s1;// string (because of widening)

As it is generally a breaking change for us to more strongly type anything, I'm marking this as a breaking change. In practice, the breaks appear to be rare and easy to fix.

Fixes#41631.

@DanielRosenwasserDanielRosenwasser left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation looks good apart from the API stuff.

Comment threadsrc/compiler/types.ts
Comment threadsrc/compiler/types.ts
@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

@typescript-bot test this
@typescript-bot user test this
@typescript-bot run dt
@typescript-bot perf test this

@typescript-bot

typescript-bot commented Dec 9, 2020

Copy link
Copy Markdown
Contributor

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

@typescript-bot

typescript-bot commented Dec 9, 2020

Copy link
Copy Markdown
Contributor

Heya @ahejlsberg, I've started to run the perf test suite on this PR at 96885c3. You can monitor the build here.

Update: The results are in!

@typescript-bot

typescript-bot commented Dec 9, 2020

Copy link
Copy Markdown
Contributor

Heya @ahejlsberg, I've started to run the extended test suite on this PR at 96885c3. You can monitor the build here.

@typescript-bot

typescript-bot commented Dec 9, 2020

Copy link
Copy Markdown
Contributor

Heya @ahejlsberg, I've started to run the parallelized community code test suite on this PR at 96885c3. You can monitor the build here.

@typescript-bot

Copy link
Copy Markdown
Contributor

The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master.

@typescript-bot

Copy link
Copy Markdown
Contributor

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

Here they are:

Comparison Report - master..41891

Metricmaster41891DeltaBestWorst
Angular - node (v10.16.3, x64)
Memory used344,449k (± 0.02%)345,034k (± 0.02%)+584k (+ 0.17%)344,903k345,188k
Parse Time1.99s (± 0.73%)1.98s (± 0.53%)-0.01s (- 0.25%)1.96s2.01s
Bind Time0.83s (± 0.41%)0.83s (± 0.81%)0.00s ( 0.00%)0.82s0.85s
Check Time4.95s (± 0.50%)4.97s (± 0.43%)+0.02s (+ 0.44%)4.94s5.02s
Emit Time5.32s (± 0.51%)5.34s (± 0.56%)+0.02s (+ 0.39%)5.28s5.43s
Total Time13.08s (± 0.33%)13.12s (± 0.40%)+0.04s (+ 0.31%)13.04s13.26s
Compiler-Unions - node (v10.16.3, x64)
Memory used205,378k (± 0.02%)205,380k (± 0.07%)+1k (+ 0.00%)204,860k205,516k
Parse Time0.79s (± 0.92%)0.79s (± 0.74%)-0.00s (- 0.63%)0.78s0.80s
Bind Time0.50s (± 1.17%)0.50s (± 1.17%)0.00s ( 0.00%)0.49s0.51s
Check Time11.87s (± 0.43%)12.00s (± 0.62%)+0.13s (+ 1.05%)11.79s12.15s
Emit Time2.33s (± 1.05%)2.36s (± 1.19%)+0.03s (+ 1.38%)2.30s2.44s
Total Time15.49s (± 0.42%)15.64s (± 0.59%)+0.15s (+ 0.97%)15.38s15.84s
Monaco - node (v10.16.3, x64)
Memory used354,918k (± 0.02%)354,811k (± 0.02%)-108k (- 0.03%)354,579k354,965k
Parse Time1.60s (± 0.51%)1.60s (± 0.63%)-0.01s (- 0.44%)1.57s1.61s
Bind Time0.72s (± 0.83%)0.73s (± 0.84%)+0.01s (+ 0.83%)0.72s0.74s
Check Time5.09s (± 0.28%)5.12s (± 0.49%)+0.04s (+ 0.73%)5.07s5.16s
Emit Time2.80s (± 0.67%)2.80s (± 0.55%)0.00s ( 0.00%)2.78s2.84s
Total Time10.22s (± 0.25%)10.25s (± 0.37%)+0.04s (+ 0.35%)10.15s10.33s
TFS - node (v10.16.3, x64)
Memory used307,937k (± 0.03%)307,862k (± 0.02%)-75k (- 0.02%)307,714k308,015k
Parse Time1.24s (± 0.59%)1.24s (± 0.48%)-0.00s (- 0.24%)1.22s1.25s
Bind Time0.67s (± 1.23%)0.68s (± 0.85%)+0.01s (+ 0.89%)0.67s0.69s
Check Time4.58s (± 0.54%)4.59s (± 0.27%)+0.00s (+ 0.07%)4.56s4.62s
Emit Time2.93s (± 0.96%)2.95s (± 0.63%)+0.02s (+ 0.65%)2.92s3.01s
Total Time9.43s (± 0.32%)9.45s (± 0.28%)+0.02s (+ 0.25%)9.41s9.54s
material-ui - node (v10.16.3, x64)
Memory used489,542k (± 0.01%)489,806k (± 0.02%)+264k (+ 0.05%)489,643k489,947k
Parse Time2.06s (± 0.63%)2.05s (± 0.54%)-0.00s (- 0.10%)2.03s2.08s
Bind Time0.65s (± 0.99%)0.65s (± 1.03%)-0.01s (- 0.77%)0.63s0.66s
Check Time13.56s (± 0.51%)13.54s (± 0.47%)-0.02s (- 0.17%)13.43s13.73s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time16.26s (± 0.43%)16.23s (± 0.40%)-0.03s (- 0.18%)16.12s16.43s
Angular - node (v12.1.0, x64)
Memory used322,311k (± 0.02%)322,786k (± 0.04%)+475k (+ 0.15%)322,385k323,011k
Parse Time1.96s (± 0.48%)1.96s (± 0.70%)+0.01s (+ 0.31%)1.94s2.01s
Bind Time0.81s (± 0.69%)0.81s (± 1.23%)+0.01s (+ 0.62%)0.79s0.84s
Check Time4.87s (± 0.36%)4.92s (± 1.02%)+0.05s (+ 1.03%)4.84s5.10s
Emit Time5.48s (± 0.76%)5.47s (± 0.44%)-0.01s (- 0.09%)5.44s5.54s
Total Time13.11s (± 0.39%)13.17s (± 0.51%)+0.06s (+ 0.42%)13.07s13.40s
Compiler-Unions - node (v12.1.0, x64)
Memory used191,517k (± 0.05%)191,391k (± 0.10%)-126k (- 0.07%)190,988k191,625k
Parse Time0.77s (± 0.52%)0.77s (± 0.62%)+0.00s (+ 0.52%)0.76s0.78s
Bind Time0.49s (± 1.01%)0.50s (± 0.60%)+0.00s (+ 0.61%)0.49s0.50s
Check Time10.63s (± 0.81%)10.68s (± 0.69%)+0.05s (+ 0.47%)10.54s10.85s
Emit Time2.35s (± 0.41%)2.35s (± 1.16%)+0.00s (+ 0.13%)2.30s2.41s
Total Time14.25s (± 0.57%)14.30s (± 0.51%)+0.06s (+ 0.40%)14.18s14.51s
Monaco - node (v12.1.0, x64)
Memory used336,986k (± 0.02%)336,973k (± 0.02%)-12k (- 0.00%)336,809k337,146k
Parse Time1.57s (± 0.79%)1.58s (± 0.73%)+0.01s (+ 0.45%)1.56s1.62s
Bind Time0.71s (± 0.91%)0.71s (± 0.87%)+0.00s (+ 0.14%)0.70s0.72s
Check Time4.90s (± 0.41%)4.90s (± 0.35%)+0.01s (+ 0.16%)4.86s4.95s
Emit Time2.86s (± 0.62%)2.86s (± 0.87%)-0.00s (- 0.07%)2.83s2.94s
Total Time10.04s (± 0.34%)10.05s (± 0.38%)+0.01s (+ 0.14%)9.96s10.13s
TFS - node (v12.1.0, x64)
Memory used292,164k (± 0.02%)292,154k (± 0.01%)-10k (- 0.00%)292,081k292,264k
Parse Time1.24s (± 0.45%)1.25s (± 0.53%)+0.01s (+ 0.64%)1.24s1.27s
Bind Time0.65s (± 0.91%)0.65s (± 1.26%)0.00s ( 0.00%)0.64s0.68s
Check Time4.49s (± 0.77%)4.51s (± 0.54%)+0.01s (+ 0.31%)4.46s4.57s
Emit Time2.96s (± 0.64%)2.98s (± 0.62%)+0.02s (+ 0.68%)2.92s3.00s
Total Time9.34s (± 0.57%)9.39s (± 0.42%)+0.05s (+ 0.49%)9.31s9.46s
material-ui - node (v12.1.0, x64)
Memory used467,478k (± 0.05%)467,354k (± 0.09%)-124k (- 0.03%)466,592k467,968k
Parse Time2.07s (± 0.39%)2.07s (± 0.42%)-0.00s (- 0.10%)2.05s2.09s
Bind Time0.64s (± 0.73%)0.65s (± 0.90%)+0.01s (+ 1.09%)0.63s0.66s
Check Time11.97s (± 0.42%)12.25s (± 1.43%)+0.28s (+ 2.36%)11.89s12.62s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time14.68s (± 0.35%)14.97s (± 1.21%)+0.29s (+ 1.95%)14.61s15.33s
Angular - node (v8.9.0, x64)
Memory used347,151k (± 0.02%)347,682k (± 0.01%)+531k (+ 0.15%)347,601k347,787k
Parse Time2.51s (± 0.34%)2.51s (± 0.53%)+0.00s (+ 0.16%)2.49s2.55s
Bind Time0.86s (± 0.67%)0.86s (± 0.81%)+0.00s (+ 0.12%)0.84s0.87s
Check Time5.60s (± 0.58%)5.61s (± 0.34%)+0.01s (+ 0.25%)5.55s5.64s
Emit Time6.29s (± 1.68%)6.36s (± 0.69%)+0.07s (+ 1.13%)6.26s6.45s
Total Time15.26s (± 0.84%)15.35s (± 0.37%)+0.09s (+ 0.59%)15.22s15.47s
Compiler-Unions - node (v8.9.0, x64)
Memory used213,067k (± 0.02%)213,162k (± 0.02%)+94k (+ 0.04%)213,041k213,329k
Parse Time0.95s (± 0.78%)0.95s (± 0.23%)+0.00s (+ 0.11%)0.95s0.96s
Bind Time0.57s (± 1.17%)0.57s (± 1.27%)+0.00s (+ 0.35%)0.56s0.59s
Check Time14.51s (± 0.91%)14.57s (± 0.73%)+0.06s (+ 0.43%)14.33s14.74s
Emit Time2.75s (± 1.87%)2.72s (± 2.02%)-0.03s (- 0.95%)2.59s2.78s
Total Time18.77s (± 0.88%)18.82s (± 0.76%)+0.04s (+ 0.22%)18.55s19.00s
Monaco - node (v8.9.0, x64)
Memory used358,757k (± 0.01%)358,739k (± 0.01%)-18k (- 0.01%)358,628k358,845k
Parse Time1.93s (± 0.40%)1.93s (± 0.39%)-0.00s (- 0.16%)1.91s1.95s
Bind Time0.91s (± 0.68%)0.91s (± 0.57%)0.00s ( 0.00%)0.89s0.92s
Check Time5.63s (± 0.51%)5.61s (± 0.47%)-0.02s (- 0.32%)5.56s5.70s
Emit Time3.42s (± 0.69%)3.40s (± 0.59%)-0.02s (- 0.53%)3.35s3.45s
Total Time11.89s (± 0.34%)11.86s (± 0.30%)-0.04s (- 0.33%)11.79s11.95s
TFS - node (v8.9.0, x64)
Memory used310,532k (± 0.02%)310,485k (± 0.01%)-47k (- 0.02%)310,423k310,582k
Parse Time1.57s (± 0.49%)1.56s (± 0.31%)-0.01s (- 0.45%)1.56s1.58s
Bind Time0.69s (± 0.58%)0.68s (± 0.54%)-0.00s (- 0.58%)0.68s0.69s
Check Time5.33s (± 0.67%)5.30s (± 0.63%)-0.03s (- 0.49%)5.25s5.42s
Emit Time2.98s (± 0.88%)2.96s (± 1.05%)-0.02s (- 0.54%)2.88s3.01s
Total Time10.56s (± 0.50%)10.51s (± 0.56%)-0.05s (- 0.50%)10.40s10.68s
material-ui - node (v8.9.0, x64)
Memory used496,643k (± 0.01%)496,986k (± 0.01%)+343k (+ 0.07%)496,907k497,068k
Parse Time2.48s (± 0.40%)2.48s (± 0.38%)+0.00s (+ 0.12%)2.46s2.50s
Bind Time0.80s (± 0.83%)0.81s (± 1.32%)+0.01s (+ 0.75%)0.79s0.84s
Check Time18.10s (± 0.60%)18.21s (± 0.56%)+0.11s (+ 0.59%)18.01s18.46s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time21.38s (± 0.56%)21.50s (± 0.52%)+0.12s (+ 0.55%)21.28s21.77s
Angular - node (v8.9.0, x86)
Memory used199,086k (± 0.02%)199,390k (± 0.02%)+304k (+ 0.15%)199,313k199,468k
Parse Time2.42s (± 0.51%)2.43s (± 0.65%)+0.01s (+ 0.41%)2.39s2.46s
Bind Time1.02s (± 0.91%)1.01s (± 0.47%)-0.01s (- 0.49%)1.00s1.02s
Check Time5.04s (± 0.38%)5.06s (± 0.50%)+0.02s (+ 0.36%)5.02s5.12s
Emit Time6.11s (± 0.91%)6.10s (± 0.56%)-0.01s (- 0.15%)6.05s6.18s
Total Time14.59s (± 0.39%)14.60s (± 0.37%)+0.01s (+ 0.10%)14.51s14.71s
Compiler-Unions - node (v8.9.0, x86)
Memory used128,101k (± 0.04%)128,182k (± 0.03%)+82k (+ 0.06%)128,084k128,279k
Parse Time0.97s (± 0.97%)0.96s (± 0.86%)-0.00s (- 0.31%)0.95s0.99s
Bind Time0.49s (± 1.26%)0.49s (± 1.36%)+0.00s (+ 0.41%)0.48s0.51s
Check Time13.70s (± 0.45%)13.67s (± 0.46%)-0.02s (- 0.17%)13.47s13.77s
Emit Time2.61s (± 0.83%)2.62s (± 0.50%)+0.01s (+ 0.19%)2.58s2.64s
Total Time17.77s (± 0.38%)17.75s (± 0.37%)-0.02s (- 0.12%)17.57s17.87s
Monaco - node (v8.9.0, x86)
Memory used203,246k (± 0.03%)203,238k (± 0.02%)-8k (- 0.00%)203,123k203,318k
Parse Time1.98s (± 1.09%)1.96s (± 0.33%)-0.02s (- 0.91%)1.95s1.98s
Bind Time0.72s (± 0.51%)0.71s (± 0.69%)-0.00s (- 0.28%)0.71s0.73s
Check Time5.74s (± 1.55%)5.76s (± 0.84%)+0.02s (+ 0.38%)5.67s5.88s
Emit Time2.81s (± 3.31%)2.78s (± 1.67%)-0.03s (- 1.03%)2.71s2.92s
Total Time11.24s (± 0.43%)11.22s (± 0.38%)-0.02s (- 0.21%)11.14s11.32s
TFS - node (v8.9.0, x86)
Memory used177,603k (± 0.02%)177,597k (± 0.02%)-6k (- 0.00%)177,513k177,705k
Parse Time1.60s (± 0.51%)1.61s (± 0.54%)+0.01s (+ 0.50%)1.59s1.62s
Bind Time0.65s (± 0.85%)0.65s (± 1.14%)-0.00s (- 0.31%)0.64s0.67s
Check Time4.84s (± 0.41%)4.86s (± 0.42%)+0.02s (+ 0.37%)4.82s4.90s
Emit Time2.85s (± 1.14%)2.83s (± 1.04%)-0.01s (- 0.42%)2.74s2.89s
Total Time9.94s (± 0.41%)9.95s (± 0.28%)+0.01s (+ 0.11%)9.87s10.00s
material-ui - node (v8.9.0, x86)
Memory used279,649k (± 0.03%)279,852k (± 0.02%)+202k (+ 0.07%)279,741k279,936k
Parse Time2.55s (± 0.80%)2.54s (± 0.49%)-0.00s (- 0.16%)2.52s2.57s
Bind Time0.73s (± 6.22%)0.77s (± 7.04%)+0.04s (+ 5.34%)0.69s0.88s
Check Time16.38s (± 0.68%)16.44s (± 0.46%)+0.06s (+ 0.38%)16.24s16.59s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time19.66s (± 0.41%)19.76s (± 0.28%)+0.10s (+ 0.50%)19.64s19.89s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-197-generic
Architecturex64
Available Memory16 GB
Available Memory11 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v8.9.0, x64)
  • node (v8.9.0, x86)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v8.9.0, x64)
  • Angular - node (v8.9.0, x86)
  • Compiler-Unions - node (v10.16.3, x64)
  • Compiler-Unions - node (v12.1.0, x64)
  • Compiler-Unions - node (v8.9.0, x64)
  • Compiler-Unions - node (v8.9.0, x86)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v8.9.0, x64)
  • Monaco - node (v8.9.0, x86)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v8.9.0, x64)
  • TFS - node (v8.9.0, x86)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v8.9.0, x64)
  • material-ui - node (v8.9.0, x86)
BenchmarkNameIterations
Current4189110
Baselinemaster10

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

Test suites revealed that template literal types didn't consistently have a string constraint and therefore weren't assignable to String, Object, {}, and so on. Latest commits fix that.

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

@typescript-bot test this
@typescript-bot user test this

@typescript-bot

typescript-bot commented Dec 9, 2020

Copy link
Copy Markdown
Contributor

Heya @ahejlsberg, I've started to run the parallelized community code test suite on this PR at 5cf670b. You can monitor the build here.

@typescript-bot

typescript-bot commented Dec 9, 2020

Copy link
Copy Markdown
Contributor

Heya @ahejlsberg, I've started to run the extended test suite on this PR at 5cf670b. You can monitor the build here.

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

DT run is clean. Performance looks fine. Latest RWC run shows a few errors that shouldn't have been errors disappearing.

@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

Three user test suites have new errors.

office-ui-fabric

We are now (correctly) reporting an error that was previously silenced because they're compiling with strictFunctionTypes off. Simplified example:

declareconstsomeStringArray: string[];someStringArray.map(key=>!!true ? `foo${key}` : null).filter((s: string)=>s);

We now report an error neither `foo${string` | null or string are assignable to each other. Previously it (unsoundly) succeeded because string is assignable to string | null.

We're also reporting an error on something similar to this:

declareconstsomeStringArray: string[];someStringArray.map(key=>`foo${key}`).concat(someStringArray);// string[] not assignable to `foo${string}`[]

Ideally this wouldn't be an error. The core issue is that concat types the array and the argument using the same type variable. It really should be T and U with the result typed as (T | U)[].

fp-ts

One new error that looks to be correct and simply a result of the stronger typing.

webpack

One new error on something similar to this:

declareconstsomeArray: unknown[];someArray.map(item=>`foo${item}`).unshift("someString");// Type "someString" not assignable to type `foo${string}`

Not much we can do about this. The array is now of type `foo${string}`[] instead of just string[], so it is an error to insert a value of type "someString".

@ahejlsbergahejlsberg added the Breaking Change Would introduce errors in existing code label Dec 10, 2020
@ahejlsberg

Copy link
Copy Markdown
MemberAuthor

I'm going to mark this as a breaking change given what we're seeing in the user test suites.

@ahejlsberg
ahejlsberg merged commit ee1f262 into masterDec 12, 2020
@ahejlsberg
ahejlsberg deleted the fix41631 branch December 12, 2020 01:07
@weswigham

Copy link
Copy Markdown
Member

Oof, apparently breaky enough to break our own build post-LKG. Namely, we have

constinternal=jsDocStyle ? `/**@internal*/` : `/*@internal*/`;// ...appendText(fs,sources[Project.second][Source.ts][Part.one],`class normalC {${internal} constructor() { }${internal} prop: string;${internal} method() { }${internal} get c() { return 10; }${internal} set c(val: number) { }}namespace normalN {${internal} export class C { }${internal} export function foo() {}${internal} export namespace someNamespace { export class C {} }${internal} export namespace someOther.something { export class someClass {} }${internal} export import someImport = someNamespace.C;${internal} export type internalType = internalC;${internal} export const internalConst = 10;${internal} export enum internalEnum { a, b, c }}${internal} class internalC {}${internal} function internalfoo() {}${internal} namespace internalNamespace { export class someClass {} }${internal} namespace internalOther.something { export class someClass {} }${internal} import internalImport = internalNamespace.someClass;${internal} type internalType = internalC;${internal} const internalConst = 10;${internal} enum internalEnum { a, b, c }`);

in our test harness.

@weswigham

Copy link
Copy Markdown
Member

#41942 is up with a fix to the build break, assuming we don't want to do anything with this change,

@jcalz

jcalz commented Feb 8, 2021

Copy link
Copy Markdown
Contributor

So #42588 undoes #41891, right? Just cross-linking them.

@pedrodurek

Copy link
Copy Markdown

Hey @DanielRosenwasser, considering that changes here were rolled back, do we have a new issue opened for this? Or you'll reopen this one #41631?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Author: TeamBreaking ChangeWould introduce errors in existing codeFor Uncommitted BugPR for untriaged, rejected, closed or missing bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Try to preserve template-ness of string literal types where possible

6 participants

@ahejlsberg@typescript-bot@weswigham@jcalz@pedrodurek@DanielRosenwasser