-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge trivially mergeable intersection types for identity comparison
- Loading branch information
MichaelMitchell-at
committed
Dec 9, 2024
1 parent
3d2b8f3
commit f7b81cf
Showing
5 changed files
with
830 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
tests/baselines/reference/identityRelationIntersectionTypes.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
//// [tests/cases/compiler/identityRelationIntersectionTypes.ts] //// | ||
|
||
//// [identityRelationIntersectionTypes.ts] | ||
namespace identityRelationIntersectionTypes { | ||
type Equals<A, B> = (<T>() => T extends B ? 1 : 0) extends (<T>() => T extends A ? 1 : 0) ? true : false; | ||
|
||
type GoodIntersection = Equals<{a: 1} & {b: 2}, {a: 1; b: 2}>; // true | ||
|
||
// Interfaces aren't mergeable | ||
interface I {i: 3}; | ||
type BadIntersection1 = Equals<{a: 1} & I, {a: 1; i: 3}>; // false | ||
|
||
// Objects with call or constructor signatures aren't mergeable | ||
type BadIntersection2 = Equals<{a: 1} & {b: 2; (): void}, {a: 1; b: 2; (): void}>; // false | ||
type BadIntersection3 = Equals<{a: 1} & {b: 2; new (): void}, {a: 1; b: 2; new (): void}>; // false | ||
|
||
// Objects with index signatures aren't mergeable | ||
type BadIntersection4 = Equals<{a: 1} & {b: 2; [key: string]: number}, {a: 1; b: 2; [key: string]: number}>; // false | ||
|
||
// Shouldn't merge intersection if any constituents aren't mergeable | ||
type StillBadIntersection1 = Equals<{a: 1} & {b: 2} & I, {a: 1; b: 2; i: 3}>; // false | ||
type StillBadIntersection2 = Equals<{a: 1} & {b: 2} & I, {a: 1; b: 2} & I>; // false | ||
|
||
// Parentheses don't matter because intersections are flattened | ||
type StillBadIntersection3 = Equals<({a: 1} & {b: 2}) & I, {a: 1; b: 2; i: 3}>; // false | ||
type StillBadIntersection4 = Equals<({a: 1} & {b: 2}) & I, {a: 1; b: 2} & I>; // false | ||
|
||
// Type aliases also don't prevent flattening | ||
type AB = {a: 1} & {b: 2}; | ||
type StillBadIntersection5 = Equals<AB & I, {a: 1; b: 2; i: 3}>; // false | ||
type StillBadIntersection6 = Equals<AB & I, {a: 1; b: 2} & I>; // false | ||
|
||
type GoodDeepIntersection1 = Equals<{a: 0 | 1} & {a: 1 | 2}, {a: 1}>; // true | ||
type GoodDeepIntersection2 = Equals<{a: {x: 1}} & {a: {y: 2}}, {a: {x: 1; y: 2}}>; // true | ||
|
||
type GoodShallowBadDeepIntersection1 = Equals<{a: {x: 1}} & {a: {y: 2} & I}, {a: {x: 1; y: 2} & I}>; // false | ||
type GoodShallowBadDeepIntersection2 = Equals<{a: {x: 1}} & {a: {y: 2} & I}, {a: {x: 1} & {y: 2} & I}>; // true | ||
|
||
// Reduction applies to nested intersections | ||
type DeepReduction = Equals<{a: {x: 1}} & {a: {x: 2}}, {a: never}>; // true | ||
|
||
// Intersections are distributed and merged if possible with union constituents | ||
type Distributed = Equals< | ||
{a: 1} & {b: 2} & ({c: 3} | {d: 4} | I), | ||
{a: 1; b: 2; c: 3} | {a: 1; b: 2; d: 4} | {a: 1} & {b: 2} & I | ||
>; // true | ||
|
||
// Should work with recursive types | ||
type R1 = {a: R1; x: 1}; | ||
type R2 = {a: R2; y: 1}; | ||
type R = R1 & R2; | ||
|
||
type Recursive1 = Equals<R, {a: R1 & R2; x: 1; y: 1}>; // true | ||
type Recursive2 = Equals<R, {a: {a: R1 & R2; x: 1; y: 1}; x: 1; y: 1}>; // true | ||
type Recursive3 = Equals<R, {a: {a: {a: R1 & R2; x: 1; y: 1}; x: 1; y: 1}; x: 1; y: 1}>; // true | ||
type Recursive4 = Equals<R, {a: {a: {a: R1 & R2; x: 1; y: 0}; x: 1; y: 1}; x: 1; y: 1}>; // false | ||
} | ||
|
||
|
||
//// [identityRelationIntersectionTypes.js] | ||
"use strict"; | ||
var identityRelationIntersectionTypes; | ||
(function (identityRelationIntersectionTypes) { | ||
; | ||
})(identityRelationIntersectionTypes || (identityRelationIntersectionTypes = {})); | ||
|
||
|
||
//// [identityRelationIntersectionTypes.d.ts] | ||
declare namespace identityRelationIntersectionTypes { | ||
} |
Oops, something went wrong.