Skip to main content
The TypeFlags enum contains bit flags that classify types in the TypeScript type system. Every Type object has a flags property containing a combination of these flags.
export const enum TypeFlags {
  Any = 1 << 0,
  Unknown = 1 << 1,
  // ... many more flags
}

interface Type {
  flags: TypeFlags;
  // ...
}

Primitive Type Flags

Basic Types

FlagDescription
Anyany type
Unknownunknown type
Undefinedundefined type
Nullnull type
Voidvoid type
Stringstring type
Numbernumber type
BigIntbigint type
Booleanboolean type
ESSymbolsymbol type
Nevernever type

Literal Types

FlagDescription
StringLiteralString literal type (e.g., "hello")
NumberLiteralNumber literal type (e.g., 42)
BigIntLiteralBigInt literal type (e.g., 100n)
BooleanLiteralBoolean literal type (true or false)
UniqueESSymbolUnique symbol type
EnumLiteralEnum member literal
EnumComputed enum member value

Complex Type Flags

Object and Structure Types

FlagDescription
ObjectObject type
NonPrimitiveobject intrinsic type
TypeParameterType parameter
UnionUnion type (`TU`)
IntersectionIntersection type (T & U)

Advanced Types

FlagDescription
Indexkeyof T type
IndexedAccessT[K] type
ConditionalConditional type (T extends U ? X : Y)
SubstitutionType parameter substitution
TemplateLiteralTemplate literal type
StringMappingString mapping type (e.g., Uppercase<T>)

Composite Flags

The enum includes composite flags for common type combinations:

Nullable Types

Nullable = Undefined | Null
Represents types that are undefined or null.

Literal Types

Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral
All literal types.

Unit Types

Unit = Enum | Literal | UniqueESSymbol | Nullable
Types with a single possible value.

String-like Types

StringLike = String | StringLiteral | TemplateLiteral | StringMapping
All types that behave like strings.

Number-like Types

NumberLike = Number | NumberLiteral | Enum
All types that behave like numbers.

Boolean-like Types

BooleanLike = Boolean | BooleanLiteral
Boolean and boolean literal types.

Primitive Types

Primitive = 
  | StringLike 
  | NumberLike 
  | BigIntLike 
  | BooleanLike 
  | EnumLike 
  | ESSymbolLike 
  | VoidLike 
  | Null
All primitive types.

Structured Types

StructuredType = Object | Union | Intersection
Types with structure.

Type Variables

TypeVariable = TypeParameter | IndexedAccess
Types that can be instantiated.

Instantiable Types

InstantiableNonPrimitive = TypeVariable | Conditional | Substitution
InstantiablePrimitive = Index | TemplateLiteral | StringMapping
Instantiable = InstantiableNonPrimitive | InstantiablePrimitive
Types that need instantiation.

Union and Intersection

UnionOrIntersection = Union | Intersection
Composite types.

Structured or Instantiable

StructuredOrInstantiable = StructuredType | Instantiable
Complex types requiring special handling.

Specialized Composite Flags

Possibly Falsy

DefinitelyFalsy = 
  | StringLiteral 
  | NumberLiteral 
  | BigIntLiteral 
  | BooleanLiteral 
  | Void 
  | Undefined 
  | Null

PossiblyFalsy = DefinitelyFalsy | String | Number | BigInt | Boolean
Types that can be falsy in JavaScript.

Narrowable Types

Narrowable = 
  | Any 
  | Unknown 
  | StructuredOrInstantiable 
  | StringLike 
  | NumberLike 
  | BigIntLike 
  | BooleanLike 
  | ESSymbol 
  | UniqueESSymbol 
  | NonPrimitive
Types where narrowing actually narrows (excludes null, undefined, void, and never).

Definitely Non-Nullable

DefinitelyNonNullable = 
  | StringLike 
  | NumberLike 
  | BigIntLike 
  | BooleanLike 
  | EnumLike 
  | ESSymbolLike 
  | Object 
  | NonPrimitive
Types that cannot be null or undefined.

Using TypeFlags

Checking Type Flags

import ts from 'typescript';

function checkType(type: ts.Type, checker: ts.TypeChecker) {
  if (type.flags & ts.TypeFlags.String) {
    console.log('String type');
  }
  
  if (type.flags & ts.TypeFlags.StringLiteral) {
    const literal = type as ts.StringLiteralType;
    console.log(`String literal: "${literal.value}"`);
  }
  
  if (type.flags & ts.TypeFlags.Union) {
    const union = type as ts.UnionType;
    console.log(`Union with ${union.types.length} types`);
  }
}

Testing Multiple Flags

// Check if type is string-like
if (type.flags & ts.TypeFlags.StringLike) {
  console.log('String-like type');
}

// Check if type is a literal
if (type.flags & ts.TypeFlags.Literal) {
  console.log('Literal type');
}

// Check for any or unknown
if (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) {
  console.log('Any or unknown type');
}

Type Guards

Combine flags with type narrowing:
function isStringLiteralType(type: ts.Type): type is ts.StringLiteralType {
  return (type.flags & ts.TypeFlags.StringLiteral) !== 0;
}

function isUnionType(type: ts.Type): type is ts.UnionType {
  return (type.flags & ts.TypeFlags.Union) !== 0;
}

Common Patterns

Checking for Nullable Types

if (type.flags & ts.TypeFlags.Nullable) {
  console.log('Type includes null or undefined');
}

Distinguishing Primitives

if (type.flags & ts.TypeFlags.Primitive) {
  console.log('Primitive type');
}

Working with Literals

if (type.flags & ts.TypeFlags.Literal) {
  if (type.flags & ts.TypeFlags.StringLiteral) {
    const value = (type as ts.StringLiteralType).value;
    console.log(`String literal: "${value}"`);
  } else if (type.flags & ts.TypeFlags.NumberLiteral) {
    const value = (type as ts.NumberLiteralType).value;
    console.log(`Number literal: ${value}`);
  }
}

Handling Unions and Intersections

if (type.flags & ts.TypeFlags.UnionOrIntersection) {
  const composite = type as ts.UnionOrIntersectionType;
  console.log(`Composite type with ${composite.types.length} constituents`);
}

Internal Flags

Some flags are marked as internal and used by the compiler:
AnyOrUnknown = Any | Unknown
StringOrNumberLiteralOrUnique = StringLiteral | NumberLiteral | UniqueESSymbol
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral | StringMapping
These are typically used during type checking and type construction.

See Also

Build docs developers (and LLMs) love