mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Preserve special intersections in mapped types (#50704)
* Preserve special intersections in mapped types * Add regression test
This commit is contained in:
parent
1a1c271675
commit
a70bb9d3ff
@ -11780,6 +11780,12 @@ namespace ts {
|
||||
return mapType(type as UnionType, getLowerBoundOfKeyType);
|
||||
}
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
// Similarly to getTypeFromIntersectionTypeNode, we preserve the special string & {}, number & {},
|
||||
// and bigint & {} intersections that are used to prevent subtype reduction in union types.
|
||||
const types = (type as IntersectionType).types;
|
||||
if (types.length === 2 && !!(types[0].flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.BigInt)) && types[1] === emptyTypeLiteralType) {
|
||||
return type;
|
||||
}
|
||||
return getIntersectionType(sameMap((type as UnionType).types, getLowerBoundOfKeyType));
|
||||
}
|
||||
return type;
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
tests/cases/compiler/specialIntersectionsInMappedTypes.ts(14,1): error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/specialIntersectionsInMappedTypes.ts (1 errors) ====
|
||||
// Repro from #50683
|
||||
|
||||
type Alignment = (string & {}) | "left" | "center" | "right";
|
||||
type Alignments = Record<Alignment, string>;
|
||||
|
||||
const a: Alignments = {
|
||||
left: "align-left",
|
||||
center: "align-center",
|
||||
right: "align-right",
|
||||
other: "align-other",
|
||||
};
|
||||
|
||||
a.left.length;
|
||||
a.other.length; // Error expected here
|
||||
~~~~~~~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
//// [specialIntersectionsInMappedTypes.ts]
|
||||
// Repro from #50683
|
||||
|
||||
type Alignment = (string & {}) | "left" | "center" | "right";
|
||||
type Alignments = Record<Alignment, string>;
|
||||
|
||||
const a: Alignments = {
|
||||
left: "align-left",
|
||||
center: "align-center",
|
||||
right: "align-right",
|
||||
other: "align-other",
|
||||
};
|
||||
|
||||
a.left.length;
|
||||
a.other.length; // Error expected here
|
||||
|
||||
|
||||
//// [specialIntersectionsInMappedTypes.js]
|
||||
"use strict";
|
||||
// Repro from #50683
|
||||
var a = {
|
||||
left: "align-left",
|
||||
center: "align-center",
|
||||
right: "align-right",
|
||||
other: "align-other"
|
||||
};
|
||||
a.left.length;
|
||||
a.other.length; // Error expected here
|
||||
@ -0,0 +1,41 @@
|
||||
=== tests/cases/compiler/specialIntersectionsInMappedTypes.ts ===
|
||||
// Repro from #50683
|
||||
|
||||
type Alignment = (string & {}) | "left" | "center" | "right";
|
||||
>Alignment : Symbol(Alignment, Decl(specialIntersectionsInMappedTypes.ts, 0, 0))
|
||||
|
||||
type Alignments = Record<Alignment, string>;
|
||||
>Alignments : Symbol(Alignments, Decl(specialIntersectionsInMappedTypes.ts, 2, 61))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>Alignment : Symbol(Alignment, Decl(specialIntersectionsInMappedTypes.ts, 0, 0))
|
||||
|
||||
const a: Alignments = {
|
||||
>a : Symbol(a, Decl(specialIntersectionsInMappedTypes.ts, 5, 5))
|
||||
>Alignments : Symbol(Alignments, Decl(specialIntersectionsInMappedTypes.ts, 2, 61))
|
||||
|
||||
left: "align-left",
|
||||
>left : Symbol(left, Decl(specialIntersectionsInMappedTypes.ts, 5, 23))
|
||||
|
||||
center: "align-center",
|
||||
>center : Symbol(center, Decl(specialIntersectionsInMappedTypes.ts, 6, 23))
|
||||
|
||||
right: "align-right",
|
||||
>right : Symbol(right, Decl(specialIntersectionsInMappedTypes.ts, 7, 27))
|
||||
|
||||
other: "align-other",
|
||||
>other : Symbol(other, Decl(specialIntersectionsInMappedTypes.ts, 8, 25))
|
||||
|
||||
};
|
||||
|
||||
a.left.length;
|
||||
>a.left.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>a.left : Symbol(left)
|
||||
>a : Symbol(a, Decl(specialIntersectionsInMappedTypes.ts, 5, 5))
|
||||
>left : Symbol(left)
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
a.other.length; // Error expected here
|
||||
>a.other.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>a : Symbol(a, Decl(specialIntersectionsInMappedTypes.ts, 5, 5))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
=== tests/cases/compiler/specialIntersectionsInMappedTypes.ts ===
|
||||
// Repro from #50683
|
||||
|
||||
type Alignment = (string & {}) | "left" | "center" | "right";
|
||||
>Alignment : (string & {}) | "left" | "center" | "right"
|
||||
|
||||
type Alignments = Record<Alignment, string>;
|
||||
>Alignments : { [x: string & {}]: string; left: string; center: string; right: string; }
|
||||
|
||||
const a: Alignments = {
|
||||
>a : Alignments
|
||||
>{ left: "align-left", center: "align-center", right: "align-right", other: "align-other",} : { left: string; center: string; right: string; other: string; }
|
||||
|
||||
left: "align-left",
|
||||
>left : string
|
||||
>"align-left" : "align-left"
|
||||
|
||||
center: "align-center",
|
||||
>center : string
|
||||
>"align-center" : "align-center"
|
||||
|
||||
right: "align-right",
|
||||
>right : string
|
||||
>"align-right" : "align-right"
|
||||
|
||||
other: "align-other",
|
||||
>other : string
|
||||
>"align-other" : "align-other"
|
||||
|
||||
};
|
||||
|
||||
a.left.length;
|
||||
>a.left.length : number
|
||||
>a.left : string
|
||||
>a : Alignments
|
||||
>left : string
|
||||
>length : number
|
||||
|
||||
a.other.length; // Error expected here
|
||||
>a.other.length : number
|
||||
>a.other : string | undefined
|
||||
>a : Alignments
|
||||
>other : string | undefined
|
||||
>length : number
|
||||
|
||||
17
tests/cases/compiler/specialIntersectionsInMappedTypes.ts
Normal file
17
tests/cases/compiler/specialIntersectionsInMappedTypes.ts
Normal file
@ -0,0 +1,17 @@
|
||||
// @strict: true
|
||||
// @noUncheckedIndexedAccess: true
|
||||
|
||||
// Repro from #50683
|
||||
|
||||
type Alignment = (string & {}) | "left" | "center" | "right";
|
||||
type Alignments = Record<Alignment, string>;
|
||||
|
||||
const a: Alignments = {
|
||||
left: "align-left",
|
||||
center: "align-center",
|
||||
right: "align-right",
|
||||
other: "align-other",
|
||||
};
|
||||
|
||||
a.left.length;
|
||||
a.other.length; // Error expected here
|
||||
Loading…
x
Reference in New Issue
Block a user