Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Improve intersection reduction and CFA for truthy, equality, and typeof checks#49119

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ahejlsberg merged 32 commits intomainfromimproveIntersectionReduction
May 27, 2022

Conversation

@ahejlsberg
Copy link
Member

@ahejlsbergahejlsberg commentedMay 15, 2022
edited
Loading

This PR introduces a number of changes affecting control flow analysis of truthy, equality, and typeof checks involving typeunknown and unconstrained type variables in--strictNullChecks mode. Key to these changes is the fact that{}, the empty object type literal, is a supertype of all types exceptnull andundefined. Thus,{} | null | undefined is effectively equivalent tounknown, and for an arbitrary typeT, the intersectionT & {} represents the non-nullable form ofT.

The PR introduces the following new behaviors:

  • An unconstrained type parameter is no longer assignable to{}.
  • The predefined typeNonNullable<T> is now an alias forT & {}.
  • An intersectionT & {}, whereT is non-generic and notnull orundefined, reduces to justT (null & {} andundefined & {} already reduce tonever). See below for exceptions forstring & {},number & {}, andbigint & {}.
  • An intersectionundefined & void reduces to justundefined.
  • Any type is assignable to a union type that contains{},null, andundefined.
  • In control flow analysis,unknown behaves similarly to the union type{} | null | undefined.
  • In control flow analysis of truthy checks, generic types are intersected with{} in the true branch.
  • In control flow analysis of equality comparisons withnull orundefined, generic types are intersected with{},{} | null, or{} | undefined in the false branch.
  • In control flow analysis oftypeof x === "object" expressions, generic types are intersected withobject and/ornull in the true branch (typeof checks for other types already produce intersections in a similar manner).

Some examples:

typeT1={}&string;// stringtypeT2={}&'a';// 'a'typeT3={}&object;// objecttypeT4={}&{x:number};// { x: number }typeT5={}&null;// nevertypeT6={}&undefined;// nevertypeT7=undefined&void;// undefinedfunctionf1(u:unknown){letx1:{}=u;// Errorletx2:{}|null|undefined=u;// Okletx3:{}|{x:string}|null|undefined=u;// Ok}functionf2(x:unknown){if(x){x;// {}}else{x;// unknown}}functionf3<T>(x:T){if(x){x;// T & {}}else{x;// T}}functionf4(x:unknown){if(x!==undefined){x;// {} | null}else{x;// undefined}if(x!==null){x;// {} | undefined}else{x;// null}if(x!==undefined&&x!==null){x;// {}}else{x;// null | undefined}if(x!=undefined){x;// {}}else{x;// null | undefined}if(x!=null){x;// {}}else{x;// null | undefined}}functionf5<T>(x:T){if(x!==undefined){x;// T & ({} | null)}else{x;// T}if(x!==null){x;// T & ({} | undefined)}else{x;// T}if(x!==undefined&&x!==null){x;// {}}else{x;// T}if(x!=undefined){x;// {}}else{x;// T}if(x!=null){x;// {}}else{x;// T}}functionf6<T>(x:T){if(typeofx==="object"){x;// T & object | T & null}if(x&&typeofx==="object"){x;// T & object}if(typeofx==="object"&&x){x;// T & object}}functionensureNotNull<T>(x:T){if(x===null)throwError();returnx;// T & ({} | undefined)}functionensureNotUndefined<T>(x:T){if(x===undefined)throwError();returnx;// T & ({} | null)}functionensureNotNullOrUndefined<T>(x:T){returnensureNotUndefined(ensureNotNull(x));// T & {}}functionf7(a:string|undefined,b:number|null|undefined){leta1=ensureNotNullOrUndefined(a);// stringletb1=ensureNotNullOrUndefined(b);// number}

Note the manner in which types are properly inferred, combined, and reduced in theensureNotXXX functions. This contrasts with theNonNullable<T> conditional type provided inlib.d.ts, which unfortunately combines and reduces poorly. For example,NonNullable<NonNullable<T>> doesn't inherently reduce toNonNullable<T>, sometimes leading to needlessly complex types. For this and other reasons we intend to investigate switchingNonNullable<T> to be an alias forT & {}.

