Compare commits
4 commits
main
...
alwaysCach
Author | SHA1 | Date | |
---|---|---|---|
6499302983 | |||
8c278bf5ab | |||
bd0833afaa | |||
79a73bf510 |
|
@ -18207,13 +18207,12 @@ namespace ts {
|
|||
let result = Ternary.False;
|
||||
const saveErrorInfo = captureErrorCalculationState();
|
||||
|
||||
// Note that these checks are specifically ordered to produce correct results. In particular,
|
||||
// we need to deconstruct unions before intersections (because unions are always at the top),
|
||||
// and we need to handle "each" relations before "some" relations for the same kind of type.
|
||||
if (source.flags & TypeFlags.UnionOrIntersection || target.flags & TypeFlags.UnionOrIntersection) {
|
||||
result = getConstituentCount(source) * getConstituentCount(target) >= 4 ?
|
||||
recursiveTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck, recursionFlags) :
|
||||
structuredTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck);
|
||||
if ((source.flags & TypeFlags.Union || target.flags & TypeFlags.Union) && getConstituentCount(source) * getConstituentCount(target) < 0) {
|
||||
// We skip caching when source or target is a union with no more than three constituents.
|
||||
result = structuredTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck);
|
||||
}
|
||||
else if (source.flags & TypeFlags.UnionOrIntersection || target.flags & TypeFlags.UnionOrIntersection) {
|
||||
result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState | IntersectionState.UnionIntersectionCheck, recursionFlags);
|
||||
}
|
||||
if (!result && !(source.flags & TypeFlags.Union) && (source.flags & (TypeFlags.StructuredOrInstantiable) || target.flags & TypeFlags.StructuredOrInstantiable)) {
|
||||
if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState, recursionFlags)) {
|
||||
|
@ -18677,17 +18676,17 @@ namespace ts {
|
|||
const maybeStart = maybeCount;
|
||||
maybeKeys[maybeCount] = id;
|
||||
maybeCount++;
|
||||
const saveExpandingFlags = expandingFlags;
|
||||
if (recursionFlags & RecursionFlags.Source) {
|
||||
sourceStack[sourceDepth] = source;
|
||||
sourceDepth++;
|
||||
if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, sourceDepth)) expandingFlags |= ExpandingFlags.Source;
|
||||
}
|
||||
if (recursionFlags & RecursionFlags.Target) {
|
||||
targetStack[targetDepth] = target;
|
||||
targetDepth++;
|
||||
if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) expandingFlags |= ExpandingFlags.Target;
|
||||
}
|
||||
const saveExpandingFlags = expandingFlags;
|
||||
if (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, sourceDepth)) expandingFlags |= ExpandingFlags.Source;
|
||||
if (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(target, targetStack, targetDepth)) expandingFlags |= ExpandingFlags.Target;
|
||||
let originalHandler: typeof outofbandVarianceMarkerHandler;
|
||||
let propagatingVarianceFlags: RelationComparisonResult = 0;
|
||||
if (outofbandVarianceMarkerHandler) {
|
||||
|
@ -18713,13 +18712,13 @@ namespace ts {
|
|||
if (outofbandVarianceMarkerHandler) {
|
||||
outofbandVarianceMarkerHandler = originalHandler;
|
||||
}
|
||||
expandingFlags = saveExpandingFlags;
|
||||
if (recursionFlags & RecursionFlags.Source) {
|
||||
sourceDepth--;
|
||||
}
|
||||
if (recursionFlags & RecursionFlags.Target) {
|
||||
targetDepth--;
|
||||
}
|
||||
expandingFlags = saveExpandingFlags;
|
||||
if (result) {
|
||||
if (result === Ternary.True || (sourceDepth === 0 && targetDepth === 0)) {
|
||||
if (result === Ternary.True || result === Ternary.Maybe) {
|
||||
|
@ -23150,7 +23149,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getConstituentCount(type: Type) {
|
||||
return type.flags & TypeFlags.UnionOrIntersection ? (type as UnionOrIntersectionType).types.length : 1;
|
||||
return type.flags & TypeFlags.Union ? (type as UnionType).types.length : 1;
|
||||
}
|
||||
|
||||
function extractTypesOfKind(type: Type, kind: TypeFlags) {
|
||||
|
|
|
@ -9,16 +9,14 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t
|
|||
Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
Type '"text"' is not assignable to type 'T & "text"'.
|
||||
Type '"text"' is not assignable to type 'T'.
|
||||
'"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
|
||||
Type 'T' is not assignable to type 'T & "text"'.
|
||||
Type '"text" | "email"' is not assignable to type 'T & "text"'.
|
||||
Type '"text"' is not assignable to type 'T & "text"'.
|
||||
Type '"text"' is not assignable to type 'T'.
|
||||
'"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
|
||||
Type 'T' is not assignable to type '"text"'.
|
||||
Type '"text" | "email"' is not assignable to type '"text"'.
|
||||
Type '"email"' is not assignable to type '"text"'.
|
||||
Type 'T' is not assignable to type 'T & "text"'.
|
||||
Type '"text" | "email"' is not assignable to type 'T & "text"'.
|
||||
Type '"text"' is not assignable to type 'T & "text"'.
|
||||
Type '"text"' is not assignable to type 'T'.
|
||||
'"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
|
||||
Type 'T' is not assignable to type '"text"'.
|
||||
Type '"text" | "email"' is not assignable to type '"text"'.
|
||||
Type '"email"' is not assignable to type '"text"'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.ts (1 errors) ====
|
||||
|
@ -67,16 +65,14 @@ tests/cases/compiler/complicatedIndexedAccessKeyofReliesOnKeyofNeverUpperBound.t
|
|||
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'ChannelOfType<T, TextChannel>["type"]'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'T'.
|
||||
!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'T & "text"'.
|
||||
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'T & "text"'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'T'.
|
||||
!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type '"text"'.
|
||||
!!! error TS2322: Type '"text" | "email"' is not assignable to type '"text"'.
|
||||
!!! error TS2322: Type '"email"' is not assignable to type '"text"'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'T & "text"'.
|
||||
!!! error TS2322: Type '"text" | "email"' is not assignable to type 'T & "text"'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'T & "text"'.
|
||||
!!! error TS2322: Type '"text"' is not assignable to type 'T'.
|
||||
!!! error TS2322: '"text"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '"text" | "email"'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type '"text"'.
|
||||
!!! error TS2322: Type '"text" | "email"' is not assignable to type '"text"'.
|
||||
!!! error TS2322: Type '"email"' is not assignable to type '"text"'.
|
||||
}
|
||||
|
||||
const newTextChannel = makeNewChannel('text');
|
||||
|
|
|
@ -46,4 +46,23 @@ tests/cases/compiler/deepComparisons.ts(4,9): error TS2322: Type 'T[K1][K2]' is
|
|||
|
||||
function f3<U>() {
|
||||
let x: Foo1<U> = 0 as any as Bar<U>; // No error!
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #46500
|
||||
|
||||
type F<T> = {} & (
|
||||
T extends [any, ...any[]]
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
: T extends any[]
|
||||
? F<T[number]>[]
|
||||
: T extends { [K: string]: any }
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
: { x: string }
|
||||
);
|
||||
|
||||
declare function f<T = any>(): F<T>;
|
||||
|
||||
function g() {
|
||||
return f() as F<any>;
|
||||
}
|
||||
|
|
@ -17,7 +17,26 @@ type Foo2<T> = { x: Foo1<T> };
|
|||
|
||||
function f3<U>() {
|
||||
let x: Foo1<U> = 0 as any as Bar<U>; // No error!
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #46500
|
||||
|
||||
type F<T> = {} & (
|
||||
T extends [any, ...any[]]
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
: T extends any[]
|
||||
? F<T[number]>[]
|
||||
: T extends { [K: string]: any }
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
: { x: string }
|
||||
);
|
||||
|
||||
declare function f<T = any>(): F<T>;
|
||||
|
||||
function g() {
|
||||
return f() as F<any>;
|
||||
}
|
||||
|
||||
|
||||
//// [deepComparisons.js]
|
||||
function f1() {
|
||||
|
@ -31,3 +50,6 @@ function f2() {
|
|||
function f3() {
|
||||
var x = 0; // No error!
|
||||
}
|
||||
function g() {
|
||||
return f();
|
||||
}
|
||||
|
|
|
@ -84,3 +84,57 @@ function f3<U>() {
|
|||
>Bar : Symbol(Bar, Decl(deepComparisons.ts, 6, 28))
|
||||
>U : Symbol(U, Decl(deepComparisons.ts, 16, 12))
|
||||
}
|
||||
|
||||
// Repro from #46500
|
||||
|
||||
type F<T> = {} & (
|
||||
>F : Symbol(F, Decl(deepComparisons.ts, 18, 1))
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
|
||||
T extends [any, ...any[]]
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
>K : Symbol(K, Decl(deepComparisons.ts, 24, 13))
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
>F : Symbol(F, Decl(deepComparisons.ts, 18, 1))
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
>K : Symbol(K, Decl(deepComparisons.ts, 24, 13))
|
||||
|
||||
: T extends any[]
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
|
||||
? F<T[number]>[]
|
||||
>F : Symbol(F, Decl(deepComparisons.ts, 18, 1))
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
|
||||
: T extends { [K: string]: any }
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
>K : Symbol(K, Decl(deepComparisons.ts, 27, 27))
|
||||
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
>K : Symbol(K, Decl(deepComparisons.ts, 28, 21))
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
>F : Symbol(F, Decl(deepComparisons.ts, 18, 1))
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 22, 7))
|
||||
>K : Symbol(K, Decl(deepComparisons.ts, 28, 21))
|
||||
|
||||
: { x: string }
|
||||
>x : Symbol(x, Decl(deepComparisons.ts, 29, 19))
|
||||
|
||||
);
|
||||
|
||||
declare function f<T = any>(): F<T>;
|
||||
>f : Symbol(f, Decl(deepComparisons.ts, 30, 2))
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 32, 19))
|
||||
>F : Symbol(F, Decl(deepComparisons.ts, 18, 1))
|
||||
>T : Symbol(T, Decl(deepComparisons.ts, 32, 19))
|
||||
|
||||
function g() {
|
||||
>g : Symbol(g, Decl(deepComparisons.ts, 32, 36))
|
||||
|
||||
return f() as F<any>;
|
||||
>f : Symbol(f, Decl(deepComparisons.ts, 30, 2))
|
||||
>F : Symbol(F, Decl(deepComparisons.ts, 18, 1))
|
||||
}
|
||||
|
||||
|
|
|
@ -56,3 +56,34 @@ function f3<U>() {
|
|||
>0 as any : any
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
// Repro from #46500
|
||||
|
||||
type F<T> = {} & (
|
||||
>F : F<T>
|
||||
|
||||
T extends [any, ...any[]]
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
: T extends any[]
|
||||
? F<T[number]>[]
|
||||
: T extends { [K: string]: any }
|
||||
>K : string
|
||||
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
: { x: string }
|
||||
>x : string
|
||||
|
||||
);
|
||||
|
||||
declare function f<T = any>(): F<T>;
|
||||
>f : <T = any>() => F<T>
|
||||
|
||||
function g() {
|
||||
>g : () => F<any>
|
||||
|
||||
return f() as F<any>;
|
||||
>f() as F<any> : F<any>
|
||||
>f() : F<any>
|
||||
>f : <T = any>() => F<T>
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(20,1): e
|
|||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(23,1): error TS2322: Type 'A | B' is not assignable to type '(A & B) | (C & D)'.
|
||||
Type 'A' is not assignable to type '(A & B) | (C & D)'.
|
||||
Type 'A' is not assignable to type 'A & B'.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(25,1): error TS2322: Type 'C | D' is not assignable to type '(A & B) | (C & D)'.
|
||||
Type 'C' is not assignable to type '(A & B) | (C & D)'.
|
||||
Type 'C' is not assignable to type 'C & D'.
|
||||
|
@ -80,7 +79,6 @@ tests/cases/conformance/types/intersection/intersectionAndUnionTypes.ts(37,1): e
|
|||
!!! error TS2322: Type 'A | B' is not assignable to type '(A & B) | (C & D)'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type '(A & B) | (C & D)'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'A & B'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
x = cnd; // Ok
|
||||
x = cod;
|
||||
~
|
||||
|
|
|
@ -33,8 +33,11 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(82,5): error
|
|||
Type 'string | number | symbol' is not assignable to type 'keyof U'.
|
||||
Type 'string' is not assignable to type 'keyof U'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(83,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
|
||||
Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
|
||||
Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(87,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
|
||||
Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(103,9): error TS2322: Type 'Extract<keyof T, string>' is not assignable to type 'K'.
|
||||
'Extract<keyof T, string>' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'.
|
||||
Type 'string & keyof T' is not assignable to type 'K'.
|
||||
|
@ -209,14 +212,17 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(142,5): error
|
|||
k1 = k4; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
|
||||
|
||||
k2 = k1;
|
||||
k2 = k3; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
|
||||
k2 = k4; // Error
|
||||
~~
|
||||
!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'.
|
||||
|
||||
k3 = k1;
|
||||
k3 = k2;
|
||||
|
|
|
@ -6,14 +6,12 @@ tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(38,4): error TS2
|
|||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(39,1): error TS2684: The 'this' context of type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' is not assignable to method's 'this' of type 'B'.
|
||||
Property 'b' is missing in type 'A & C & { f0: F0 | F3; f1: F1 | F3; f2: F1 | F4; f3: F3 | F4; f4: F3 | F5; }' but required in type 'B'.
|
||||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(48,1): error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'.
|
||||
Type 'void' is not assignable to type 'A'.
|
||||
tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(55,1): error TS2769: No overload matches this call.
|
||||
Overload 1 of 2, '(this: A & B & C): void', gave the following error.
|
||||
The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B & C'.
|
||||
Type 'void' is not assignable to type 'A'.
|
||||
Overload 2 of 2, '(this: A & B): void', gave the following error.
|
||||
The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'.
|
||||
Type 'void' is not assignable to type 'A'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/union/unionTypeCallSignatures6.ts (6 errors) ====
|
||||
|
@ -79,7 +77,6 @@ tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(55,1): error TS2
|
|||
f3(); // error
|
||||
~~~~
|
||||
!!! error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'.
|
||||
!!! error TS2684: Type 'void' is not assignable to type 'A'.
|
||||
|
||||
interface F7 {
|
||||
(this: A & B & C): void;
|
||||
|
@ -94,5 +91,4 @@ tests/cases/conformance/types/union/unionTypeCallSignatures6.ts(55,1): error TS2
|
|||
!!! error TS2769: Type 'void' is not assignable to type 'A'.
|
||||
!!! error TS2769: Overload 2 of 2, '(this: A & B): void', gave the following error.
|
||||
!!! error TS2769: The 'this' context of type 'void' is not assignable to method's 'this' of type 'A & B'.
|
||||
!!! error TS2769: Type 'void' is not assignable to type 'A'.
|
||||
|
|
@ -16,4 +16,22 @@ type Foo2<T> = { x: Foo1<T> };
|
|||
|
||||
function f3<U>() {
|
||||
let x: Foo1<U> = 0 as any as Bar<U>; // No error!
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #46500
|
||||
|
||||
type F<T> = {} & (
|
||||
T extends [any, ...any[]]
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
: T extends any[]
|
||||
? F<T[number]>[]
|
||||
: T extends { [K: string]: any }
|
||||
? { [K in keyof T]?: F<T[K]> }
|
||||
: { x: string }
|
||||
);
|
||||
|
||||
declare function f<T = any>(): F<T>;
|
||||
|
||||
function g() {
|
||||
return f() as F<any>;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue