Merge pull request #31838 from microsoft/emptyIntersectionReduction

Empty intersection reduction
This commit is contained in:
Anders Hejlsberg
2019-06-11 12:25:51 -07:00
committed by GitHub
51 changed files with 1078 additions and 229 deletions
+25 -35
View File
@@ -9522,44 +9522,13 @@ namespace ts {
return false;
}
// Return true if the given intersection type contains
// more than one unit type or,
// an object type and a nullable type (null or undefined), or
// a string-like type and a type known to be non-string-like, or
// a number-like type and a type known to be non-number-like, or
// a symbol-like type and a type known to be non-symbol-like, or
// a void-like type and a type known to be non-void-like, or
// a non-primitive type and a type known to be primitive.
function isEmptyIntersectionType(type: IntersectionType) {
let combined: TypeFlags = 0;
for (const t of type.types) {
if (t.flags & TypeFlags.Unit && combined & TypeFlags.Unit) {
return true;
}
combined |= t.flags;
if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive) ||
combined & TypeFlags.NonPrimitive && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) ||
combined & TypeFlags.StringLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) ||
combined & TypeFlags.NumberLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) ||
combined & TypeFlags.BigIntLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) ||
combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) ||
combined & TypeFlags.VoidLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) {
return true;
}
}
return false;
}
function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) {
const flags = type.flags;
if (flags & TypeFlags.Union) {
return addTypesToUnion(typeSet, includes, (<UnionType>type).types);
}
// We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are
// another form of 'never' (in that they have an empty value domain). We could in theory turn
// intersections of unit types into 'never' upon construction, but deferring the reduction makes it
// easier to reason about their origin.
if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(<IntersectionType>type))) {
// We ignore 'never' types in unions
if (!(flags & TypeFlags.Never)) {
includes |= flags & TypeFlags.IncludesMask;
if (flags & TypeFlags.StructuredOrInstantiable) includes |= TypeFlags.IncludesStructuredOrInstantiable;
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
@@ -9783,13 +9752,18 @@ namespace ts {
}
}
else {
includes |= flags & TypeFlags.IncludesMask;
if (flags & TypeFlags.AnyOrUnknown) {
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
}
else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
if (type.flags & TypeFlags.Unit && includes & TypeFlags.Unit) {
// We have seen two distinct unit types which means we should reduce to an
// empty intersection. Adding TypeFlags.NonPrimitive causes that to happen.
includes |= TypeFlags.NonPrimitive;
}
typeSet.push(type);
}
includes |= flags & TypeFlags.IncludesMask;
}
return includes;
}
@@ -9905,7 +9879,23 @@ namespace ts {
function getIntersectionType(types: ReadonlyArray<Type>, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray<Type>): Type {
const typeSet: Type[] = [];
const includes = addTypesToIntersection(typeSet, 0, types);
if (includes & TypeFlags.Never) {
// An intersection type is considered empty if it contains
// the type never, or
// more than one unit type or,
// an object type and a nullable type (null or undefined), or
// a string-like type and a type known to be non-string-like, or
// a number-like type and a type known to be non-number-like, or
// a symbol-like type and a type known to be non-symbol-like, or
// a void-like type and a type known to be non-void-like, or
// a non-primitive type and a type known to be primitive.
if (includes & TypeFlags.Never ||
strictNullChecks && includes & TypeFlags.Nullable && includes & (TypeFlags.Object | TypeFlags.NonPrimitive | TypeFlags.IncludesEmptyObject) ||
includes & TypeFlags.NonPrimitive && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) ||
includes & TypeFlags.StringLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) ||
includes & TypeFlags.NumberLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) ||
includes & TypeFlags.BigIntLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.BigIntLike) ||
includes & TypeFlags.ESSymbolLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) ||
includes & TypeFlags.VoidLike && includes & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) {
return neverType;
}
if (includes & TypeFlags.Any) {
+1 -1
View File
@@ -3983,7 +3983,7 @@ namespace ts {
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable,
// The following flags are aggregated during union and intersection type construction
/* @internal */
IncludesMask = Any | Unknown | Primitive | Never | Object | Union,
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | NonPrimitive,
// The following flags are used for different purposes during union and intersection type construction
/* @internal */
IncludesStructuredOrInstantiable = TypeParameter,
@@ -69,8 +69,8 @@ declare function genericFn3<
// Should be never
const result5 = genericFn3({ g: "gtest", h: "htest" }, "g", "h"); // 'g' & 'h' will reduce to never
>result5 : unknown
>genericFn3({ g: "gtest", h: "htest" }, "g", "h") : unknown
>result5 : never
>genericFn3({ g: "gtest", h: "htest" }, "g", "h") : never
>genericFn3 : <T extends { [K in keyof T]: T[K]; }, U extends keyof T, V extends keyof T>(obj: T, u: U, v: V) => T[U & V]
>{ g: "gtest", h: "htest" } : { g: string; h: string; }
>g : string
@@ -107,7 +107,7 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(145,40): error TS2322:
type T50 = X3<{}>; // never
type T51 = X3<{ a: (x: string) => void }>; // never
type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never
type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number
type T60 = infer U; // Error
+1 -1
View File
@@ -69,7 +69,7 @@ type X3<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U
type T50 = X3<{}>; // never
type T51 = X3<{ a: (x: string) => void }>; // never
type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never
type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number
type T60 = infer U; // Error
@@ -297,7 +297,7 @@ type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string
>b : Symbol(b, Decl(inferTypes1.ts, 69, 39))
>x : Symbol(x, Decl(inferTypes1.ts, 69, 44))
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never
>T53 : Symbol(T53, Decl(inferTypes1.ts, 69, 66))
>X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52))
>a : Symbol(a, Decl(inferTypes1.ts, 70, 15))
+2 -2
View File
@@ -211,8 +211,8 @@ type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string
>b : (x: string) => void
>x : string
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number
>T53 : number & string
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never
>T53 : never
>a : (x: number) => void
>x : number
>b : (x: string) => void
@@ -0,0 +1,66 @@
tests/cases/conformance/types/intersection/intersectionReduction.ts(40,1): error TS2322: Type 'any' is not assignable to type 'never'.
tests/cases/conformance/types/intersection/intersectionReduction.ts(41,1): error TS2322: Type 'any' is not assignable to type 'never'.
==== tests/cases/conformance/types/intersection/intersectionReduction.ts (2 errors) ====
declare const sym1: unique symbol;
declare const sym2: unique symbol;
type T1 = string & 'a'; // 'a'
type T2 = 'a' & string & 'b'; // never
type T3 = number & 10; // 10
type T4 = 10 & number & 20; // never
type T5 = symbol & typeof sym1; // typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // never
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
type T10 = string & ('a' | 'b'); // 'a' | 'b'
type T11 = (string | number) & ('a' | 10); // 'a' | 10
type N1 = 'a' & 'b';
type N2 = { a: string } & null;
type N3 = { a: string } & undefined;
type N4 = string & number;
type N5 = number & object;
type N6 = symbol & string;
type N7 = void & string;
type X = { x: string };
type X1 = X | 'a' & 'b';
type X2 = X | { a: string } & null;
type X3 = X | { a: string } & undefined;
type X4 = X | string & number;
type X5 = X | number & object;
type X6 = X | symbol & string;
type X7 = X | void & string;
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
const x2 = { a: 'foo', b: true };
declare let k: 'a' | 'b';
x1[k] = 'bar' as any; // Error
~~~~~
!!! error TS2322: Type 'any' is not assignable to type 'never'.
x2[k] = 'bar' as any; // Error
~~~~~
!!! error TS2322: Type 'any' is not assignable to type 'never'.
const enum Tag1 {}
const enum Tag2 {}
declare let s1: string & Tag1;
declare let s2: string & Tag2;
declare let t1: string & Tag1 | undefined;
declare let t2: string & Tag2 | undefined;
s1 = s2;
s2 = s1;
t1 = t2;
t2 = t1;
@@ -1,20 +1,69 @@
//// [intersectionReduction.ts]
// @strict
declare const sym1: unique symbol;
declare const sym2: unique symbol;
type T1 = string & 'a'; // 'a'
type T2 = 'a' & string & 'b'; // 'a' & 'b'
type T2 = 'a' & string & 'b'; // never
type T3 = number & 10; // 10
type T4 = 10 & number & 20; // 10 & 20
type T4 = 10 & number & 20; // never
type T5 = symbol & typeof sym1; // typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // never
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
type T10 = string & ('a' | 'b'); // 'a' | 'b'
type T11 = (string | number) & ('a' | 10); // 'a' | 10
type N1 = 'a' & 'b';
type N2 = { a: string } & null;
type N3 = { a: string } & undefined;
type N4 = string & number;
type N5 = number & object;
type N6 = symbol & string;
type N7 = void & string;
type X = { x: string };
type X1 = X | 'a' & 'b';
type X2 = X | { a: string } & null;
type X3 = X | { a: string } & undefined;
type X4 = X | string & number;
type X5 = X | number & object;
type X6 = X | symbol & string;
type X7 = X | void & string;
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
const x2 = { a: 'foo', b: true };
declare let k: 'a' | 'b';
x1[k] = 'bar' as any; // Error
x2[k] = 'bar' as any; // Error
const enum Tag1 {}
const enum Tag2 {}
declare let s1: string & Tag1;
declare let s2: string & Tag2;
declare let t1: string & Tag1 | undefined;
declare let t2: string & Tag2 | undefined;
s1 = s2;
s2 = s1;
t1 = t2;
t2 = t1;
//// [intersectionReduction.js]
// @strict
// Repro from #31663
var x1 = { a: 'foo', b: 42 };
var x2 = { a: 'foo', b: true };
x1[k] = 'bar'; // Error
x2[k] = 'bar'; // Error
s1 = s2;
s2 = s1;
t1 = t2;
t2 = t1;
@@ -1,40 +1,156 @@
=== tests/cases/conformance/types/intersection/intersectionReduction.ts ===
// @strict
declare const sym1: unique symbol;
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 0, 13))
declare const sym2: unique symbol;
>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13))
>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 1, 13))
type T1 = string & 'a'; // 'a'
>T1 : Symbol(T1, Decl(intersectionReduction.ts, 3, 34))
>T1 : Symbol(T1, Decl(intersectionReduction.ts, 1, 34))
type T2 = 'a' & string & 'b'; // 'a' & 'b'
>T2 : Symbol(T2, Decl(intersectionReduction.ts, 5, 23))
type T2 = 'a' & string & 'b'; // never
>T2 : Symbol(T2, Decl(intersectionReduction.ts, 3, 23))
type T3 = number & 10; // 10
>T3 : Symbol(T3, Decl(intersectionReduction.ts, 6, 29))
>T3 : Symbol(T3, Decl(intersectionReduction.ts, 4, 29))
type T4 = 10 & number & 20; // 10 & 20
>T4 : Symbol(T4, Decl(intersectionReduction.ts, 7, 22))
type T4 = 10 & number & 20; // never
>T4 : Symbol(T4, Decl(intersectionReduction.ts, 5, 22))
type T5 = symbol & typeof sym1; // typeof sym1
>T5 : Symbol(T5, Decl(intersectionReduction.ts, 8, 27))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13))
>T5 : Symbol(T5, Decl(intersectionReduction.ts, 6, 27))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 0, 13))
type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2
>T6 : Symbol(T6, Decl(intersectionReduction.ts, 9, 31))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13))
>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13))
type T6 = typeof sym1 & symbol & typeof sym2; // never
>T6 : Symbol(T6, Decl(intersectionReduction.ts, 7, 31))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 0, 13))
>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 1, 13))
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1
>T7 : Symbol(T7, Decl(intersectionReduction.ts, 10, 45))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13))
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
>T7 : Symbol(T7, Decl(intersectionReduction.ts, 8, 45))
>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 0, 13))
type T10 = string & ('a' | 'b'); // 'a' | 'b'
>T10 : Symbol(T10, Decl(intersectionReduction.ts, 11, 60))
>T10 : Symbol(T10, Decl(intersectionReduction.ts, 9, 60))
type T11 = (string | number) & ('a' | 10); // 'a' | 10
>T11 : Symbol(T11, Decl(intersectionReduction.ts, 13, 32))
>T11 : Symbol(T11, Decl(intersectionReduction.ts, 11, 32))
type N1 = 'a' & 'b';
>N1 : Symbol(N1, Decl(intersectionReduction.ts, 12, 42))
type N2 = { a: string } & null;
>N2 : Symbol(N2, Decl(intersectionReduction.ts, 14, 20))
>a : Symbol(a, Decl(intersectionReduction.ts, 15, 11))
type N3 = { a: string } & undefined;
>N3 : Symbol(N3, Decl(intersectionReduction.ts, 15, 31))
>a : Symbol(a, Decl(intersectionReduction.ts, 16, 11))
type N4 = string & number;
>N4 : Symbol(N4, Decl(intersectionReduction.ts, 16, 36))
type N5 = number & object;
>N5 : Symbol(N5, Decl(intersectionReduction.ts, 17, 26))
type N6 = symbol & string;
>N6 : Symbol(N6, Decl(intersectionReduction.ts, 18, 26))
type N7 = void & string;
>N7 : Symbol(N7, Decl(intersectionReduction.ts, 19, 26))
type X = { x: string };
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
>x : Symbol(x, Decl(intersectionReduction.ts, 22, 10))
type X1 = X | 'a' & 'b';
>X1 : Symbol(X1, Decl(intersectionReduction.ts, 22, 23))
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
type X2 = X | { a: string } & null;
>X2 : Symbol(X2, Decl(intersectionReduction.ts, 24, 24))
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
>a : Symbol(a, Decl(intersectionReduction.ts, 25, 15))
type X3 = X | { a: string } & undefined;
>X3 : Symbol(X3, Decl(intersectionReduction.ts, 25, 35))
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
>a : Symbol(a, Decl(intersectionReduction.ts, 26, 15))
type X4 = X | string & number;
>X4 : Symbol(X4, Decl(intersectionReduction.ts, 26, 40))
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
type X5 = X | number & object;
>X5 : Symbol(X5, Decl(intersectionReduction.ts, 27, 30))
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
type X6 = X | symbol & string;
>X6 : Symbol(X6, Decl(intersectionReduction.ts, 28, 30))
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
type X7 = X | void & string;
>X7 : Symbol(X7, Decl(intersectionReduction.ts, 29, 30))
>X : Symbol(X, Decl(intersectionReduction.ts, 20, 24))
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
>x1 : Symbol(x1, Decl(intersectionReduction.ts, 34, 5))
>a : Symbol(a, Decl(intersectionReduction.ts, 34, 12))
>b : Symbol(b, Decl(intersectionReduction.ts, 34, 22))
const x2 = { a: 'foo', b: true };
>x2 : Symbol(x2, Decl(intersectionReduction.ts, 35, 5))
>a : Symbol(a, Decl(intersectionReduction.ts, 35, 12))
>b : Symbol(b, Decl(intersectionReduction.ts, 35, 22))
declare let k: 'a' | 'b';
>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11))
x1[k] = 'bar' as any; // Error
>x1 : Symbol(x1, Decl(intersectionReduction.ts, 34, 5))
>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11))
x2[k] = 'bar' as any; // Error
>x2 : Symbol(x2, Decl(intersectionReduction.ts, 35, 5))
>k : Symbol(k, Decl(intersectionReduction.ts, 37, 11))
const enum Tag1 {}
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21))
const enum Tag2 {}
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18))
declare let s1: string & Tag1;
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11))
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21))
declare let s2: string & Tag2;
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11))
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18))
declare let t1: string & Tag1 | undefined;
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11))
>Tag1 : Symbol(Tag1, Decl(intersectionReduction.ts, 40, 21))
declare let t2: string & Tag2 | undefined;
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11))
>Tag2 : Symbol(Tag2, Decl(intersectionReduction.ts, 42, 18))
s1 = s2;
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11))
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11))
s2 = s1;
>s2 : Symbol(s2, Decl(intersectionReduction.ts, 46, 11))
>s1 : Symbol(s1, Decl(intersectionReduction.ts, 45, 11))
t1 = t2;
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11))
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11))
t2 = t1;
>t2 : Symbol(t2, Decl(intersectionReduction.ts, 49, 11))
>t1 : Symbol(t1, Decl(intersectionReduction.ts, 48, 11))
@@ -1,6 +1,4 @@
=== tests/cases/conformance/types/intersection/intersectionReduction.ts ===
// @strict
declare const sym1: unique symbol;
>sym1 : unique symbol
@@ -10,26 +8,26 @@ declare const sym2: unique symbol;
type T1 = string & 'a'; // 'a'
>T1 : "a"
type T2 = 'a' & string & 'b'; // 'a' & 'b'
>T2 : T2
type T2 = 'a' & string & 'b'; // never
>T2 : never
type T3 = number & 10; // 10
>T3 : 10
type T4 = 10 & number & 20; // 10 & 20
>T4 : T4
type T4 = 10 & number & 20; // never
>T4 : never
type T5 = symbol & typeof sym1; // typeof sym1
>T5 : unique symbol
>sym1 : unique symbol
type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2
>T6 : T6
type T6 = typeof sym1 & symbol & typeof sym2; // never
>T6 : never
>sym1 : unique symbol
>sym2 : unique symbol
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1
>T7 : T7
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
>T7 : never
>sym1 : unique symbol
type T10 = string & ('a' | 'b'); // 'a' | 'b'
@@ -38,3 +36,130 @@ type T10 = string & ('a' | 'b'); // 'a' | 'b'
type T11 = (string | number) & ('a' | 10); // 'a' | 10
>T11 : "a" | 10
type N1 = 'a' & 'b';
>N1 : never
type N2 = { a: string } & null;
>N2 : null
>a : string
>null : null
type N3 = { a: string } & undefined;
>N3 : undefined
>a : string
type N4 = string & number;
>N4 : never
type N5 = number & object;
>N5 : never
type N6 = symbol & string;
>N6 : never
type N7 = void & string;
>N7 : never
type X = { x: string };
>X : X
>x : string
type X1 = X | 'a' & 'b';
>X1 : X
type X2 = X | { a: string } & null;
>X2 : X
>a : string
>null : null
type X3 = X | { a: string } & undefined;
>X3 : X
>a : string
type X4 = X | string & number;
>X4 : X
type X5 = X | number & object;
>X5 : X
type X6 = X | symbol & string;
>X6 : X
type X7 = X | void & string;
>X7 : X
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
>x1 : { a: string; b: number; }
>{ a: 'foo', b: 42 } : { a: string; b: number; }
>a : string
>'foo' : "foo"
>b : number
>42 : 42
const x2 = { a: 'foo', b: true };
>x2 : { a: string; b: boolean; }
>{ a: 'foo', b: true } : { a: string; b: boolean; }
>a : string
>'foo' : "foo"
>b : boolean
>true : true
declare let k: 'a' | 'b';
>k : "a" | "b"
x1[k] = 'bar' as any; // Error
>x1[k] = 'bar' as any : any
>x1[k] : never
>x1 : { a: string; b: number; }
>k : "a" | "b"
>'bar' as any : any
>'bar' : "bar"
x2[k] = 'bar' as any; // Error
>x2[k] = 'bar' as any : any
>x2[k] : never
>x2 : { a: string; b: boolean; }
>k : "a" | "b"
>'bar' as any : any
>'bar' : "bar"
const enum Tag1 {}
>Tag1 : Tag1
const enum Tag2 {}
>Tag2 : Tag2
declare let s1: string & Tag1;
>s1 : never
declare let s2: string & Tag2;
>s2 : never
declare let t1: string & Tag1 | undefined;
>t1 : undefined
declare let t2: string & Tag2 | undefined;
>t2 : undefined
s1 = s2;
>s1 = s2 : never
>s1 : never
>s2 : never
s2 = s1;
>s2 = s1 : never
>s2 : never
>s1 : never
t1 = t2;
>t1 = t2 : undefined
>t1 : undefined
>t2 : undefined
t2 = t1;
>t2 = t1 : undefined
>t2 : undefined
>t1 : undefined
@@ -0,0 +1,66 @@
tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(40,1): error TS2322: Type 'any' is not assignable to type 'never'.
tests/cases/conformance/types/intersection/intersectionReductionStrict.ts(41,1): error TS2322: Type 'any' is not assignable to type 'never'.
==== tests/cases/conformance/types/intersection/intersectionReductionStrict.ts (2 errors) ====
declare const sym1: unique symbol;
declare const sym2: unique symbol;
type T1 = string & 'a'; // 'a'
type T2 = 'a' & string & 'b'; // never
type T3 = number & 10; // 10
type T4 = 10 & number & 20; // never
type T5 = symbol & typeof sym1; // typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // never
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
type T10 = string & ('a' | 'b'); // 'a' | 'b'
type T11 = (string | number) & ('a' | 10); // 'a' | 10
type N1 = 'a' & 'b';
type N2 = { a: string } & null;
type N3 = { a: string } & undefined;
type N4 = string & number;
type N5 = number & object;
type N6 = symbol & string;
type N7 = void & string;
type X = { x: string };
type X1 = X | 'a' & 'b';
type X2 = X | { a: string } & null;
type X3 = X | { a: string } & undefined;
type X4 = X | string & number;
type X5 = X | number & object;
type X6 = X | symbol & string;
type X7 = X | void & string;
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
const x2 = { a: 'foo', b: true };
declare let k: 'a' | 'b';
x1[k] = 'bar' as any; // Error
~~~~~
!!! error TS2322: Type 'any' is not assignable to type 'never'.
x2[k] = 'bar' as any; // Error
~~~~~
!!! error TS2322: Type 'any' is not assignable to type 'never'.
const enum Tag1 {}
const enum Tag2 {}
declare let s1: string & Tag1;
declare let s2: string & Tag2;
declare let t1: string & Tag1 | undefined;
declare let t2: string & Tag2 | undefined;
s1 = s2;
s2 = s1;
t1 = t2;
t2 = t1;
@@ -0,0 +1,70 @@
//// [intersectionReductionStrict.ts]
declare const sym1: unique symbol;
declare const sym2: unique symbol;
type T1 = string & 'a'; // 'a'
type T2 = 'a' & string & 'b'; // never
type T3 = number & 10; // 10
type T4 = 10 & number & 20; // never
type T5 = symbol & typeof sym1; // typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // never
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
type T10 = string & ('a' | 'b'); // 'a' | 'b'
type T11 = (string | number) & ('a' | 10); // 'a' | 10
type N1 = 'a' & 'b';
type N2 = { a: string } & null;
type N3 = { a: string } & undefined;
type N4 = string & number;
type N5 = number & object;
type N6 = symbol & string;
type N7 = void & string;
type X = { x: string };
type X1 = X | 'a' & 'b';
type X2 = X | { a: string } & null;
type X3 = X | { a: string } & undefined;
type X4 = X | string & number;
type X5 = X | number & object;
type X6 = X | symbol & string;
type X7 = X | void & string;
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
const x2 = { a: 'foo', b: true };
declare let k: 'a' | 'b';
x1[k] = 'bar' as any; // Error
x2[k] = 'bar' as any; // Error
const enum Tag1 {}
const enum Tag2 {}
declare let s1: string & Tag1;
declare let s2: string & Tag2;
declare let t1: string & Tag1 | undefined;
declare let t2: string & Tag2 | undefined;
s1 = s2;
s2 = s1;
t1 = t2;
t2 = t1;
//// [intersectionReductionStrict.js]
"use strict";
// Repro from #31663
var x1 = { a: 'foo', b: 42 };
var x2 = { a: 'foo', b: true };
x1[k] = 'bar'; // Error
x2[k] = 'bar'; // Error
s1 = s2;
s2 = s1;
t1 = t2;
t2 = t1;
@@ -0,0 +1,156 @@
=== tests/cases/conformance/types/intersection/intersectionReductionStrict.ts ===
declare const sym1: unique symbol;
>sym1 : Symbol(sym1, Decl(intersectionReductionStrict.ts, 0, 13))
declare const sym2: unique symbol;
>sym2 : Symbol(sym2, Decl(intersectionReductionStrict.ts, 1, 13))
type T1 = string & 'a'; // 'a'
>T1 : Symbol(T1, Decl(intersectionReductionStrict.ts, 1, 34))
type T2 = 'a' & string & 'b'; // never
>T2 : Symbol(T2, Decl(intersectionReductionStrict.ts, 3, 23))
type T3 = number & 10; // 10
>T3 : Symbol(T3, Decl(intersectionReductionStrict.ts, 4, 29))
type T4 = 10 & number & 20; // never
>T4 : Symbol(T4, Decl(intersectionReductionStrict.ts, 5, 22))
type T5 = symbol & typeof sym1; // typeof sym1
>T5 : Symbol(T5, Decl(intersectionReductionStrict.ts, 6, 27))
>sym1 : Symbol(sym1, Decl(intersectionReductionStrict.ts, 0, 13))
type T6 = typeof sym1 & symbol & typeof sym2; // never
>T6 : Symbol(T6, Decl(intersectionReductionStrict.ts, 7, 31))
>sym1 : Symbol(sym1, Decl(intersectionReductionStrict.ts, 0, 13))
>sym2 : Symbol(sym2, Decl(intersectionReductionStrict.ts, 1, 13))
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
>T7 : Symbol(T7, Decl(intersectionReductionStrict.ts, 8, 45))
>sym1 : Symbol(sym1, Decl(intersectionReductionStrict.ts, 0, 13))
type T10 = string & ('a' | 'b'); // 'a' | 'b'
>T10 : Symbol(T10, Decl(intersectionReductionStrict.ts, 9, 60))
type T11 = (string | number) & ('a' | 10); // 'a' | 10
>T11 : Symbol(T11, Decl(intersectionReductionStrict.ts, 11, 32))
type N1 = 'a' & 'b';
>N1 : Symbol(N1, Decl(intersectionReductionStrict.ts, 12, 42))
type N2 = { a: string } & null;
>N2 : Symbol(N2, Decl(intersectionReductionStrict.ts, 14, 20))
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 15, 11))
type N3 = { a: string } & undefined;
>N3 : Symbol(N3, Decl(intersectionReductionStrict.ts, 15, 31))
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 16, 11))
type N4 = string & number;
>N4 : Symbol(N4, Decl(intersectionReductionStrict.ts, 16, 36))
type N5 = number & object;
>N5 : Symbol(N5, Decl(intersectionReductionStrict.ts, 17, 26))
type N6 = symbol & string;
>N6 : Symbol(N6, Decl(intersectionReductionStrict.ts, 18, 26))
type N7 = void & string;
>N7 : Symbol(N7, Decl(intersectionReductionStrict.ts, 19, 26))
type X = { x: string };
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
>x : Symbol(x, Decl(intersectionReductionStrict.ts, 22, 10))
type X1 = X | 'a' & 'b';
>X1 : Symbol(X1, Decl(intersectionReductionStrict.ts, 22, 23))
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
type X2 = X | { a: string } & null;
>X2 : Symbol(X2, Decl(intersectionReductionStrict.ts, 24, 24))
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 25, 15))
type X3 = X | { a: string } & undefined;
>X3 : Symbol(X3, Decl(intersectionReductionStrict.ts, 25, 35))
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 26, 15))
type X4 = X | string & number;
>X4 : Symbol(X4, Decl(intersectionReductionStrict.ts, 26, 40))
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
type X5 = X | number & object;
>X5 : Symbol(X5, Decl(intersectionReductionStrict.ts, 27, 30))
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
type X6 = X | symbol & string;
>X6 : Symbol(X6, Decl(intersectionReductionStrict.ts, 28, 30))
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
type X7 = X | void & string;
>X7 : Symbol(X7, Decl(intersectionReductionStrict.ts, 29, 30))
>X : Symbol(X, Decl(intersectionReductionStrict.ts, 20, 24))
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
>x1 : Symbol(x1, Decl(intersectionReductionStrict.ts, 34, 5))
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 34, 12))
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 34, 22))
const x2 = { a: 'foo', b: true };
>x2 : Symbol(x2, Decl(intersectionReductionStrict.ts, 35, 5))
>a : Symbol(a, Decl(intersectionReductionStrict.ts, 35, 12))
>b : Symbol(b, Decl(intersectionReductionStrict.ts, 35, 22))
declare let k: 'a' | 'b';
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11))
x1[k] = 'bar' as any; // Error
>x1 : Symbol(x1, Decl(intersectionReductionStrict.ts, 34, 5))
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11))
x2[k] = 'bar' as any; // Error
>x2 : Symbol(x2, Decl(intersectionReductionStrict.ts, 35, 5))
>k : Symbol(k, Decl(intersectionReductionStrict.ts, 37, 11))
const enum Tag1 {}
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21))
const enum Tag2 {}
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18))
declare let s1: string & Tag1;
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11))
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21))
declare let s2: string & Tag2;
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11))
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18))
declare let t1: string & Tag1 | undefined;
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11))
>Tag1 : Symbol(Tag1, Decl(intersectionReductionStrict.ts, 40, 21))
declare let t2: string & Tag2 | undefined;
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11))
>Tag2 : Symbol(Tag2, Decl(intersectionReductionStrict.ts, 42, 18))
s1 = s2;
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11))
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11))
s2 = s1;
>s2 : Symbol(s2, Decl(intersectionReductionStrict.ts, 46, 11))
>s1 : Symbol(s1, Decl(intersectionReductionStrict.ts, 45, 11))
t1 = t2;
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11))
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11))
t2 = t1;
>t2 : Symbol(t2, Decl(intersectionReductionStrict.ts, 49, 11))
>t1 : Symbol(t1, Decl(intersectionReductionStrict.ts, 48, 11))
@@ -0,0 +1,165 @@
=== tests/cases/conformance/types/intersection/intersectionReductionStrict.ts ===
declare const sym1: unique symbol;
>sym1 : unique symbol
declare const sym2: unique symbol;
>sym2 : unique symbol
type T1 = string & 'a'; // 'a'
>T1 : "a"
type T2 = 'a' & string & 'b'; // never
>T2 : never
type T3 = number & 10; // 10
>T3 : 10
type T4 = 10 & number & 20; // never
>T4 : never
type T5 = symbol & typeof sym1; // typeof sym1
>T5 : unique symbol
>sym1 : unique symbol
type T6 = typeof sym1 & symbol & typeof sym2; // never
>T6 : never
>sym1 : unique symbol
>sym2 : unique symbol
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
>T7 : never
>sym1 : unique symbol
type T10 = string & ('a' | 'b'); // 'a' | 'b'
>T10 : "a" | "b"
type T11 = (string | number) & ('a' | 10); // 'a' | 10
>T11 : "a" | 10
type N1 = 'a' & 'b';
>N1 : never
type N2 = { a: string } & null;
>N2 : never
>a : string
>null : null
type N3 = { a: string } & undefined;
>N3 : never
>a : string
type N4 = string & number;
>N4 : never
type N5 = number & object;
>N5 : never
type N6 = symbol & string;
>N6 : never
type N7 = void & string;
>N7 : never
type X = { x: string };
>X : X
>x : string
type X1 = X | 'a' & 'b';
>X1 : X
type X2 = X | { a: string } & null;
>X2 : X
>a : string
>null : null
type X3 = X | { a: string } & undefined;
>X3 : X
>a : string
type X4 = X | string & number;
>X4 : X
type X5 = X | number & object;
>X5 : X
type X6 = X | symbol & string;
>X6 : X
type X7 = X | void & string;
>X7 : X
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
>x1 : { a: string; b: number; }
>{ a: 'foo', b: 42 } : { a: string; b: number; }
>a : string
>'foo' : "foo"
>b : number
>42 : 42
const x2 = { a: 'foo', b: true };
>x2 : { a: string; b: boolean; }
>{ a: 'foo', b: true } : { a: string; b: boolean; }
>a : string
>'foo' : "foo"
>b : boolean
>true : true
declare let k: 'a' | 'b';
>k : "a" | "b"
x1[k] = 'bar' as any; // Error
>x1[k] = 'bar' as any : any
>x1[k] : never
>x1 : { a: string; b: number; }
>k : "a" | "b"
>'bar' as any : any
>'bar' : "bar"
x2[k] = 'bar' as any; // Error
>x2[k] = 'bar' as any : any
>x2[k] : never
>x2 : { a: string; b: boolean; }
>k : "a" | "b"
>'bar' as any : any
>'bar' : "bar"
const enum Tag1 {}
>Tag1 : Tag1
const enum Tag2 {}
>Tag2 : Tag2
declare let s1: string & Tag1;
>s1 : never
declare let s2: string & Tag2;
>s2 : never
declare let t1: string & Tag1 | undefined;
>t1 : undefined
declare let t2: string & Tag2 | undefined;
>t2 : undefined
s1 = s2;
>s1 = s2 : never
>s1 : never
>s2 : never
s2 = s1;
>s2 = s1 : never
>s2 : never
>s1 : never
t1 = t2;
>t1 = t2 : undefined
>t1 : undefined
>t2 : undefined
t2 = t1;
>t2 = t1 : undefined
>t2 : undefined
>t1 : undefined
@@ -4,8 +4,8 @@ declare function f<T>(x: { prop: T }): T;
declare const a: { prop: string } & { prop: number };
declare const b: { prop: string & number };
f(a); // string & number
f(b); // string & number
f(a); // never
f(b); // never
// Repro from #18354
@@ -17,7 +17,7 @@ f2(obj, 'b');
//// [intersectionTypeInference2.js]
f(a); // string & number
f(b); // string & number
f(a); // never
f(b); // never
f2(obj, 'a');
f2(obj, 'b');
@@ -16,11 +16,11 @@ declare const b: { prop: string & number };
>b : Symbol(b, Decl(intersectionTypeInference2.ts, 3, 13))
>prop : Symbol(prop, Decl(intersectionTypeInference2.ts, 3, 18))
f(a); // string & number
f(a); // never
>f : Symbol(f, Decl(intersectionTypeInference2.ts, 0, 0))
>a : Symbol(a, Decl(intersectionTypeInference2.ts, 2, 13))
f(b); // string & number
f(b); // never
>f : Symbol(f, Decl(intersectionTypeInference2.ts, 0, 0))
>b : Symbol(b, Decl(intersectionTypeInference2.ts, 3, 13))
@@ -10,18 +10,18 @@ declare const a: { prop: string } & { prop: number };
>prop : number
declare const b: { prop: string & number };
>b : { prop: string & number; }
>prop : string & number
>b : { prop: never; }
>prop : never
f(a); // string & number
>f(a) : string & number
f(a); // never
>f(a) : never
>f : <T>(x: { prop: T; }) => T
>a : { prop: string; } & { prop: number; }
f(b); // string & number
>f(b) : string & number
f(b); // never
>f(b) : never
>f : <T>(x: { prop: T; }) => T
>b : { prop: string & number; }
>b : { prop: never; }
// Repro from #18354
@@ -17,8 +17,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(31,5): error TS232
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(38,5): error TS2322: Type '{ [x: string]: number; }' is not assignable to type '{ [P in K]: number; }'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(50,3): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Item'.
No index signature with a parameter of type 'string' was found on type 'Item'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(51,3): error TS2322: Type '123' is not assignable to type 'string & number'.
Type '123' is not assignable to type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(51,3): error TS2322: Type '123' is not assignable to type 'never'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(52,3): error TS2322: Type '123' is not assignable to type 'T[keyof T]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(53,3): error TS2322: Type '123' is not assignable to type 'T[K]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(65,7): error TS2339: Property 'foo' does not exist on type 'T'.
@@ -26,8 +25,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(66,3): error TS253
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(67,3): error TS2322: Type '123' is not assignable to type 'T[keyof T]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(68,3): error TS2322: Type '123' is not assignable to type 'T[K]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS2322: Type '123' is not assignable to type 'Type[K]'.
Type '123' is not assignable to type '123 & "some string"'.
Type '123' is not assignable to type '"some string"'.
Type '123' is not assignable to type 'never'.
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts (23 errors) ====
@@ -117,8 +115,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23
!!! error TS7053: No index signature with a parameter of type 'string' was found on type 'Item'.
obj[k2] = 123; // Error
~~~~~~~
!!! error TS2322: Type '123' is not assignable to type 'string & number'.
!!! error TS2322: Type '123' is not assignable to type 'string'.
!!! error TS2322: Type '123' is not assignable to type 'never'.
obj[k3] = 123; // Error
~~~~~~~
!!! error TS2322: Type '123' is not assignable to type 'T[keyof T]'.
@@ -190,8 +187,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23
return 123; // Error
~~~~~~~~~~~
!!! error TS2322: Type '123' is not assignable to type 'Type[K]'.
!!! error TS2322: Type '123' is not assignable to type '123 & "some string"'.
!!! error TS2322: Type '123' is not assignable to type '"some string"'.
!!! error TS2322: Type '123' is not assignable to type 'never'.
}
// Repro from #30920
@@ -249,7 +249,7 @@ function f10<T extends Item, K extends keyof T>(obj: T, k1: string, k2: keyof It
obj[k2] = 123; // Error
>obj[k2] = 123 : 123
>obj[k2] : string & number
>obj[k2] : never
>obj : T
>k2 : "a" | "b"
>123 : 123
@@ -10,7 +10,6 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(27,18): error
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(28,18): error TS2538: Type '{ x: string; }' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'number'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(29,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(30,18): error TS2538: Type 'string & number' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2537: Type 'Shape' has no matching index signature for type 'string'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2538: Type 'false' cannot be used as an index type.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(31,18): error TS2538: Type 'true' cannot be used as an index type.
@@ -81,7 +80,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(141,5): error
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(142,5): error TS2322: Type 'number[]' is not assignable to type 'T[K]'.
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (41 errors) ====
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (40 errors) ====
class Shape {
name: string;
width: number;
@@ -135,9 +134,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(142,5): error
!!! error TS2537: Type 'Shape' has no matching index signature for type 'number'.
~~~~~~~~~~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'string'.
type T21 = Shape[string & number]; // Error
~~~~~~~~~~~~~~~
!!! error TS2538: Type 'string & number' cannot be used as an index type.
type T21 = Shape[string & number];
type T22 = Shape[string | boolean]; // Error
~~~~~~~~~~~~~~~~
!!! error TS2537: Type 'Shape' has no matching index signature for type 'string'.
@@ -28,7 +28,7 @@ type T17 = Shape[void]; // Error
type T18 = Shape[undefined]; // Error
type T19 = Shape[{ x: string }]; // Error
type T20 = Shape[string | number]; // Error
type T21 = Shape[string & number]; // Error
type T21 = Shape[string & number];
type T22 = Shape[string | boolean]; // Error
type T30 = string[]["length"];
@@ -93,7 +93,7 @@ type T20 = Shape[string | number]; // Error
>T20 : Symbol(T20, Decl(keyofAndIndexedAccessErrors.ts, 27, 32))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccessErrors.ts, 0, 0))
type T21 = Shape[string & number]; // Error
type T21 = Shape[string & number];
>T21 : Symbol(T21, Decl(keyofAndIndexedAccessErrors.ts, 28, 34))
>Shape : Symbol(Shape, Decl(keyofAndIndexedAccessErrors.ts, 0, 0))
@@ -74,8 +74,8 @@ type T19 = Shape[{ x: string }]; // Error
type T20 = Shape[string | number]; // Error
>T20 : any
type T21 = Shape[string & number]; // Error
>T21 : any
type T21 = Shape[string & number];
>T21 : never
type T22 = Shape[string | boolean]; // Error
>T22 : any
@@ -1,9 +1,7 @@
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(1,5): error TS2322: Type '""' is not assignable to type 'object & string'.
Type '""' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(1,5): error TS2322: Type '""' is not assignable to type 'never'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(3,5): error TS2322: Type '123' is not assignable to type 'object & {}'.
Type '123' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(4,1): error TS2322: Type 'string' is not assignable to type 'object & string'.
Type 'string' is not assignable to type 'object'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(4,1): error TS2322: Type 'string' is not assignable to type 'never'.
tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(8,38): error TS2322: Type '{ bar: string; }' is not assignable to type 'object & { err: string; }'.
Object literal may only specify known properties, and 'bar' does not exist in type 'object & { err: string; }'.
@@ -11,8 +9,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(8,38
==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts (4 errors) ====
var a: object & string = ""; // error
~
!!! error TS2322: Type '""' is not assignable to type 'object & string'.
!!! error TS2322: Type '""' is not assignable to type 'object'.
!!! error TS2322: Type '""' is not assignable to type 'never'.
var b: object | string = ""; // ok
var c: object & {} = 123; // error
~
@@ -20,8 +17,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts(8,38
!!! error TS2322: Type '123' is not assignable to type 'object'.
a = b; // error
~
!!! error TS2322: Type 'string' is not assignable to type 'object & string'.
!!! error TS2322: Type 'string' is not assignable to type 'object'.
!!! error TS2322: Type 'string' is not assignable to type 'never'.
b = a; // ok
const foo: object & {} = {bar: 'bar'}; // ok
@@ -1,6 +1,6 @@
=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveUnionIntersection.ts ===
var a: object & string = ""; // error
>a : object & string
>a : never
>"" : ""
var b: object | string = ""; // ok
@@ -13,13 +13,13 @@ var c: object & {} = 123; // error
a = b; // error
>a = b : string
>a : object & string
>a : never
>b : string
b = a; // ok
>b = a : object & string
>b = a : never
>b : string | object
>a : object & string
>a : never
const foo: object & {} = {bar: 'bar'}; // ok
>foo : object & {}
+2 -2
View File
@@ -11,7 +11,7 @@ var {...rest4 } = nullAndUndefinedUnion;
>nullAndUndefinedUnion : null | undefined
declare const unionWithIntersection: ({ n: number } & { s: string }) & undefined;
>unionWithIntersection : { n: number; } & { s: string; } & undefined
>unionWithIntersection : never
>n : number
>s : string
@@ -22,5 +22,5 @@ var rest5: { n: number, s: string };
var {...rest5 } = unionWithIntersection;
>rest5 : { n: number; s: string; }
>unionWithIntersection : { n: number; } & { s: string; } & undefined
>unionWithIntersection : never
@@ -1,30 +0,0 @@
tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(22,10): error TS2678: Type 'boolean' is not comparable to type 'string & number'.
==== tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts (1 errors) ====
var strAndNum: string & number;
var numAndBool: number & boolean;
var str: string;
var num: number;
var bool: boolean;
switch (strAndNum) {
// Identical
case strAndNum:
break;
// Constituents
case str:
case num:
break;
// Overlap in constituents
case numAndBool:
break;
// No relation
case bool:
~~~~
!!! error TS2678: Type 'boolean' is not comparable to type 'string & number'.
break;
}
@@ -1,6 +1,6 @@
=== tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts ===
var strAndNum: string & number;
>strAndNum : string & number
>strAndNum : never
var numAndBool: number & boolean;
>numAndBool : never
@@ -15,11 +15,11 @@ var bool: boolean;
>bool : boolean
switch (strAndNum) {
>strAndNum : string & number
>strAndNum : never
// Identical
case strAndNum:
>strAndNum : string & number
>strAndNum : never
break;
@@ -1,5 +1,4 @@
tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'string' is not assignable to type 'number & string'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'string' is not assignable to type 'never'.
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
@@ -36,8 +35,7 @@ tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'string' is not
// OK
let a = <RCComp x="Hi" />;
~
!!! error TS2322: Type 'string' is not assignable to type 'number & string'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'never'.
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<RC1 | RC2> & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }'
let a1 = <EmptyRCComp />;
let a2 = <EmptyRCComp data-prop="hello" />;
@@ -1,5 +1,4 @@
tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'true' is not assignable to type 'number & string'.
Type 'true' is not assignable to type 'number'.
tests/cases/conformance/jsx/file.tsx(32,17): error TS2322: Type 'true' is not assignable to type 'never'.
tests/cases/conformance/jsx/file.tsx(33,10): error TS2322: Type '{ x: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<RC4> & { children?: ReactNode; }'.
Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<RC4> & { children?: ReactNode; }'.
tests/cases/conformance/jsx/file.tsx(34,10): error TS2322: Type '{ prop: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<RC3> & { children?: ReactNode; }'.
@@ -40,8 +39,7 @@ tests/cases/conformance/jsx/file.tsx(34,10): error TS2322: Type '{ prop: true; }
// Error
let a = <RCComp x />;
~
!!! error TS2322: Type 'true' is not assignable to type 'number & string'.
!!! error TS2322: Type 'true' is not assignable to type 'number'.
!!! error TS2322: Type 'true' is not assignable to type 'never'.
!!! related TS6500 tests/cases/conformance/jsx/file.tsx:3:36: The expected type comes from property 'x' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes<RC1 | RC2> & { x: number; } & { children?: ReactNode; } & { x: string; } & { children?: ReactNode; }'
let b = <PartRCComp x={10} />
~~~~~~~~~~
@@ -40,12 +40,12 @@ const enum Tag2 {}
>Tag2 : Tag2
declare function isNonBlank2(value: string) : value is (string & Tag2);
>isNonBlank2 : (value: string) => value is string & Tag2
>isNonBlank2 : (value: string) => value is never
>value : string
declare function doThis2(value: string & Tag2): void;
>doThis2 : (value: string & Tag2) => void
>value : string & Tag2
>doThis2 : (value: never) => void
>value : never
declare function doThat2(value: string) : void;
>doThat2 : (value: string) => void
@@ -53,13 +53,13 @@ declare function doThat2(value: string) : void;
if (isNonBlank2(value)) {
>isNonBlank2(value) : boolean
>isNonBlank2 : (value: string) => value is string & Tag2
>isNonBlank2 : (value: string) => value is never
>value : string
doThis2(value);
>doThis2(value) : void
>doThis2 : (value: string & Tag2) => void
>value : string & Tag2
>doThis2 : (value: never) => void
>value : never
} else {
doThat2(value);
@@ -20,8 +20,8 @@ var c2: string & { name: string } & number;
var d2: string & { name: string } & number & { name: string };
f2(a2); // string
f2(b2); // string[]
f2(c2); // string & number
f2(d2); // string & number
f2(c2); // never
f2(d2); // never
//// [unionAndIntersectionInference2.js]
@@ -41,5 +41,5 @@ var c2;
var d2;
f2(a2); // string
f2(b2); // string[]
f2(c2); // string & number
f2(d2); // string & number
f2(c2); // never
f2(d2); // never
@@ -75,11 +75,11 @@ f2(b2); // string[]
>f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7))
>b2 : Symbol(b2, Decl(unionAndIntersectionInference2.ts, 16, 3))
f2(c2); // string & number
f2(c2); // never
>f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7))
>c2 : Symbol(c2, Decl(unionAndIntersectionInference2.ts, 17, 3))
f2(d2); // string & number
f2(d2); // never
>f2 : Symbol(f2, Decl(unionAndIntersectionInference2.ts, 11, 7))
>d2 : Symbol(d2, Decl(unionAndIntersectionInference2.ts, 18, 3))
@@ -58,11 +58,11 @@ var b2: { name: string } & string[];
>name : string
var c2: string & { name: string } & number;
>c2 : string & { name: string; } & number
>c2 : never
>name : string
var d2: string & { name: string } & number & { name: string };
>d2 : string & { name: string; } & number & { name: string; }
>d2 : never
>name : string
>name : string
@@ -76,13 +76,13 @@ f2(b2); // string[]
>f2 : <T>(x: T & { name: string; }) => T
>b2 : { name: string; } & string[]
f2(c2); // string & number
>f2(c2) : string & number
f2(c2); // never
>f2(c2) : never
>f2 : <T>(x: T & { name: string; }) => T
>c2 : string & { name: string; } & number
>c2 : never
f2(d2); // string & number
>f2(d2) : string & number
f2(d2); // never
>f2(d2) : never
>f2 : <T>(x: T & { name: string; }) => T
>d2 : string & { name: string; } & number & { name: string; }
>d2 : never
@@ -2,10 +2,8 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(9,43): error TS23
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(10,29): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(15,29): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(16,1): error TS2554: Expected 1 arguments, but got 0.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(19,32): error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'.
Type '10' is not assignable to type 'string'.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(20,32): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'.
Type '"hello"' is not assignable to type 'number'.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(19,32): error TS2345: Argument of type '10' is not assignable to parameter of type 'never'.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(20,32): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'never'.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(21,1): error TS2554: Expected 1 arguments, but got 0.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(24,1): error TS2554: Expected 1 arguments, but got 0.
tests/cases/conformance/types/union/unionTypeCallSignatures.ts(26,36): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'.
@@ -59,12 +57,10 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(73,12): error TS2
var unionOfDifferentParameterTypes: { (a: number): number; } | { (a: string): Date; };
unionOfDifferentParameterTypes(10);// error - no call signatures
~~
!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'.
!!! error TS2345: Type '10' is not assignable to type 'string'.
!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'never'.
unionOfDifferentParameterTypes("hello");// error - no call signatures
~~~~~~~
!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'.
!!! error TS2345: Type '"hello"' is not assignable to type 'number'.
!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'never'.
unionOfDifferentParameterTypes();// error - no call signatures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2554: Expected 1 arguments, but got 0.
@@ -2,10 +2,8 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(9,47): error
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(10,33): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(15,33): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string'.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(16,1): error TS2554: Expected 1 arguments, but got 0.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(19,36): error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'.
Type '10' is not assignable to type 'string'.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(20,36): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'.
Type '"hello"' is not assignable to type 'number'.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(19,36): error TS2345: Argument of type '10' is not assignable to parameter of type 'never'.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(20,36): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'never'.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(21,1): error TS2554: Expected 1 arguments, but got 0.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(24,1): error TS2554: Expected 1 arguments, but got 0.
tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(26,40): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'.
@@ -58,12 +56,10 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(70,12): erro
var unionOfDifferentParameterTypes: { new (a: number): number; } | { new (a: string): Date; };
new unionOfDifferentParameterTypes(10);// error - no call signatures
~~
!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'number & string'.
!!! error TS2345: Type '10' is not assignable to type 'string'.
!!! error TS2345: Argument of type '10' is not assignable to parameter of type 'never'.
new unionOfDifferentParameterTypes("hello");// error - no call signatures
~~~~~~~
!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number & string'.
!!! error TS2345: Type '"hello"' is not assignable to type 'number'.
!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'never'.
new unionOfDifferentParameterTypes();// error - no call signatures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2554: Expected 1 arguments, but got 0.
@@ -1,6 +1,5 @@
tests/cases/conformance/types/union/unionTypeMembers.ts(44,38): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string & number'.
Type 'string' is not assignable to type 'string & number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/union/unionTypeMembers.ts(44,38): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'never'.
Type 'string' is not assignable to type 'never'.
tests/cases/conformance/types/union/unionTypeMembers.ts(51,3): error TS2339: Property 'propertyOnlyInI1' does not exist on type 'I1<number> | I2<number>'.
Property 'propertyOnlyInI1' does not exist on type 'I2<number>'.
tests/cases/conformance/types/union/unionTypeMembers.ts(52,3): error TS2339: Property 'propertyOnlyInI2' does not exist on type 'I1<number> | I2<number>'.
@@ -57,9 +56,8 @@ tests/cases/conformance/types/union/unionTypeMembers.ts(54,3): error TS2339: Pro
x.commonMethodDifferentParameterType; // No error - property exists
x.commonMethodDifferentParameterType(strOrNum); // error - no call signatures because the type of this property is ((a: string) => string) | (a: number) => number
~~~~~~~~
!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string & number'.
!!! error TS2345: Type 'string' is not assignable to type 'string & number'.
!!! error TS2345: Type 'string' is not assignable to type 'number'.
!!! error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'never'.
!!! error TS2345: Type 'string' is not assignable to type 'never'.
// and the call signatures arent identical
num = x.commonMethodWithTypeParameter(num);
num = x.commonMethodWithOwnTypeParameter(num);
@@ -35,7 +35,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(180,5): error TS2322: Type
type T00 = unknown & null; // null
type T01 = unknown & undefined; // undefined
type T02 = unknown & null & undefined; // null & undefined (which becomes never in union)
type T02 = unknown & null & undefined; // never
type T03 = unknown & string; // string
type T04 = unknown & string[]; // string[]
type T05 = unknown & unknown; // unknown
+1 -1
View File
@@ -3,7 +3,7 @@
type T00 = unknown & null; // null
type T01 = unknown & undefined; // undefined
type T02 = unknown & null & undefined; // null & undefined (which becomes never in union)
type T02 = unknown & null & undefined; // never
type T03 = unknown & string; // string
type T04 = unknown & string[]; // string[]
type T05 = unknown & unknown; // unknown
@@ -7,7 +7,7 @@ type T00 = unknown & null; // null
type T01 = unknown & undefined; // undefined
>T01 : Symbol(T01, Decl(unknownType1.ts, 2, 26))
type T02 = unknown & null & undefined; // null & undefined (which becomes never in union)
type T02 = unknown & null & undefined; // never
>T02 : Symbol(T02, Decl(unknownType1.ts, 3, 31))
type T03 = unknown & string; // string
+2 -2
View File
@@ -8,8 +8,8 @@ type T00 = unknown & null; // null
type T01 = unknown & undefined; // undefined
>T01 : undefined
type T02 = unknown & null & undefined; // null & undefined (which becomes never in union)
>T02 : T02
type T02 = unknown & null & undefined; // never
>T02 : never
>null : null
type T03 = unknown & string; // string
@@ -71,7 +71,7 @@ type X3<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U
type T50 = X3<{}>; // never
type T51 = X3<{ a: (x: string) => void }>; // never
type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // string & number
type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never
type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number
type T60 = infer U; // Error
@@ -1,15 +1,58 @@
// @strict
// @strict: false
declare const sym1: unique symbol;
declare const sym2: unique symbol;
type T1 = string & 'a'; // 'a'
type T2 = 'a' & string & 'b'; // 'a' & 'b'
type T2 = 'a' & string & 'b'; // never
type T3 = number & 10; // 10
type T4 = 10 & number & 20; // 10 & 20
type T4 = 10 & number & 20; // never
type T5 = symbol & typeof sym1; // typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // never
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
type T10 = string & ('a' | 'b'); // 'a' | 'b'
type T11 = (string | number) & ('a' | 10); // 'a' | 10
type N1 = 'a' & 'b';
type N2 = { a: string } & null;
type N3 = { a: string } & undefined;
type N4 = string & number;
type N5 = number & object;
type N6 = symbol & string;
type N7 = void & string;
type X = { x: string };
type X1 = X | 'a' & 'b';
type X2 = X | { a: string } & null;
type X3 = X | { a: string } & undefined;
type X4 = X | string & number;
type X5 = X | number & object;
type X6 = X | symbol & string;
type X7 = X | void & string;
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
const x2 = { a: 'foo', b: true };
declare let k: 'a' | 'b';
x1[k] = 'bar' as any; // Error
x2[k] = 'bar' as any; // Error
const enum Tag1 {}
const enum Tag2 {}
declare let s1: string & Tag1;
declare let s2: string & Tag2;
declare let t1: string & Tag1 | undefined;
declare let t2: string & Tag2 | undefined;
s1 = s2;
s2 = s1;
t1 = t2;
t2 = t1;
@@ -0,0 +1,58 @@
// @strict: true
declare const sym1: unique symbol;
declare const sym2: unique symbol;
type T1 = string & 'a'; // 'a'
type T2 = 'a' & string & 'b'; // never
type T3 = number & 10; // 10
type T4 = 10 & number & 20; // never
type T5 = symbol & typeof sym1; // typeof sym1
type T6 = typeof sym1 & symbol & typeof sym2; // never
type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // never
type T10 = string & ('a' | 'b'); // 'a' | 'b'
type T11 = (string | number) & ('a' | 10); // 'a' | 10
type N1 = 'a' & 'b';
type N2 = { a: string } & null;
type N3 = { a: string } & undefined;
type N4 = string & number;
type N5 = number & object;
type N6 = symbol & string;
type N7 = void & string;
type X = { x: string };
type X1 = X | 'a' & 'b';
type X2 = X | { a: string } & null;
type X3 = X | { a: string } & undefined;
type X4 = X | string & number;
type X5 = X | number & object;
type X6 = X | symbol & string;
type X7 = X | void & string;
// Repro from #31663
const x1 = { a: 'foo', b: 42 };
const x2 = { a: 'foo', b: true };
declare let k: 'a' | 'b';
x1[k] = 'bar' as any; // Error
x2[k] = 'bar' as any; // Error
const enum Tag1 {}
const enum Tag2 {}
declare let s1: string & Tag1;
declare let s2: string & Tag2;
declare let t1: string & Tag1 | undefined;
declare let t2: string & Tag2 | undefined;
s1 = s2;
s2 = s1;
t1 = t2;
t2 = t1;
@@ -3,8 +3,8 @@ declare function f<T>(x: { prop: T }): T;
declare const a: { prop: string } & { prop: number };
declare const b: { prop: string & number };
f(a); // string & number
f(b); // string & number
f(a); // never
f(b); // never
// Repro from #18354
@@ -27,7 +27,7 @@ type T17 = Shape[void]; // Error
type T18 = Shape[undefined]; // Error
type T19 = Shape[{ x: string }]; // Error
type T20 = Shape[string | number]; // Error
type T21 = Shape[string & number]; // Error
type T21 = Shape[string & number];
type T22 = Shape[string | boolean]; // Error
type T30 = string[]["length"];
@@ -19,5 +19,5 @@ var c2: string & { name: string } & number;
var d2: string & { name: string } & number & { name: string };
f2(a2); // string
f2(b2); // string[]
f2(c2); // string & number
f2(d2); // string & number
f2(c2); // never
f2(d2); // never
@@ -4,7 +4,7 @@
type T00 = unknown & null; // null
type T01 = unknown & undefined; // undefined
type T02 = unknown & null & undefined; // null & undefined (which becomes never in union)
type T02 = unknown & null & undefined; // never
type T03 = unknown & string; // string
type T04 = unknown & string[]; // string[]
type T05 = unknown & unknown; // unknown
+1 -1
View File
@@ -15,5 +15,5 @@
verify.quickInfos({
1: "function ComponentSpecific<number>(l: {\n prop: number;\n}): any",
2: "function ComponentSpecific<number & string>(l: {\n prop: number & string;\n}): any"
2: "function ComponentSpecific<never>(l: {\n prop: never;\n}): any"
});
+2 -2
View File
@@ -24,6 +24,6 @@ verify.quickInfos({
3: "function OverloadComponent<boolean, string>(attr: {\n b: string;\n a: boolean;\n}): any (+2 overloads)",
4: "function OverloadComponent(): any (+2 overloads)", // Subtype pass chooses this overload, since `a` is missing from the top overload, and `ignore-prop` is missing from the second (while T & {ignore-prop: true} is a proper subtype of `{}`)
5: "function OverloadComponent(): any (+2 overloads)",
6: "function OverloadComponent<boolean, string & number>(attr: {\n b: string & number;\n a: boolean;\n}): any (+2 overloads)",
7: "function OverloadComponent<boolean, number & string>(attr: {\n b: number & string;\n a: boolean;\n}): any (+2 overloads)",
6: "function OverloadComponent<boolean, never>(attr: {\n b: never;\n a: boolean;\n}): any (+2 overloads)",
7: "function OverloadComponent<boolean, never>(attr: {\n b: never;\n a: boolean;\n}): any (+2 overloads)",
});