For backwards compatibility, special exceptions to theT & {} type reduction rules existing for intersections written explicitly asstring & {},number & {}, andbigint & {} (as opposed to created through instantiation of a generic typeT & {}). These types are used in a few frameworks (e.g.react andcsstype) to construct types that permit anystring,number, orbigint, but has statement completion hints for common literal values. For example:

typeAlignment=string&{}|"left"|"center"|"right";

The specialstring & {} type prevents subtype reduction from taking place in the union type, thus preserving the literal types, but otherwise anystring value is assignable to the type.

This PR reinstatates#48366 (which was removed from 4.7 due to concerns over breaking changes).

Fixes#23368.
Fixes#31908.
Fixes#32347.
Fixes#43997.
Fixes#44446.
Fixes#48048.
Fixes#48468.
Fixes#48691.
Fixes#49005.
Fixes#49191.

treybrisbane, Zachiah, matthargett, ArkaneMoose, VladSez, shenglol, voliva, MattiasMartens, DonIsaac, Hufschmidt, and 12 more reacted with heart emojiAviVahl, VladSez, voliva, yukinotech, Clonkex, jmopel, and worstpractice reacted with rocket emojitonivj5, FabianPuma, electron-space, VladSez, jmopel, worstpractice, and Mario-Marion reacted with eyes emoji
@typescript-bottypescript-bot added Author: Team For Uncommitted BugPR for untriaged, rejected, closed or missing bug labelsMay 15, 2022
@ahejlsberg
Copy link
MemberAuthor

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

@typescript-bot
Copy link
Collaborator

typescript-bot commentedMay 15, 2022
edited
Loading

Heya@ahejlsberg, I've started to run the abridged perf test suite on this PR at39326d7. You can monitor the buildhere.

Update:The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commentedMay 15, 2022
edited
Loading

Heya@ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at39326d7. You can monitor the buildhere.

@typescript-bot
Copy link
Collaborator

typescript-bot commentedMay 15, 2022
edited
Loading

Heya@ahejlsberg, I've started to run the extended test suite on this PR at39326d7. You can monitor the buildhere.

@typescript-bot
Copy link
Collaborator

typescript-bot commentedMay 15, 2022
edited
Loading

Heya@ahejlsberg, I've started to run the diff-based community code test suite on this PR at39326d7. You can monitor the buildhere.

Update:The results are in!

@typescript-bot
Copy link
Collaborator

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

Here they are:

Comparison Report - main..refs/pull/49119/merge

[async]

1 of 1 projects failed to build with the old tsc

/mnt/ts_downloads/async/tsconfig.json

  • error TS2339: Property 'iterator' does not exist on type 'never'.
    • /mnt/ts_downloads/async/node_modules/async/dist/async.js(477,61)
    • /mnt/ts_downloads/async/node_modules/async/internal/getIterator.js(11,61)

@typescript-bot
Copy link
Collaborator

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

Here they are:

Comparison Report - main..49119

Metricmain49119DeltaBestWorst
Angular - node (v14.15.1, x64)
Memory used333,610k (± 0.01%)333,600k (± 0.01%)-9k (- 0.00%)333,548k333,664k
Parse Time2.04s (± 0.44%)2.07s (± 0.96%)+0.02s (+ 1.08%)2.04s2.13s
Bind Time0.88s (± 0.95%)0.88s (± 0.78%)0.00s ( 0.00%)0.86s0.89s
Check Time5.65s (± 0.55%)5.69s (± 0.54%)+0.03s (+ 0.58%)5.61s5.76s
Emit Time6.29s (± 0.74%)6.37s (± 0.93%)+0.08s (+ 1.34%)6.19s6.49s
Total Time14.86s (± 0.49%)15.00s (± 0.62%)+0.14s (+ 0.94%)14.70s15.15s
Compiler-Unions - node (v14.15.1, x64)
Memory used192,272k (± 0.01%)192,173k (± 0.12%)-99k (- 0.05%)191,218k192,363k
Parse Time0.85s (± 0.87%)0.85s (± 0.35%)-0.00s (- 0.24%)0.84s0.85s
Bind Time0.56s (± 0.84%)0.56s (± 0.84%)+0.00s (+ 0.54%)0.55s0.57s
Check Time7.55s (± 0.47%)7.61s (± 0.68%)+0.06s (+ 0.78%)7.52s7.75s
Emit Time2.50s (± 0.66%)2.51s (± 0.89%)+0.01s (+ 0.28%)2.47s2.58s
Total Time11.46s (± 0.28%)11.53s (± 0.54%)+0.06s (+ 0.56%)11.43s11.74s
Monaco - node (v14.15.1, x64)
Memory used325,609k (± 0.00%)325,639k (± 0.00%)+30k (+ 0.01%)325,603k325,665k
Parse Time1.56s (± 0.40%)1.57s (± 0.85%)+0.02s (+ 1.03%)1.55s1.61s
Bind Time0.78s (± 1.15%)0.78s (± 0.71%)+0.00s (+ 0.26%)0.77s0.79s
Check Time5.54s (± 0.51%)5.54s (± 0.36%)+0.01s (+ 0.13%)5.51s5.58s
Emit Time3.31s (± 0.47%)3.33s (± 0.75%)+0.02s (+ 0.51%)3.27s3.37s
Total Time11.18s (± 0.26%)11.22s (± 0.24%)+0.05s (+ 0.42%)11.15s11.26s
TFS - node (v14.15.1, x64)
Memory used289,123k (± 0.01%)289,109k (± 0.01%)-14k (- 0.00%)289,052k289,157k
Parse Time1.36s (± 1.72%)1.37s (± 0.73%)+0.01s (+ 0.51%)1.35s1.40s
Bind Time0.72s (± 0.31%)0.72s (± 0.55%)+0.00s (+ 0.00%)0.71s0.73s
Check Time5.21s (± 0.57%)5.21s (± 0.44%)+0.00s (+ 0.08%)5.17s5.26s
Emit Time3.54s (± 1.90%)3.60s (± 1.11%)+0.06s (+ 1.70%)3.44s3.64s
Total Time10.83s (± 0.73%)10.90s (± 0.41%)+0.07s (+ 0.65%)10.77s11.01s
material-ui - node (v14.15.1, x64)
Memory used445,620k (± 0.06%)445,758k (± 0.00%)+138k (+ 0.03%)445,724k445,788k
Parse Time1.88s (± 0.59%)1.88s (± 0.59%)0.00s ( 0.00%)1.86s1.91s
Bind Time0.70s (± 0.68%)0.70s (± 0.68%)0.00s ( 0.00%)0.69s0.71s
Check Time13.12s (± 0.84%)13.15s (± 0.63%)+0.03s (+ 0.23%)12.95s13.31s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time15.70s (± 0.73%)15.73s (± 0.54%)+0.03s (+ 0.21%)15.52s15.91s
xstate - node (v14.15.1, x64)
Memory used535,261k (± 0.00%)535,348k (± 0.00%)+87k (+ 0.02%)535,298k535,383k
Parse Time2.58s (± 0.44%)2.60s (± 0.57%)+0.02s (+ 0.77%)2.57s2.64s
Bind Time1.15s (± 0.65%)1.16s (± 1.25%)+0.01s (+ 1.13%)1.14s1.20s
Check Time1.52s (± 0.48%)1.52s (± 0.45%)+0.00s (+ 0.20%)1.51s1.54s
Emit Time0.07s (± 0.00%)0.07s (± 0.00%)0.00s ( 0.00%)0.07s0.07s
Total Time5.32s (± 0.20%)5.36s (± 0.40%)+0.04s (+ 0.75%)5.32s5.42s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-210-generic
Architecturex64
Available Memory16 GB
Available Memory1 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v14.15.1, x64)
Scenarios
  • Angular - node (v14.15.1, x64)
  • Compiler-Unions - node (v14.15.1, x64)
  • Monaco - node (v14.15.1, x64)
  • TFS - node (v14.15.1, x64)
  • material-ui - node (v14.15.1, x64)
  • xstate - node (v14.15.1, x64)
BenchmarkNameIterations
Current4911910
Baselinemain10

Developer Information:

Download Benchmark

@ahejlsberg
Copy link
MemberAuthor

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

