diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ae00387fec..01945252e5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7664,7 +7664,7 @@ namespace ts { function getFlowTypeOfReference(reference: Node, declaredType: Type, assumeInitialized: boolean, includeOuterFunctions: boolean) { let key: string; - if (!reference.flowNode || assumeInitialized && (declaredType.flags & TypeFlags.NotNarrowable)) { + if (!reference.flowNode || assumeInitialized && !(declaredType.flags & TypeFlags.Narrowable)) { return declaredType; } const initialType = assumeInitialized ? declaredType : addNullableKind(declaredType, TypeFlags.Undefined); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f82d767329..a86b1ed708 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2219,12 +2219,9 @@ namespace ts { UnionOrIntersection = Union | Intersection, StructuredType = ObjectType | Union | Intersection, - // 'NotNarrowable' types are types where narrowing reverts to the original type, rather than actually narrow. - // This is never really correct - you can _always_ narrow to an intersection with that type, _but_ we keep - // Void as the only non-narrowable type, since it's a non-value type construct (representing a lack of a value) - // and, generally speaking, narrowing `void` should fail in some way, as it is nonsensical. (`void` narrowing - // to `void & T`, in a structural sense, is just narrowing to T, which we wouldn't allow under normal rules) - NotNarrowable = Void, + // 'Narrowable' types are types where narrowing actually narrows. + // This *should* be every type other than null, undefined, void, and never + Narrowable = Any | StructuredType | TypeParameter | StringLike | NumberLike | Boolean | ESSymbol, /* @internal */ RequiresWidening = ContainsWideningType | ContainsObjectLiteral, /* @internal */