mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-07 05:41:22 -06:00
Filter origin types when filtering union types (#42378)
* When filtering a union type, also filter its origin type, if any * Accept new baselines
This commit is contained in:
parent
1cef53f9f5
commit
028f14c507
@ -21689,7 +21689,27 @@ namespace ts {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
const types = (<UnionType>type).types;
|
||||
const filtered = filter(types, f);
|
||||
return filtered === types ? type : getUnionTypeFromSortedList(filtered, (<UnionType>type).objectFlags);
|
||||
if (filtered === types) {
|
||||
return type;
|
||||
}
|
||||
const origin = (<UnionType>type).origin;
|
||||
let newOrigin: Type | undefined;
|
||||
if (origin && origin.flags & TypeFlags.Union) {
|
||||
// If the origin type is a (denormalized) union type, filter its non-union constituents. If that ends
|
||||
// up removing a smaller number of types than in the normalized constituent set (meaning some of the
|
||||
// filtered types are within nested unions in the origin), then we can't construct a new origin type.
|
||||
// Otherwise, if we have exactly one type left in the origin set, return that as the filtered type.
|
||||
// Otherwise, construct a new filtered origin type.
|
||||
const originTypes = (<UnionType>origin).types;
|
||||
const originFiltered = filter(originTypes, t => !!(t.flags & TypeFlags.Union) || f(t));
|
||||
if (originTypes.length - originFiltered.length === types.length - filtered.length) {
|
||||
if (originFiltered.length === 1) {
|
||||
return originFiltered[0];
|
||||
}
|
||||
newOrigin = createOriginUnionOrIntersectionType(TypeFlags.Union, originFiltered);
|
||||
}
|
||||
}
|
||||
return getUnionTypeFromSortedList(filtered, (<UnionType>type).objectFlags, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, newOrigin);
|
||||
}
|
||||
return type.flags & TypeFlags.Never || f(type) ? type : neverType;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(7,9): error TS7027: Unreachable code detected.
|
||||
tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(235,5): error TS2367: This condition will always return 'false' since the types '"a" | "b"' and '"c"' have no overlap.
|
||||
tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(235,5): error TS2367: This condition will always return 'false' since the types 'keyof O' and '"c"' have no overlap.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts (2 errors) ====
|
||||
@ -241,7 +241,7 @@ tests/cases/conformance/controlFlow/exhaustiveSwitchStatements1.ts(235,5): error
|
||||
}
|
||||
k === 'c'; // Error
|
||||
~~~~~~~~~
|
||||
!!! error TS2367: This condition will always return 'false' since the types '"a" | "b"' and '"c"' have no overlap.
|
||||
!!! error TS2367: This condition will always return 'false' since the types 'keyof O' and '"c"' have no overlap.
|
||||
return o[k];
|
||||
}
|
||||
|
||||
@ -695,12 +695,12 @@ function ff(o: O, k: K) {
|
||||
}
|
||||
k === 'c'; // Error
|
||||
>k === 'c' : boolean
|
||||
>k : "a" | "b"
|
||||
>k : keyof O
|
||||
>'c' : "c"
|
||||
|
||||
return o[k];
|
||||
>o[k] : number
|
||||
>o : O
|
||||
>k : "a" | "b"
|
||||
>k : keyof O
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +52,6 @@ function asObservable(input: string | ObservableInput<string>): Observable<strin
|
||||
>input : string
|
||||
>from(input) : Observable<string>
|
||||
>from : <O extends ObservableInput<any>>(input: O) => Observable<ObservedValueOf<O>>
|
||||
>input : Subscribable<never> | Subscribable<string>
|
||||
>input : ObservableInput<string>
|
||||
}
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ function fail(s: Shapes) {
|
||||
if (s.kind === "circle") {
|
||||
>s.kind === "circle" : boolean
|
||||
>s.kind : "square" | "circle"
|
||||
>s : Square | Circle
|
||||
>s : Shape
|
||||
>kind : "square" | "circle"
|
||||
>"circle" : "circle"
|
||||
|
||||
|
||||
@ -27,6 +27,6 @@ foo1 = [...Array.isArray(foo2) ? foo2 : [foo2]];
|
||||
>isArray : (arg: any) => arg is any[]
|
||||
>foo2 : Foo
|
||||
>foo2 : FooArray
|
||||
>[foo2] : (string | false)[]
|
||||
>foo2 : string | false
|
||||
>[foo2] : FooBase[]
|
||||
>foo2 : FooBase
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ function f(foo: T) {
|
||||
>foo : T
|
||||
|
||||
return foo;
|
||||
>foo : "a" | "b"
|
||||
>foo : S
|
||||
}
|
||||
else {
|
||||
return foo[0];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user