diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts index 2f51cedbe82..69a69a8c3c8 100644 --- a/src/services/codefixes/fixStrictClassInitialization.ts +++ b/src/services/codefixes/fixStrictClassInitialization.ts @@ -116,13 +116,13 @@ namespace ts.codefix { else if (type.flags & TypeFlags.Boolean) { return createFalse(); } - else if (type.flags & TypeFlags.Literal) { - return createLiteral((type).value); + else if (type.isLiteral()) { + return createLiteral(type.value); } - else if (type.flags & TypeFlags.Union) { - return firstDefined((type).types, t => getDefaultValueFromType(checker, t)); + else if (type.isUnion()) { + return firstDefined(type.types, t => getDefaultValueFromType(checker, t)); } - else if (getObjectFlags(type) & ObjectFlags.Class) { + else if (type.isClass()) { const classDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); if (!classDeclaration || hasModifier(classDeclaration, ModifierFlags.Abstract)) return undefined; diff --git a/src/services/completions.ts b/src/services/completions.ts index 83701342f51..ffbd6a2d9e6 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -474,10 +474,10 @@ namespace ts.Completions { function getStringLiteralTypes(type: Type | undefined, typeChecker: TypeChecker, uniques = createMap()): ReadonlyArray | undefined { if (!type) return emptyArray; type = skipConstraint(type); - return type.flags & TypeFlags.Union - ? flatMap((type).types, t => getStringLiteralTypes(t, typeChecker, uniques)) - : type.flags & TypeFlags.StringLiteral && !(type.flags & TypeFlags.EnumLiteral) && addToSeen(uniques, (type as StringLiteralType).value) - ? [type as StringLiteralType] + return type.isUnion() + ? flatMap(type.types, t => getStringLiteralTypes(t, typeChecker, uniques)) + : type.isStringLiteral() && !(type.flags & TypeFlags.EnumLiteral) && addToSeen(uniques, type.value) + ? [type] : emptyArray; } @@ -2202,13 +2202,12 @@ namespace ts.Completions { * excludes array-like types or callable/constructable types. */ function getPropertiesForCompletion(type: Type, checker: TypeChecker, isForAccess: boolean): Symbol[] { - if (!(type.flags & TypeFlags.Union)) { + if (!(type.isUnion())) { return Debug.assertEachDefined(type.getApparentProperties(), "getApparentProperties() should all be defined"); } - const { types } = type as UnionType; // If we're providing completions for an object literal, skip primitive, array-like, or callable types since those shouldn't be implemented by object literals. - const filteredTypes = isForAccess ? types : types.filter(memberType => + const filteredTypes = isForAccess ? type.types : type.types.filter(memberType => !(memberType.flags & TypeFlags.Primitive || checker.isArrayLikeType(memberType) || typeHasCallOrConstructSignatures(memberType, checker))); return Debug.assertEachDefined(checker.getAllPossiblePropertiesOfTypes(filteredTypes), "getAllPossiblePropertiesOfTypes() should all be defined"); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index ac3745a7926..0a81af1efb1 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1132,8 +1132,8 @@ namespace ts.FindAllReferences.Core { if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) { result.push(componentType.symbol); } - if (componentType.getFlags() & TypeFlags.UnionOrIntersection) { - getSymbolsForClassAndInterfaceComponents(componentType, result); + if (componentType.isUnionOrIntersection()) { + getSymbolsForClassAndInterfaceComponents(componentType, result); } } return result; @@ -1567,7 +1567,7 @@ namespace ts.FindAllReferences.Core { const name = getNameFromPropertyName(node.name); const symbol = contextualType && name && contextualType.getProperty(name); return symbol ? [symbol] : - contextualType && contextualType.flags & TypeFlags.Union ? mapDefined((contextualType).types, t => t.getProperty(name)) : emptyArray; + contextualType && contextualType.isUnion() ? mapDefined(contextualType.types, t => t.getProperty(name)) : emptyArray; } /** @@ -1650,8 +1650,8 @@ namespace ts.FindAllReferences.Core { const localParentType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression); return localParentType && localParentType.symbol && localParentType.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== symbol.parent ? [localParentType.symbol] - : localParentType && localParentType.flags & TypeFlags.UnionOrIntersection - ? getSymbolsForClassAndInterfaceComponents(localParentType) + : localParentType && localParentType.isUnionOrIntersection() + ? getSymbolsForClassAndInterfaceComponents(localParentType) : undefined; } } diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 08478344428..4b2ba7e4536 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -131,8 +131,8 @@ namespace ts.GoToDefinition { return undefined; } - if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum)) { - return flatMap((type).types, t => t.symbol && getDefinitionFromSymbol(typeChecker, t.symbol, node)); + if (type.isUnion() && !(type.flags & TypeFlags.Enum)) { + return flatMap(type.types, t => t.symbol && getDefinitionFromSymbol(typeChecker, t.symbol, node)); } return type.symbol && getDefinitionFromSymbol(typeChecker, type.symbol, node); diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 7144265d11a..b99a4b26552 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1600,8 +1600,8 @@ namespace ts.refactor.extractSymbol { const {visitedTypes} = symbolWalker.walkType(type); for (const visitedType of visitedTypes) { - if (visitedType.flags & TypeFlags.TypeParameter) { - allTypeParameterUsages.set(visitedType.id.toString(), visitedType as TypeParameter); + if (visitedType.isTypeParameter()) { + allTypeParameterUsages.set(visitedType.id.toString(), visitedType); } } } diff --git a/src/services/services.ts b/src/services/services.ts index 7165c7ad4bb..45d505466fa 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -431,9 +431,7 @@ namespace ts { return this.checker.getIndexTypeOfType(this, IndexKind.Number); } getBaseTypes(): BaseType[] | undefined { - return this.flags & TypeFlags.Object && this.objectFlags & (ObjectFlags.Class | ObjectFlags.Interface) - ? this.checker.getBaseTypes(this) - : undefined; + return this.isClassOrInterface() ? this.checker.getBaseTypes(this) : undefined; } getNonNullableType(): Type { return this.checker.getNonNullableType(this); @@ -444,6 +442,34 @@ namespace ts { getDefault(): Type | undefined { return this.checker.getDefaultFromTypeParameter(this); } + + isUnion(): this is UnionType { + return !!(this.flags & TypeFlags.Union); + } + isIntersection(): this is IntersectionType { + return !!(this.flags & TypeFlags.Intersection); + } + isUnionOrIntersection(): this is UnionOrIntersectionType { + return !!(this.flags & TypeFlags.UnionOrIntersection); + } + isLiteral(): this is LiteralType { + return !!(this.flags & TypeFlags.Literal); + } + isStringLiteral(): this is StringLiteralType { + return !!(this.flags & TypeFlags.StringLiteral); + } + isNumberLiteral(): this is NumberLiteralType { + return !!(this.flags & TypeFlags.NumberLiteral); + } + isTypeParameter(): this is TypeParameter { + return !!(this.flags & TypeFlags.TypeParameter); + } + isClassOrInterface(): this is InterfaceType { + return !!(getObjectFlags(this) & ObjectFlags.ClassOrInterface); + } + isClass(): this is InterfaceType { + return !!(getObjectFlags(this) & ObjectFlags.Class); + } } class SignatureObject implements Signature { diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index c88202b8dbe..4693a5089f1 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -201,7 +201,7 @@ namespace ts.SymbolDisplay { // If it is call or construct signature of lambda's write type name displayParts.push(punctuationPart(SyntaxKind.ColonToken)); displayParts.push(spacePart()); - if (!(type.flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous) && type.symbol) { + if (!(getObjectFlags(type) & ObjectFlags.Anonymous) && type.symbol) { addRange(displayParts, symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, SymbolFormatFlags.AllowAnyNodeKind | SymbolFormatFlags.WriteTypeParametersOrArguments)); displayParts.push(lineBreakPart()); } diff --git a/src/services/types.ts b/src/services/types.ts index 096ef2de190..0c3e6a90314 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -52,6 +52,16 @@ namespace ts { getNonNullableType(): Type; getConstraint(): Type | undefined; getDefault(): Type | undefined; + + isUnion(): this is UnionType; + isIntersection(): this is IntersectionType; + isUnionOrIntersection(): this is UnionOrIntersectionType; + isLiteral(): this is LiteralType; + isStringLiteral(): this is StringLiteralType; + isNumberLiteral(): this is NumberLiteralType; + isTypeParameter(): this is TypeParameter; + isClassOrInterface(): this is InterfaceType; + isClass(): this is InterfaceType; } export interface Signature { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 18b0db15981..378a711e0c9 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1218,7 +1218,7 @@ namespace ts { } export function skipConstraint(type: Type): Type { - return type.flags & TypeFlags.TypeParameter ? type.getConstraint() : type; + return type.isTypeParameter() ? type.getConstraint() : type; } export function getNameFromPropertyName(name: PropertyName): string | undefined { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ed83dbfd69d..3bb826b0fef 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4007,6 +4007,15 @@ declare namespace ts { getNonNullableType(): Type; getConstraint(): Type | undefined; getDefault(): Type | undefined; + isUnion(): this is UnionType; + isIntersection(): this is IntersectionType; + isUnionOrIntersection(): this is UnionOrIntersectionType; + isLiteral(): this is LiteralType; + isStringLiteral(): this is StringLiteralType; + isNumberLiteral(): this is NumberLiteralType; + isTypeParameter(): this is TypeParameter; + isClassOrInterface(): this is InterfaceType; + isClass(): this is InterfaceType; } interface Signature { getDeclaration(): SignatureDeclaration; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 20982c23365..99804672930 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4260,6 +4260,15 @@ declare namespace ts { getNonNullableType(): Type; getConstraint(): Type | undefined; getDefault(): Type | undefined; + isUnion(): this is UnionType; + isIntersection(): this is IntersectionType; + isUnionOrIntersection(): this is UnionOrIntersectionType; + isLiteral(): this is LiteralType; + isStringLiteral(): this is StringLiteralType; + isNumberLiteral(): this is NumberLiteralType; + isTypeParameter(): this is TypeParameter; + isClassOrInterface(): this is InterfaceType; + isClass(): this is InterfaceType; } interface Signature { getDeclaration(): SignatureDeclaration;