@typescript-bot
Copy link
Collaborator

typescript-bot commentedMay 15, 2022
edited
Loading

Heya@ahejlsberg, I've started to run the abridged perf test suite on this PR at986963c. You can monitor the buildhere.

Update:The results are in!

@typescript-bot
Copy link
Collaborator

typescript-bot commentedMay 15, 2022
edited
Loading

Heya@ahejlsberg, I've started to run the parallelized Definitely Typed test suite on this PR at986963c. You can monitor the buildhere.

@typescript-bot
Copy link
Collaborator

typescript-bot commentedMay 15, 2022
edited
Loading

Heya@ahejlsberg, I've started to run the diff-based community code test suite on this PR at986963c. You can monitor the buildhere.

@typescript-bot
Copy link
Collaborator

typescript-bot commentedMay 15, 2022
edited
Loading

Heya@ahejlsberg, I've started to run the extended test suite on this PR at986963c. You can monitor the buildhere.

@typescript-bot
Copy link
Collaborator

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

Here they are:

Comparison Report - main..49119

Metricmain49119DeltaBestWorst
Angular - node (v14.15.1, x64)
Memory used333,610k (± 0.01%)333,609k (± 0.00%)-1k (- 0.00%)333,591k333,642k
Parse Time2.04s (± 0.44%)2.04s (± 0.46%)-0.00s (- 0.10%)2.02s2.06s
Bind Time0.88s (± 0.95%)0.87s (± 0.46%)-0.00s (- 0.46%)0.86s0.88s
Check Time5.65s (± 0.55%)5.65s (± 0.39%)-0.00s (- 0.02%)5.60s5.69s
Emit Time6.29s (± 0.74%)6.35s (± 0.88%)+0.06s (+ 0.97%)6.27s6.49s
Total Time14.86s (± 0.49%)14.91s (± 0.44%)+0.05s (+ 0.35%)14.78s15.04s
Compiler-Unions - node (v14.15.1, x64)
Memory used192,272k (± 0.01%)192,279k (± 0.02%)+7k (+ 0.00%)192,180k192,344k
Parse Time0.85s (± 0.87%)0.85s (± 0.73%)-0.00s (- 0.12%)0.84s0.86s
Bind Time0.56s (± 0.84%)0.56s (± 0.65%)+0.00s (+ 0.71%)0.56s0.57s
Check Time7.55s (± 0.47%)7.55s (± 0.40%)-0.00s (- 0.03%)7.50s7.63s
Emit Time2.50s (± 0.66%)2.50s (± 0.75%)+0.00s (+ 0.12%)2.46s2.54s
Total Time11.46s (± 0.28%)11.46s (± 0.35%)+0.00s (+ 0.02%)11.39s11.59s
Monaco - node (v14.15.1, x64)
Memory used325,609k (± 0.00%)325,627k (± 0.01%)+18k (+ 0.01%)325,586k325,688k
Parse Time1.56s (± 0.40%)1.57s (± 0.67%)+0.01s (+ 0.90%)1.56s1.60s
Bind Time0.78s (± 1.15%)0.77s (± 0.72%)-0.00s (- 0.52%)0.76s0.78s
Check Time5.54s (± 0.51%)5.59s (± 0.32%)+0.06s (+ 0.99%)5.54s5.63s
Emit Time3.31s (± 0.47%)3.35s (± 0.75%)+0.04s (+ 1.18%)3.30s3.40s
Total Time11.18s (± 0.26%)11.29s (± 0.37%)+0.11s (+ 0.98%)11.20s11.36s
TFS - node (v14.15.1, x64)
Memory used289,123k (± 0.01%)289,132k (± 0.00%)+8k (+ 0.00%)289,103k289,147k
Parse Time1.36s (± 1.72%)1.36s (± 1.10%)-0.01s (- 0.44%)1.31s1.38s
Bind Time0.72s (± 0.31%)0.72s (± 0.50%)+0.00s (+ 0.42%)0.72s0.73s
Check Time5.21s (± 0.57%)5.21s (± 0.29%)+0.00s (+ 0.02%)5.18s5.24s
Emit Time3.54s (± 1.90%)3.56s (± 1.93%)+0.03s (+ 0.76%)3.41s3.65s
Total Time10.83s (± 0.73%)10.85s (± 0.69%)+0.02s (+ 0.22%)10.67s10.97s
material-ui - node (v14.15.1, x64)
Memory used445,620k (± 0.06%)445,722k (± 0.01%)+102k (+ 0.02%)445,618k445,786k
Parse Time1.88s (± 0.59%)1.88s (± 0.56%)-0.01s (- 0.37%)1.86s1.91s
Bind Time0.70s (± 0.68%)0.70s (± 0.74%)+0.00s (+ 0.57%)0.69s0.71s
Check Time13.12s (± 0.84%)13.11s (± 0.61%)-0.01s (- 0.08%)12.96s13.36s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time15.70s (± 0.73%)15.69s (± 0.53%)-0.01s (- 0.07%)15.52s15.95s
xstate - node (v14.15.1, x64)
Memory used535,261k (± 0.00%)535,395k (± 0.00%)+134k (+ 0.03%)535,367k535,423k
Parse Time2.58s (± 0.44%)2.60s (± 0.58%)+0.02s (+ 0.77%)2.57s2.63s
Bind Time1.15s (± 0.65%)1.15s (± 1.04%)+0.00s (+ 0.26%)1.13s1.19s
Check Time1.52s (± 0.48%)1.52s (± 0.70%)+0.00s (+ 0.20%)1.51s1.55s
Emit Time0.07s (± 0.00%)0.07s (± 0.00%)0.00s ( 0.00%)0.07s0.07s
Total Time5.32s (± 0.20%)5.35s (± 0.42%)+0.03s (+ 0.53%)5.30s5.39s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-210-generic
Architecturex64
Available Memory16 GB
Available Memory1 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v14.15.1, x64)
Scenarios
  • Angular - node (v14.15.1, x64)
  • Compiler-Unions - node (v14.15.1, x64)
  • Monaco - node (v14.15.1, x64)
  • TFS - node (v14.15.1, x64)
  • material-ui - node (v14.15.1, x64)
  • xstate - node (v14.15.1, x64)
