Various type comparison fixes (#64280)

This commit is contained in:
Jake Bailey authored and GitHub committed 2026-09-15 19:08:36 +00:00
1 parent 4870825525
commit 454c081981
22 files changed
+836 -27

No files matched your search

+37 -9
View File
@@ -490,13 +490,36 @@ func CompareTypes(t1, t2 *Type) int {
} else if t2.objectFlags&ObjectFlagsReference != 0 {
return 1
} else {
// Order unnamed non-reference object types by kind associated type mappers. Reverse mapped types have
// neither symbols nor mappers so they're ultimately ordered by unstable type IDs, but given their rarity
// this should be fine.
// Order unnamed non-reference object types by kind and instantiation data.
if c := int(t1.objectFlags&ObjectFlagsObjectTypeKindMask) - int(t2.objectFlags&ObjectFlagsObjectTypeKindMask); c != 0 {
return c
}
if c := compareTypeMappers(t1.AsObjectType().mapper, t2.AsObjectType().mapper); c != 0 {
if t1.objectFlags&ObjectFlagsReverseMapped != 0 {
r1 := t1.AsReverseMappedType()
r2 := t2.AsReverseMappedType()
if c := CompareTypes(r1.source, r2.source); c != 0 {
return c
}
if c := CompareTypes(r1.mappedType, r2.mappedType); c != 0 {
return c
}
if c := CompareTypes(r1.constraintType, r2.constraintType); c != 0 {
return c
}
}
m1 := t1.AsObjectType().mapper
m2 := t2.AsObjectType().mapper
if t1.objectFlags&ObjectFlagsMapped != 0 {
// instantiateAnonymousType prepends a fresh type parameter mapping.
// Compare the effective instantiation, not the identity of that fresh parameter.
if m1 != nil {
m1 = m1.data.(*CompositeTypeMapper).m2
}
if m2 != nil {
m2 = m2.data.(*CompositeTypeMapper).m2
}
}
if c := compareTypeMappers(m1, m2); c != 0 {
return c
}
}
@@ -537,6 +560,10 @@ func CompareTypes(t1, t2 *Type) int {
if c := cmp.Compare(t1.AsLiteralType().value.(jsnum.Number), t2.AsLiteralType().value.(jsnum.Number)); c != 0 {
return c
}
case t1.flags&TypeFlagsBigIntLiteral != 0:
if c := getBigIntLiteralValue(t1).Compare(getBigIntLiteralValue(t2)); c != 0 {
return c
}
case t1.flags&TypeFlagsBooleanLiteral != 0:
b1 := t1.AsLiteralType().value.(bool)
b2 := t2.AsLiteralType().value.(bool)
@@ -606,10 +633,7 @@ func compareTypeNames(t1, t2 *Type) int {
s1 := getTypeNameSymbol(t1)
s2 := getTypeNameSymbol(t2)
if s1 == s2 {
if t1.alias != nil {
return compareTypeLists(t1.alias.typeArguments, t2.alias.typeArguments)
}
return 0
return compareTypeLists(t1.alias.TypeArguments(), t2.alias.TypeArguments())
}
if s1 == nil {
return 1
@@ -617,7 +641,11 @@ func compareTypeNames(t1, t2 *Type) int {
if s2 == nil {
return -1
}
return strings.Compare(s1.Name, s2.Name)
if c := strings.Compare(s1.Name, s2.Name); c != 0 {
return c
}
// Keep distinct same-named declarations together before comparing alias arguments or structure.
return t1.checker.compareSymbols(s1, s2)
}
func getTypeNameSymbol(t *Type) *ast.Symbol {
@@ -34,8 +34,8 @@ export function foo(position: -1n | 0n) {
Items: &fourslash.CompletionsExpectedItems{
Includes: []fourslash.CompletionsExpectedItem{
&lsproto.CompletionItem{
Label: "case 0n: ...",
InsertText: new("case 0n:$1\ncase -1n:$2"),
Label: "case -1n: ...",
InsertText: new("case -1n:$1\ncase 0n:$2"),
SortText: new(string(ls.SortTextGlobalsOrKeywords)),
InsertTextFormat: new(lsproto.InsertTextFormatSnippet),
},
+15
View File
@@ -1,6 +1,7 @@
package jsnum
import (
"cmp"
"fmt"
"math/big"
"strings"
@@ -37,6 +38,20 @@ func (value PseudoBigInt) Sign() int {
return 1
}
func (value PseudoBigInt) Compare(other PseudoBigInt) int {
if c := cmp.Compare(value.Sign(), other.Sign()); c != 0 {
return c
}
c := cmp.Compare(len(value.Base10Value), len(other.Base10Value))
if c == 0 {
c = strings.Compare(value.Base10Value, other.Base10Value)
}
if value.Negative {
c = -c
}
return c
}
func ParseValidBigInt(text string) PseudoBigInt {
text, negative := strings.CutPrefix(text, "-")
return NewPseudoBigInt(ParsePseudoBigInt(text), negative)
@@ -0,0 +1,79 @@
//// [tests/cases/compiler/comparisonAnonymousMappedTypes.ts] ////
//// [comparisonAnonymousMappedTypes.ts]
declare function mapped<T>(): { [K in "value"]: T };
declare function object<T>(): { value: T };
declare function homomorphic<T>(): { [K in keyof T]: T[K] };
export const mappedValues = [mapped<number>(), mapped<string>(), mapped<boolean>()];
export const objectValues = [object<number>(), object<string>(), object<boolean>()];
export const reversedMappedValues = [mapped<boolean>(), mapped<string>(), mapped<number>()];
interface StringValue { value: string }
interface NumberValue { value: number }
interface BooleanValue { value: boolean }
export const homomorphicValues = [
homomorphic<NumberValue>(),
homomorphic<StringValue>(),
homomorphic<BooleanValue>()
];
export const reversedHomomorphicValues = [
homomorphic<BooleanValue>(),
homomorphic<StringValue>(),
homomorphic<NumberValue>()
];
//// [comparisonAnonymousMappedTypes.js]
export const mappedValues = [mapped(), mapped(), mapped()];
export const objectValues = [object(), object(), object()];
export const reversedMappedValues = [mapped(), mapped(), mapped()];
export const homomorphicValues = [
homomorphic(),
homomorphic(),
homomorphic()
];
export const reversedHomomorphicValues = [
homomorphic(),
homomorphic(),
homomorphic()
];
//// [comparisonAnonymousMappedTypes.d.ts]
export declare const mappedValues: ({
value: string;
} | {
value: number;
} | {
value: boolean;
})[];
export declare const objectValues: ({
value: string;
} | {
value: number;
} | {
value: boolean;
})[];
export declare const reversedMappedValues: ({
value: string;
} | {
value: number;
} | {
value: boolean;
})[];
export declare const homomorphicValues: ({
value: boolean;
} | {
value: number;
} | {
value: string;
})[];
export declare const reversedHomomorphicValues: ({
value: boolean;
} | {
value: number;
} | {
value: string;
})[];
@@ -0,0 +1,86 @@
//// [tests/cases/compiler/comparisonAnonymousMappedTypes.ts] ////
=== comparisonAnonymousMappedTypes.ts ===
declare function mapped<T>(): { [K in "value"]: T };
>mapped : Symbol(mapped, Decl(comparisonAnonymousMappedTypes.ts, 0, 0))
>T : Symbol(T, Decl(comparisonAnonymousMappedTypes.ts, 0, 24))
>K : Symbol(K, Decl(comparisonAnonymousMappedTypes.ts, 0, 33))
>T : Symbol(T, Decl(comparisonAnonymousMappedTypes.ts, 0, 24))
declare function object<T>(): { value: T };
>object : Symbol(object, Decl(comparisonAnonymousMappedTypes.ts, 0, 52))
>T : Symbol(T, Decl(comparisonAnonymousMappedTypes.ts, 1, 24))
>value : Symbol(value, Decl(comparisonAnonymousMappedTypes.ts, 1, 31))
>T : Symbol(T, Decl(comparisonAnonymousMappedTypes.ts, 1, 24))
declare function homomorphic<T>(): { [K in keyof T]: T[K] };
>homomorphic : Symbol(homomorphic, Decl(comparisonAnonymousMappedTypes.ts, 1, 43))
>T : Symbol(T, Decl(comparisonAnonymousMappedTypes.ts, 2, 29))
>K : Symbol(K, Decl(comparisonAnonymousMappedTypes.ts, 2, 38))
>T : Symbol(T, Decl(comparisonAnonymousMappedTypes.ts, 2, 29))
>T : Symbol(T, Decl(comparisonAnonymousMappedTypes.ts, 2, 29))
>K : Symbol(K, Decl(comparisonAnonymousMappedTypes.ts, 2, 38))
export const mappedValues = [mapped<number>(), mapped<string>(), mapped<boolean>()];
>mappedValues : Symbol(mappedValues, Decl(comparisonAnonymousMappedTypes.ts, 4, 12))
>mapped : Symbol(mapped, Decl(comparisonAnonymousMappedTypes.ts, 0, 0))
>mapped : Symbol(mapped, Decl(comparisonAnonymousMappedTypes.ts, 0, 0))
>mapped : Symbol(mapped, Decl(comparisonAnonymousMappedTypes.ts, 0, 0))
export const objectValues = [object<number>(), object<string>(), object<boolean>()];
>objectValues : Symbol(objectValues, Decl(comparisonAnonymousMappedTypes.ts, 5, 12))
>object : Symbol(object, Decl(comparisonAnonymousMappedTypes.ts, 0, 52))
>object : Symbol(object, Decl(comparisonAnonymousMappedTypes.ts, 0, 52))
>object : Symbol(object, Decl(comparisonAnonymousMappedTypes.ts, 0, 52))
export const reversedMappedValues = [mapped<boolean>(), mapped<string>(), mapped<number>()];
>reversedMappedValues : Symbol(reversedMappedValues, Decl(comparisonAnonymousMappedTypes.ts, 6, 12))
>mapped : Symbol(mapped, Decl(comparisonAnonymousMappedTypes.ts, 0, 0))
>mapped : Symbol(mapped, Decl(comparisonAnonymousMappedTypes.ts, 0, 0))
>mapped : Symbol(mapped, Decl(comparisonAnonymousMappedTypes.ts, 0, 0))
interface StringValue { value: string }
>StringValue : Symbol(StringValue, Decl(comparisonAnonymousMappedTypes.ts, 6, 92))
>value : Symbol(StringValue.value, Decl(comparisonAnonymousMappedTypes.ts, 8, 23))
interface NumberValue { value: number }
>NumberValue : Symbol(NumberValue, Decl(comparisonAnonymousMappedTypes.ts, 8, 39))
>value : Symbol(NumberValue.value, Decl(comparisonAnonymousMappedTypes.ts, 9, 23))
interface BooleanValue { value: boolean }
>BooleanValue : Symbol(BooleanValue, Decl(comparisonAnonymousMappedTypes.ts, 9, 39))
>value : Symbol(BooleanValue.value, Decl(comparisonAnonymousMappedTypes.ts, 10, 24))
export const homomorphicValues = [
>homomorphicValues : Symbol(homomorphicValues, Decl(comparisonAnonymousMappedTypes.ts, 12, 12))
homomorphic<NumberValue>(),
>homomorphic : Symbol(homomorphic, Decl(comparisonAnonymousMappedTypes.ts, 1, 43))
>NumberValue : Symbol(NumberValue, Decl(comparisonAnonymousMappedTypes.ts, 8, 39))
homomorphic<StringValue>(),
>homomorphic : Symbol(homomorphic, Decl(comparisonAnonymousMappedTypes.ts, 1, 43))
>StringValue : Symbol(StringValue, Decl(comparisonAnonymousMappedTypes.ts, 6, 92))
homomorphic<BooleanValue>()
>homomorphic : Symbol(homomorphic, Decl(comparisonAnonymousMappedTypes.ts, 1, 43))
>BooleanValue : Symbol(BooleanValue, Decl(comparisonAnonymousMappedTypes.ts, 9, 39))
];
export const reversedHomomorphicValues = [
>reversedHomomorphicValues : Symbol(reversedHomomorphicValues, Decl(comparisonAnonymousMappedTypes.ts, 17, 12))
homomorphic<BooleanValue>(),
>homomorphic : Symbol(homomorphic, Decl(comparisonAnonymousMappedTypes.ts, 1, 43))
>BooleanValue : Symbol(BooleanValue, Decl(comparisonAnonymousMappedTypes.ts, 9, 39))
homomorphic<StringValue>(),
>homomorphic : Symbol(homomorphic, Decl(comparisonAnonymousMappedTypes.ts, 1, 43))
>StringValue : Symbol(StringValue, Decl(comparisonAnonymousMappedTypes.ts, 6, 92))
homomorphic<NumberValue>()
>homomorphic : Symbol(homomorphic, Decl(comparisonAnonymousMappedTypes.ts, 1, 43))
>NumberValue : Symbol(NumberValue, Decl(comparisonAnonymousMappedTypes.ts, 8, 39))
];
@@ -0,0 +1,87 @@
//// [tests/cases/compiler/comparisonAnonymousMappedTypes.ts] ////
=== comparisonAnonymousMappedTypes.ts ===
declare function mapped<T>(): { [K in "value"]: T };
>mapped : <T>() => { [K in "value"]: T; }
declare function object<T>(): { value: T };
>object : <T>() => { value: T; }
>value : T
declare function homomorphic<T>(): { [K in keyof T]: T[K] };
>homomorphic : <T>() => { [K in keyof T]: T[K]; }
export const mappedValues = [mapped<number>(), mapped<string>(), mapped<boolean>()];
>mappedValues : ({ value: string; } | { value: number; } | { value: boolean; })[]
>[mapped<number>(), mapped<string>(), mapped<boolean>()] : ({ value: string; } | { value: number; } | { value: boolean; })[]
>mapped<number>() : { value: number; }
>mapped : <T>() => { [K in "value"]: T; }
>mapped<string>() : { value: string; }
>mapped : <T>() => { [K in "value"]: T; }
>mapped<boolean>() : { value: boolean; }
>mapped : <T>() => { [K in "value"]: T; }
export const objectValues = [object<number>(), object<string>(), object<boolean>()];
>objectValues : ({ value: string; } | { value: number; } | { value: boolean; })[]
>[object<number>(), object<string>(), object<boolean>()] : ({ value: string; } | { value: number; } | { value: boolean; })[]
>object<number>() : { value: number; }
>object : <T>() => { value: T; }
>object<string>() : { value: string; }
>object : <T>() => { value: T; }
>object<boolean>() : { value: boolean; }
>object : <T>() => { value: T; }
export const reversedMappedValues = [mapped<boolean>(), mapped<string>(), mapped<number>()];
>reversedMappedValues : ({ value: string; } | { value: number; } | { value: boolean; })[]
>[mapped<boolean>(), mapped<string>(), mapped<number>()] : ({ value: string; } | { value: number; } | { value: boolean; })[]
>mapped<boolean>() : { value: boolean; }
>mapped : <T>() => { [K in "value"]: T; }
>mapped<string>() : { value: string; }
>mapped : <T>() => { [K in "value"]: T; }
>mapped<number>() : { value: number; }
>mapped : <T>() => { [K in "value"]: T; }
interface StringValue { value: string }
>value : string
interface NumberValue { value: number }
>value : number
interface BooleanValue { value: boolean }
>value : boolean
export const homomorphicValues = [
>homomorphicValues : ({ value: boolean; } | { value: number; } | { value: string; })[]
>[ homomorphic<NumberValue>(), homomorphic<StringValue>(), homomorphic<BooleanValue>()] : ({ value: boolean; } | { value: number; } | { value: string; })[]
homomorphic<NumberValue>(),
>homomorphic<NumberValue>() : { value: number; }
>homomorphic : <T>() => { [K in keyof T]: T[K]; }
homomorphic<StringValue>(),
>homomorphic<StringValue>() : { value: string; }
>homomorphic : <T>() => { [K in keyof T]: T[K]; }
homomorphic<BooleanValue>()
>homomorphic<BooleanValue>() : { value: boolean; }
>homomorphic : <T>() => { [K in keyof T]: T[K]; }
];
export const reversedHomomorphicValues = [
>reversedHomomorphicValues : ({ value: boolean; } | { value: number; } | { value: string; })[]
>[ homomorphic<BooleanValue>(), homomorphic<StringValue>(), homomorphic<NumberValue>()] : ({ value: boolean; } | { value: number; } | { value: string; })[]
homomorphic<BooleanValue>(),
>homomorphic<BooleanValue>() : { value: boolean; }
>homomorphic : <T>() => { [K in keyof T]: T[K]; }
homomorphic<StringValue>(),
>homomorphic<StringValue>() : { value: string; }
>homomorphic : <T>() => { [K in keyof T]: T[K]; }
homomorphic<NumberValue>()
>homomorphic<NumberValue>() : { value: number; }
>homomorphic : <T>() => { [K in keyof T]: T[K]; }
];
@@ -0,0 +1,18 @@
//// [tests/cases/compiler/comparisonBigIntLiterals.ts] ////
//// [comparisonBigIntLiterals.ts]
export const descending = [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n] as const;
export const ascending = [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n] as const;
export const values = [...descending, ...ascending];
//// [comparisonBigIntLiterals.js]
export const descending = [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n];
export const ascending = [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n];
export const values = [...descending, ...ascending];
//// [comparisonBigIntLiterals.d.ts]
export declare const descending: readonly [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n];
export declare const ascending: readonly [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n];
export declare const values: (-100000000000000000000n | -100n | -10n | -2n | -1n | 0n | 1n | 2n | 10n | 100n | 100000000000000000000n)[];
@@ -0,0 +1,16 @@
//// [tests/cases/compiler/comparisonBigIntLiterals.ts] ////
=== comparisonBigIntLiterals.ts ===
export const descending = [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n] as const;
>descending : Symbol(descending, Decl(comparisonBigIntLiterals.ts, 0, 12))
>const : Symbol(const)
export const ascending = [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n] as const;
>ascending : Symbol(ascending, Decl(comparisonBigIntLiterals.ts, 1, 12))
>const : Symbol(const)
export const values = [...descending, ...ascending];
>values : Symbol(values, Decl(comparisonBigIntLiterals.ts, 2, 12))
>descending : Symbol(descending, Decl(comparisonBigIntLiterals.ts, 0, 12))
>ascending : Symbol(ascending, Decl(comparisonBigIntLiterals.ts, 1, 12))
@@ -0,0 +1,53 @@
//// [tests/cases/compiler/comparisonBigIntLiterals.ts] ////
=== comparisonBigIntLiterals.ts ===
export const descending = [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n] as const;
>descending : readonly [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n]
>[100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n] as const : readonly [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n]
>[100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n] : readonly [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n]
>100000000000000000000n : 100000000000000000000n
>100n : 100n
>10n : 10n
>2n : 2n
>1n : 1n
>0n : 0n
>-1n : -1n
>1n : 1n
>-2n : -2n
>2n : 2n
>-10n : -10n
>10n : 10n
>-100n : -100n
>100n : 100n
>-100000000000000000000n : -100000000000000000000n
>100000000000000000000n : 100000000000000000000n
export const ascending = [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n] as const;
>ascending : readonly [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n]
>[-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n] as const : readonly [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n]
>[-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n] : readonly [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n]
>-100000000000000000000n : -100000000000000000000n
>100000000000000000000n : 100000000000000000000n
>-100n : -100n
>100n : 100n
>-10n : -10n
>10n : 10n
>-2n : -2n
>2n : 2n
>-1n : -1n
>1n : 1n
>0n : 0n
>1n : 1n
>2n : 2n
>10n : 10n
>100n : 100n
>100000000000000000000n : 100000000000000000000n
export const values = [...descending, ...ascending];
>values : (-100000000000000000000n | -100n | -10n | -2n | -1n | 0n | 1n | 2n | 10n | 100n | 100000000000000000000n)[]
>[...descending, ...ascending] : (-100000000000000000000n | -100n | -10n | -2n | -1n | 0n | 1n | 2n | 10n | 100n | 100000000000000000000n)[]
>...descending : -100000000000000000000n | -100n | -10n | -2n | -1n | 0n | 1n | 2n | 10n | 100n | 100000000000000000000n
>descending : readonly [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n]
>...ascending : -100000000000000000000n | -100n | -10n | -2n | -1n | 0n | 1n | 2n | 10n | 100n | 100000000000000000000n
>ascending : readonly [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n]
@@ -0,0 +1,45 @@
//// [tests/cases/compiler/comparisonReverseMappedTypes.ts] ////
//// [comparisonReverseMappedTypes.ts]
declare function unbox<T>(value: { [K in keyof T]: { value: T[K] } }): T;
declare const strings: { value: { value: string } };
declare const numbers: { value: { value: number } };
declare const booleans: { value: { value: boolean } };
export const values = [unbox(numbers), unbox(strings), unbox(booleans)];
export const reversed = [unbox(booleans), unbox(strings), unbox(numbers)];
declare function identity<T>(value: { [K in keyof T]: T[K] }): T;
declare const nested: { value: { value: string } };
export const sameSource = [identity(nested), unbox(nested)];
//// [comparisonReverseMappedTypes.js]
export const values = [unbox(numbers), unbox(strings), unbox(booleans)];
export const reversed = [unbox(booleans), unbox(strings), unbox(numbers)];
export const sameSource = [identity(nested), unbox(nested)];
//// [comparisonReverseMappedTypes.d.ts]
export declare const values: ({
value: string;
} | {
value: number;
} | {
value: boolean;
})[];
export declare const reversed: ({
value: string;
} | {
value: number;
} | {
value: boolean;
})[];
export declare const sameSource: ({
value: string;
} | {
value: {
value: string;
};
})[];
@@ -0,0 +1,69 @@
//// [tests/cases/compiler/comparisonReverseMappedTypes.ts] ////
=== comparisonReverseMappedTypes.ts ===
declare function unbox<T>(value: { [K in keyof T]: { value: T[K] } }): T;
>unbox : Symbol(unbox, Decl(comparisonReverseMappedTypes.ts, 0, 0))
>T : Symbol(T, Decl(comparisonReverseMappedTypes.ts, 0, 23))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 0, 26))
>K : Symbol(K, Decl(comparisonReverseMappedTypes.ts, 0, 36))
>T : Symbol(T, Decl(comparisonReverseMappedTypes.ts, 0, 23))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 0, 52))
>T : Symbol(T, Decl(comparisonReverseMappedTypes.ts, 0, 23))
>K : Symbol(K, Decl(comparisonReverseMappedTypes.ts, 0, 36))
>T : Symbol(T, Decl(comparisonReverseMappedTypes.ts, 0, 23))
declare const strings: { value: { value: string } };
>strings : Symbol(strings, Decl(comparisonReverseMappedTypes.ts, 2, 13))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 2, 24))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 2, 33))
declare const numbers: { value: { value: number } };
>numbers : Symbol(numbers, Decl(comparisonReverseMappedTypes.ts, 3, 13))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 3, 24))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 3, 33))
declare const booleans: { value: { value: boolean } };
>booleans : Symbol(booleans, Decl(comparisonReverseMappedTypes.ts, 4, 13))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 4, 25))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 4, 34))
export const values = [unbox(numbers), unbox(strings), unbox(booleans)];
>values : Symbol(values, Decl(comparisonReverseMappedTypes.ts, 6, 12))
>unbox : Symbol(unbox, Decl(comparisonReverseMappedTypes.ts, 0, 0))
>numbers : Symbol(numbers, Decl(comparisonReverseMappedTypes.ts, 3, 13))
>unbox : Symbol(unbox, Decl(comparisonReverseMappedTypes.ts, 0, 0))
>strings : Symbol(strings, Decl(comparisonReverseMappedTypes.ts, 2, 13))
>unbox : Symbol(unbox, Decl(comparisonReverseMappedTypes.ts, 0, 0))
>booleans : Symbol(booleans, Decl(comparisonReverseMappedTypes.ts, 4, 13))
export const reversed = [unbox(booleans), unbox(strings), unbox(numbers)];
>reversed : Symbol(reversed, Decl(comparisonReverseMappedTypes.ts, 7, 12))
>unbox : Symbol(unbox, Decl(comparisonReverseMappedTypes.ts, 0, 0))
>booleans : Symbol(booleans, Decl(comparisonReverseMappedTypes.ts, 4, 13))
>unbox : Symbol(unbox, Decl(comparisonReverseMappedTypes.ts, 0, 0))
>strings : Symbol(strings, Decl(comparisonReverseMappedTypes.ts, 2, 13))
>unbox : Symbol(unbox, Decl(comparisonReverseMappedTypes.ts, 0, 0))
>numbers : Symbol(numbers, Decl(comparisonReverseMappedTypes.ts, 3, 13))
declare function identity<T>(value: { [K in keyof T]: T[K] }): T;
>identity : Symbol(identity, Decl(comparisonReverseMappedTypes.ts, 7, 74))
>T : Symbol(T, Decl(comparisonReverseMappedTypes.ts, 9, 26))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 9, 29))
>K : Symbol(K, Decl(comparisonReverseMappedTypes.ts, 9, 39))
>T : Symbol(T, Decl(comparisonReverseMappedTypes.ts, 9, 26))
>T : Symbol(T, Decl(comparisonReverseMappedTypes.ts, 9, 26))
>K : Symbol(K, Decl(comparisonReverseMappedTypes.ts, 9, 39))
>T : Symbol(T, Decl(comparisonReverseMappedTypes.ts, 9, 26))
declare const nested: { value: { value: string } };
>nested : Symbol(nested, Decl(comparisonReverseMappedTypes.ts, 10, 13))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 10, 23))
>value : Symbol(value, Decl(comparisonReverseMappedTypes.ts, 10, 32))
export const sameSource = [identity(nested), unbox(nested)];
>sameSource : Symbol(sameSource, Decl(comparisonReverseMappedTypes.ts, 11, 12))
>identity : Symbol(identity, Decl(comparisonReverseMappedTypes.ts, 7, 74))
>nested : Symbol(nested, Decl(comparisonReverseMappedTypes.ts, 10, 13))
>unbox : Symbol(unbox, Decl(comparisonReverseMappedTypes.ts, 0, 0))
>nested : Symbol(nested, Decl(comparisonReverseMappedTypes.ts, 10, 13))
@@ -0,0 +1,68 @@
//// [tests/cases/compiler/comparisonReverseMappedTypes.ts] ////
=== comparisonReverseMappedTypes.ts ===
declare function unbox<T>(value: { [K in keyof T]: { value: T[K] } }): T;
>unbox : <T>(value: { [K in keyof T]: { value: T[K]; }; }) => T
>value : { [K in keyof T]: { value: T[K]; }; }
>value : T[K]
declare const strings: { value: { value: string } };
>strings : { value: { value: string; }; }
>value : { value: string; }
>value : string
declare const numbers: { value: { value: number } };
>numbers : { value: { value: number; }; }
>value : { value: number; }
>value : number
declare const booleans: { value: { value: boolean } };
>booleans : { value: { value: boolean; }; }
>value : { value: boolean; }
>value : boolean
export const values = [unbox(numbers), unbox(strings), unbox(booleans)];
>values : ({ value: string; } | { value: number; } | { value: boolean; })[]
>[unbox(numbers), unbox(strings), unbox(booleans)] : ({ value: string; } | { value: number; } | { value: boolean; })[]
>unbox(numbers) : { value: number; }
>unbox : <T>(value: { [K in keyof T]: { value: T[K]; }; }) => T
>numbers : { value: { value: number; }; }
>unbox(strings) : { value: string; }
>unbox : <T>(value: { [K in keyof T]: { value: T[K]; }; }) => T
>strings : { value: { value: string; }; }
>unbox(booleans) : { value: boolean; }
>unbox : <T>(value: { [K in keyof T]: { value: T[K]; }; }) => T
>booleans : { value: { value: boolean; }; }
export const reversed = [unbox(booleans), unbox(strings), unbox(numbers)];
>reversed : ({ value: string; } | { value: number; } | { value: boolean; })[]
>[unbox(booleans), unbox(strings), unbox(numbers)] : ({ value: string; } | { value: number; } | { value: boolean; })[]
>unbox(booleans) : { value: boolean; }
>unbox : <T>(value: { [K in keyof T]: { value: T[K]; }; }) => T
>booleans : { value: { value: boolean; }; }
>unbox(strings) : { value: string; }
>unbox : <T>(value: { [K in keyof T]: { value: T[K]; }; }) => T
>strings : { value: { value: string; }; }
>unbox(numbers) : { value: number; }
>unbox : <T>(value: { [K in keyof T]: { value: T[K]; }; }) => T
>numbers : { value: { value: number; }; }
declare function identity<T>(value: { [K in keyof T]: T[K] }): T;
>identity : <T>(value: { [K in keyof T]: T[K]; }) => T
>value : { [K in keyof T]: T[K]; }
declare const nested: { value: { value: string } };
>nested : { value: { value: string; }; }
>value : { value: string; }
>value : string
export const sameSource = [identity(nested), unbox(nested)];
>sameSource : ({ value: string; } | { value: { value: string; }; })[]
>[identity(nested), unbox(nested)] : ({ value: string; } | { value: { value: string; }; })[]
>identity(nested) : { value: { value: string; }; }
>identity : <T>(value: { [K in keyof T]: T[K]; }) => T
>nested : { value: { value: string; }; }
>unbox(nested) : { value: string; }
>unbox : <T>(value: { [K in keyof T]: { value: T[K]; }; }) => T
>nested : { value: { value: string; }; }
@@ -0,0 +1,52 @@
//// [tests/cases/compiler/comparisonSameNamedAliases.ts] ////
//// [comparisonSameNamedAliases.ts]
interface First { first: string }
interface Middle { middle: string }
interface ZLast { last: string }
namespace A {
export type Alias<T> = (T extends string ? ZLast : First) & { common: unknown };
}
namespace B {
export type Alias<T> = T & { common: unknown };
}
declare const a: A.Alias<string>;
declare const b: A.Alias<number>;
declare const c: B.Alias<Middle>;
export const values = [a, b, c];
export const reversed = [c, b, a];
export const shuffled = [b, a, c];
//// [comparisonSameNamedAliases.js]
export const values = [a, b, c];
export const reversed = [c, b, a];
export const shuffled = [b, a, c];
//// [comparisonSameNamedAliases.d.ts]
interface First {
first: string;
}
interface Middle {
middle: string;
}
interface ZLast {
last: string;
}
declare namespace A {
type Alias<T> = (T extends string ? ZLast : First) & {
common: unknown;
};
}
declare namespace B {
type Alias<T> = T & {
common: unknown;
};
}
export declare const values: (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[];
export declare const reversed: (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[];
export declare const shuffled: (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[];
export {};
@@ -0,0 +1,70 @@
//// [tests/cases/compiler/comparisonSameNamedAliases.ts] ////
=== comparisonSameNamedAliases.ts ===
interface First { first: string }
>First : Symbol(First, Decl(comparisonSameNamedAliases.ts, 0, 0))
>first : Symbol(First.first, Decl(comparisonSameNamedAliases.ts, 0, 17))
interface Middle { middle: string }
>Middle : Symbol(Middle, Decl(comparisonSameNamedAliases.ts, 0, 33))
>middle : Symbol(Middle.middle, Decl(comparisonSameNamedAliases.ts, 1, 18))
interface ZLast { last: string }
>ZLast : Symbol(ZLast, Decl(comparisonSameNamedAliases.ts, 1, 35))
>last : Symbol(ZLast.last, Decl(comparisonSameNamedAliases.ts, 2, 17))
namespace A {
>A : Symbol(A, Decl(comparisonSameNamedAliases.ts, 2, 32))
export type Alias<T> = (T extends string ? ZLast : First) & { common: unknown };
>Alias : Symbol(Alias, Decl(comparisonSameNamedAliases.ts, 4, 13))
>T : Symbol(T, Decl(comparisonSameNamedAliases.ts, 5, 22))
>T : Symbol(T, Decl(comparisonSameNamedAliases.ts, 5, 22))
>ZLast : Symbol(ZLast, Decl(comparisonSameNamedAliases.ts, 1, 35))
>First : Symbol(First, Decl(comparisonSameNamedAliases.ts, 0, 0))
>common : Symbol(common, Decl(comparisonSameNamedAliases.ts, 5, 65))
}
namespace B {
>B : Symbol(B, Decl(comparisonSameNamedAliases.ts, 6, 1))
export type Alias<T> = T & { common: unknown };
>Alias : Symbol(Alias, Decl(comparisonSameNamedAliases.ts, 7, 13))
>T : Symbol(T, Decl(comparisonSameNamedAliases.ts, 8, 22))
>T : Symbol(T, Decl(comparisonSameNamedAliases.ts, 8, 22))
>common : Symbol(common, Decl(comparisonSameNamedAliases.ts, 8, 32))
}
declare const a: A.Alias<string>;
>a : Symbol(a, Decl(comparisonSameNamedAliases.ts, 11, 13))
>A : Symbol(A, Decl(comparisonSameNamedAliases.ts, 2, 32))
>Alias : Symbol(A.Alias, Decl(comparisonSameNamedAliases.ts, 4, 13))
declare const b: A.Alias<number>;
>b : Symbol(b, Decl(comparisonSameNamedAliases.ts, 12, 13))
>A : Symbol(A, Decl(comparisonSameNamedAliases.ts, 2, 32))
>Alias : Symbol(A.Alias, Decl(comparisonSameNamedAliases.ts, 4, 13))
declare const c: B.Alias<Middle>;
>c : Symbol(c, Decl(comparisonSameNamedAliases.ts, 13, 13))
>B : Symbol(B, Decl(comparisonSameNamedAliases.ts, 6, 1))
>Alias : Symbol(B.Alias, Decl(comparisonSameNamedAliases.ts, 7, 13))
>Middle : Symbol(Middle, Decl(comparisonSameNamedAliases.ts, 0, 33))
export const values = [a, b, c];
>values : Symbol(values, Decl(comparisonSameNamedAliases.ts, 14, 12))
>a : Symbol(a, Decl(comparisonSameNamedAliases.ts, 11, 13))
>b : Symbol(b, Decl(comparisonSameNamedAliases.ts, 12, 13))
>c : Symbol(c, Decl(comparisonSameNamedAliases.ts, 13, 13))
export const reversed = [c, b, a];
>reversed : Symbol(reversed, Decl(comparisonSameNamedAliases.ts, 15, 12))
>c : Symbol(c, Decl(comparisonSameNamedAliases.ts, 13, 13))
>b : Symbol(b, Decl(comparisonSameNamedAliases.ts, 12, 13))
>a : Symbol(a, Decl(comparisonSameNamedAliases.ts, 11, 13))
export const shuffled = [b, a, c];
>shuffled : Symbol(shuffled, Decl(comparisonSameNamedAliases.ts, 16, 12))
>b : Symbol(b, Decl(comparisonSameNamedAliases.ts, 12, 13))
>a : Symbol(a, Decl(comparisonSameNamedAliases.ts, 11, 13))
>c : Symbol(c, Decl(comparisonSameNamedAliases.ts, 13, 13))
@@ -0,0 +1,56 @@
//// [tests/cases/compiler/comparisonSameNamedAliases.ts] ////
=== comparisonSameNamedAliases.ts ===
interface First { first: string }
>first : string
interface Middle { middle: string }
>middle : string
interface ZLast { last: string }
>last : string
namespace A {
export type Alias<T> = (T extends string ? ZLast : First) & { common: unknown };
>Alias : Alias<T>
>common : unknown
}
namespace B {
export type Alias<T> = T & { common: unknown };
>Alias : Alias<T>
>common : unknown
}
declare const a: A.Alias<string>;
>a : A.Alias<string>
>A : any
declare const b: A.Alias<number>;
>b : A.Alias<number>
>A : any
declare const c: B.Alias<Middle>;
>c : B.Alias<Middle>
>B : any
export const values = [a, b, c];
>values : (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[]
>[a, b, c] : (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[]
>a : A.Alias<string>
>b : A.Alias<number>
>c : B.Alias<Middle>
export const reversed = [c, b, a];
>reversed : (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[]
>[c, b, a] : (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[]
>c : B.Alias<Middle>
>b : A.Alias<number>
>a : A.Alias<string>
export const shuffled = [b, a, c];
>shuffled : (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[]
>[b, a, c] : (A.Alias<string> | A.Alias<number> | B.Alias<Middle>)[]
>b : A.Alias<number>
>a : A.Alias<string>
>c : B.Alias<Middle>
@@ -11,11 +11,11 @@ parseBigInt.ts(62,20): error TS1125: Hexadecimal digit expected.
parseBigInt.ts(63,26): error TS2304: Cannot find name '_123n'.
parseBigInt.ts(64,30): error TS6188: Numeric separators are not allowed here.
parseBigInt.ts(65,33): error TS6189: Multiple consecutive numeric separators are not permitted.
parseBigInt.ts(69,15): error TS2345: Argument of type '0n' is not assignable to parameter of type '1n | 3n | 2n'.
parseBigInt.ts(70,15): error TS2345: Argument of type '0' is not assignable to parameter of type '1n | 3n | 2n'.
parseBigInt.ts(70,34): error TS2345: Argument of type '1' is not assignable to parameter of type '1n | 3n | 2n'.
parseBigInt.ts(70,53): error TS2345: Argument of type '2' is not assignable to parameter of type '1n | 3n | 2n'.
parseBigInt.ts(70,72): error TS2345: Argument of type '3' is not assignable to parameter of type '1n | 3n | 2n'.
parseBigInt.ts(69,15): error TS2345: Argument of type '0n' is not assignable to parameter of type '1n | 2n | 3n'.
parseBigInt.ts(70,15): error TS2345: Argument of type '0' is not assignable to parameter of type '1n | 2n | 3n'.
parseBigInt.ts(70,34): error TS2345: Argument of type '1' is not assignable to parameter of type '1n | 2n | 3n'.
parseBigInt.ts(70,53): error TS2345: Argument of type '2' is not assignable to parameter of type '1n | 2n | 3n'.
parseBigInt.ts(70,72): error TS2345: Argument of type '3' is not assignable to parameter of type '1n | 2n | 3n'.
==== parseBigInt.ts (18 errors) ====
@@ -115,13 +115,13 @@ parseBigInt.ts(70,72): error TS2345: Argument of type '3' is not assignable to p
const oneTwoOrThree = (x: 1n | 2n | 3n): bigint => x ** 2n;
oneTwoOrThree(0n); oneTwoOrThree(1n); oneTwoOrThree(2n); oneTwoOrThree(3n);
~~
!!! error TS2345: Argument of type '0n' is not assignable to parameter of type '1n | 3n | 2n'.
!!! error TS2345: Argument of type '0n' is not assignable to parameter of type '1n | 2n | 3n'.
oneTwoOrThree(0); oneTwoOrThree(1); oneTwoOrThree(2); oneTwoOrThree(3);
~
!!! error TS2345: Argument of type '0' is not assignable to parameter of type '1n | 3n | 2n'.
!!! error TS2345: Argument of type '0' is not assignable to parameter of type '1n | 2n | 3n'.
~
!!! error TS2345: Argument of type '1' is not assignable to parameter of type '1n | 3n | 2n'.
!!! error TS2345: Argument of type '1' is not assignable to parameter of type '1n | 2n | 3n'.
~
!!! error TS2345: Argument of type '2' is not assignable to parameter of type '1n | 3n | 2n'.
!!! error TS2345: Argument of type '2' is not assignable to parameter of type '1n | 2n | 3n'.
~
!!! error TS2345: Argument of type '3' is not assignable to parameter of type '1n | 3n | 2n'.
!!! error TS2345: Argument of type '3' is not assignable to parameter of type '1n | 2n | 3n'.
@@ -220,9 +220,9 @@ const doubleSeparator = 123_456__789n;
const oneTwoOrThree = (x: 1n | 2n | 3n): bigint => x ** 2n;
>oneTwoOrThree : (x: 1n | 2n | 3n) => bigint
>(x: 1n | 2n | 3n): bigint => x ** 2n : (x: 1n | 2n | 3n) => bigint
>x : 1n | 3n | 2n
>x : 1n | 2n | 3n
>x ** 2n : bigint
>x : 1n | 3n | 2n
>x : 1n | 2n | 3n
>2n : 2n
oneTwoOrThree(0n); oneTwoOrThree(1n); oneTwoOrThree(2n); oneTwoOrThree(3n);
+4 -4
View File
@@ -355,8 +355,8 @@
>ns / 1000n : bigint
>ns : bigint
>1000n : 1000n
>((ns % 1000n) < 0n ? -1n : 0n) : 0n | -1n
>(ns % 1000n) < 0n ? -1n : 0n : 0n | -1n
>((ns % 1000n) < 0n ? -1n : 0n) : -1n | 0n
>(ns % 1000n) < 0n ? -1n : 0n : -1n | 0n
>(ns % 1000n) < 0n : boolean
>(ns % 1000n) : bigint
>ns % 1000n : bigint
@@ -1310,8 +1310,8 @@
>ns / 1000n : bigint
>ns : bigint
>1000n : 1000n
>((ns % 1000n) < 0n ? -1n : 0n) : 0n | -1n
>(ns % 1000n) < 0n ? -1n : 0n : 0n | -1n
>((ns % 1000n) < 0n ? -1n : 0n) : -1n | 0n
>(ns % 1000n) < 0n ? -1n : 0n : -1n | 0n
>(ns % 1000n) < 0n : boolean
>(ns % 1000n) : bigint
>ns % 1000n : bigint
@@ -0,0 +1,25 @@
// @strict: true
// @declaration: true
declare function mapped<T>(): { [K in "value"]: T };
declare function object<T>(): { value: T };
declare function homomorphic<T>(): { [K in keyof T]: T[K] };
export const mappedValues = [mapped<number>(), mapped<string>(), mapped<boolean>()];
export const objectValues = [object<number>(), object<string>(), object<boolean>()];
export const reversedMappedValues = [mapped<boolean>(), mapped<string>(), mapped<number>()];
interface StringValue { value: string }
interface NumberValue { value: number }
interface BooleanValue { value: boolean }
export const homomorphicValues = [
homomorphic<NumberValue>(),
homomorphic<StringValue>(),
homomorphic<BooleanValue>()
];
export const reversedHomomorphicValues = [
homomorphic<BooleanValue>(),
homomorphic<StringValue>(),
homomorphic<NumberValue>()
];
@@ -0,0 +1,7 @@
// @target: esnext
// @strict: true
// @declaration: true
export const descending = [100000000000000000000n, 100n, 10n, 2n, 1n, 0n, -1n, -2n, -10n, -100n, -100000000000000000000n] as const;
export const ascending = [-100000000000000000000n, -100n, -10n, -2n, -1n, 0n, 1n, 2n, 10n, 100n, 100000000000000000000n] as const;
export const values = [...descending, ...ascending];
@@ -0,0 +1,15 @@
// @strict: true
// @declaration: true
declare function unbox<T>(value: { [K in keyof T]: { value: T[K] } }): T;
declare const strings: { value: { value: string } };
declare const numbers: { value: { value: number } };
declare const booleans: { value: { value: boolean } };
export const values = [unbox(numbers), unbox(strings), unbox(booleans)];
export const reversed = [unbox(booleans), unbox(strings), unbox(numbers)];
declare function identity<T>(value: { [K in keyof T]: T[K] }): T;
declare const nested: { value: { value: string } };
export const sameSource = [identity(nested), unbox(nested)];
@@ -0,0 +1,20 @@
// @strict: true
// @declaration: true
interface First { first: string }
interface Middle { middle: string }
interface ZLast { last: string }
namespace A {
export type Alias<T> = (T extends string ? ZLast : First) & { common: unknown };
}
namespace B {
export type Alias<T> = T & { common: unknown };
}
declare const a: A.Alias<string>;
declare const b: A.Alias<number>;
declare const c: B.Alias<Middle>;
export const values = [a, b, c];
export const reversed = [c, b, a];
export const shuffled = [b, a, c];