BenchmarkNameIterations
Current4911910
Baselinemain10

Developer Information:

Download Benchmark

@ahejlsberg
Copy link
MemberAuthor

@user test this inline

@jcalz
Copy link
Contributor

jcalz commentedSep 17, 2022
edited
Loading

Is there a reason why this narrowing wasn't implemented fortypeof x === "undefined" the way it was forx === undefined? Seethis SO question

@jakebailey
Copy link
Member

I feel like that's an oversight and probably deserves its own issue. (But, I'm not Anders 😄)

jcalz reacted with thumbs up emoji

@Andarist
Copy link
Contributor

@jcalz what you reported here, in your last comment, was just fixed 2 days ago in#52456

@uid11
Copy link

It seems that in the examples in the main message in thefunction f5<T> the type parameterT is missing in a couple of places:

functionf5<T>(x:T){    ...if(x!==undefined&&x!==null){x;// {} -- should be T & {}}else{x;// T}if(x!=undefined){x;// {} -- should be NonNullable<T>}else{x;// T}if(x!=null){x;// {} -- should be NonNullable<T>}else{x;// T}}

But this is clear from the context and will not confuse anyone too much, I think.

@microsoftmicrosoft locked asresolvedand limited conversation to collaboratorsOct 22, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.

Reviewers

@weswighamweswighamweswigham approved these changes

@RyanCavanaughRyanCavanaughRyanCavanaugh approved these changes

@DanielRosenwasserDanielRosenwasserAwaiting requested review from DanielRosenwasser

Assignees

@ahejlsbergahejlsberg

Labels

Author: TeamBreaking ChangeWould introduce errors in existing codeFor Backlog BugPRs that fix a backlog bugFor Milestone BugPRs that fix a bug with a specific milestone

Projects

Archived in project

Milestone

No milestone

12 participants

@ahejlsberg@typescript-bot@taralx@DanielRosenwasser@sandersn@RyanCavanaugh@weswigham@jcalz@jakebailey@Andarist@uid11

[8]ページ先頭

©2009-2025 Movatter.jp