Skip to main content
The SymbolFlags enum contains bit flags that classify symbols in the TypeScript compiler. Every Symbol object has a flags property indicating what kind of declaration(s) it represents.
export const enum SymbolFlags {
  None = 0,
  FunctionScopedVariable = 1 << 0,
  BlockScopedVariable = 1 << 1,
  // ... many more flags
}

interface Symbol {
  flags: SymbolFlags;
  escapedName: __String;
  declarations?: Declaration[];
  // ...
}

Variable Flags

FlagDescription
FunctionScopedVariableVariable declared with var or parameter
BlockScopedVariableVariable declared with let or const
PropertyProperty or enum member
EnumMemberEnum member

Composite Variable Flags

Variable = FunctionScopedVariable | BlockScopedVariable
Represents any kind of variable.

Callable Flags

FlagDescription
FunctionFunction declaration or expression
MethodClass or object method
ConstructorClass constructor
GetAccessorGetter accessor
SetAccessorSetter accessor
SignatureCall, construct, or index signature

Composite Accessor Flags

Accessor = GetAccessor | SetAccessor
Represents property accessors.

Type Declaration Flags

FlagDescription
ClassClass declaration
InterfaceInterface declaration
ConstEnumConst enum declaration
RegularEnumRegular enum declaration
TypeLiteralType literal or mapped type
TypeParameterType parameter
TypeAliasType alias declaration

Composite Enum Flags

Enum = RegularEnum | ConstEnum
Represents any enum.

Module Flags

FlagDescription
ValueModuleInstantiated module (namespace with runtime value)
NamespaceModuleNon-instantiated module (type-only namespace)

Composite Module Flags

Module = ValueModule | NamespaceModule
Namespace = ValueModule | NamespaceModule | Enum

Special Flags

FlagDescription
ObjectLiteralObject literal
AliasImport alias or type alias
PrototypePrototype property (no source representation)
ExportValueExported value marker
ExportStarexport * declaration
OptionalOptional property
TransientTransient symbol (created during type checking)
AssignmentAssignment treated as declaration (e.g., this.prop = 1)
ModuleExportsCommonJS module.exports

Composite Meaning Flags

These flags group symbols by their semantic meaning:

Value Flags

Value = 
  | Variable 
  | Property 
  | EnumMember 
  | ObjectLiteral 
  | Function 
  | Class 
  | Enum 
  | ValueModule 
  | Method 
  | GetAccessor 
  | SetAccessor
Symbols that contribute a value to the JavaScript runtime.

Type Flags

Type = 
  | Class 
  | Interface 
  | Enum 
  | EnumMember 
  | TypeLiteral 
  | TypeParameter 
  | TypeAlias
Symbols that contribute a type to the type system.

Namespace Flags

Namespace = ValueModule | NamespaceModule | Enum
Symbols that contribute a namespace.

Exclusion Flags

Exclusion flags determine what cannot be merged with a symbol:

Variable Exclusions

FunctionScopedVariableExcludes = Value & ~FunctionScopedVariable
BlockScopedVariableExcludes = Value
ParameterExcludes = Value
var declarations can be redeclared with other var declarations, but block-scoped variables cannot be redeclared.

Declaration Exclusions

PropertyExcludes = None
EnumMemberExcludes = Value | Type
FunctionExcludes = Value & ~(Function | ValueModule | Class)
ClassExcludes = (Value | Type) & ~(ValueModule | Interface | Function)
InterfaceExcludes = Type & ~(Interface | Class)

Enum Exclusions

RegularEnumExcludes = (Value | Type) & ~(RegularEnum | ValueModule)
ConstEnumExcludes = (Value | Type) & ~ConstEnum
Regular enums can merge with other regular enums and modules. Const enums can only merge with other const enums.

Module and Accessor Exclusions

ValueModuleExcludes = Value & ~(Function | Class | RegularEnum | ValueModule)
NamespaceModuleExcludes = 0
MethodExcludes = Value & ~Method
GetAccessorExcludes = Value & ~SetAccessor
SetAccessorExcludes = Value & ~GetAccessor
AccessorExcludes = Value & ~Accessor

Type Exclusions

TypeParameterExcludes = Type & ~TypeParameter
TypeAliasExcludes = Type
AliasExcludes = Alias

Module Member Flags

ModuleMember = 
  | Variable 
  | Function 
  | Class 
  | Interface 
  | Enum 
  | Module 
  | TypeAlias 
  | Alias
Symbols that can be members of a module.

Scope Flags

BlockScoped = BlockScopedVariable | Class | Enum
Symbols that are block-scoped.

Export Flags

ExportHasLocal = Function | Class | Enum | ValueModule
Exports that have a local symbol.

Class Member Flags

PropertyOrAccessor = Property | Accessor
ClassMember = Method | Accessor | Property
Symbols that can be class members.

Usage Examples

Checking Symbol Flags

import ts from 'typescript';

function analyzeSymbol(symbol: ts.Symbol, checker: ts.TypeChecker) {
  const flags = symbol.flags;
  
  if (flags & ts.SymbolFlags.Variable) {
    console.log('Variable symbol');
  }
  
  if (flags & ts.SymbolFlags.Function) {
    console.log('Function symbol');
  }
  
  if (flags & ts.SymbolFlags.Class) {
    console.log('Class symbol');
  }
  
  if (flags & ts.SymbolFlags.Interface) {
    console.log('Interface symbol');
  }
}

Distinguishing Variable Types

function getVariableKind(symbol: ts.Symbol): string {
  if (symbol.flags & ts.SymbolFlags.BlockScopedVariable) {
    return 'let/const';
  }
  if (symbol.flags & ts.SymbolFlags.FunctionScopedVariable) {
    return 'var/parameter';
  }
  return 'not a variable';
}

Checking for Functions and Methods

function isCallable(symbol: ts.Symbol): boolean {
  return (
    (symbol.flags & ts.SymbolFlags.Function) !== 0 ||
    (symbol.flags & ts.SymbolFlags.Method) !== 0
  );
}

Working with Enums

function analyzeEnum(symbol: ts.Symbol) {
  if (symbol.flags & ts.SymbolFlags.ConstEnum) {
    console.log('Const enum');
  } else if (symbol.flags & ts.SymbolFlags.RegularEnum) {
    console.log('Regular enum');
  }
  
  if (symbol.flags & ts.SymbolFlags.EnumMember) {
    console.log('Enum member');
  }
}

Checking Multiple Meanings

function hasMultipleMeanings(symbol: ts.Symbol): boolean {
  const hasValue = (symbol.flags & ts.SymbolFlags.Value) !== 0;
  const hasType = (symbol.flags & ts.SymbolFlags.Type) !== 0;
  return hasValue && hasType;
}

// Classes and enums have both value and type meanings
const flags = ts.SymbolFlags.Class;
const isValue = (flags & ts.SymbolFlags.Value) !== 0; // true
const isType = (flags & ts.SymbolFlags.Type) !== 0;  // true

Finding Declarations

function findDeclarations(symbol: ts.Symbol) {
  if (!symbol.declarations) {
    return [];
  }
  
  return symbol.declarations.filter(decl => {
    if (symbol.flags & ts.SymbolFlags.Function) {
      return ts.isFunctionDeclaration(decl);
    }
    if (symbol.flags & ts.SymbolFlags.Class) {
      return ts.isClassDeclaration(decl);
    }
    return true;
  });
}

Type Guards

function isFunctionSymbol(symbol: ts.Symbol): boolean {
  return (symbol.flags & ts.SymbolFlags.Function) !== 0;
}

function isClassSymbol(symbol: ts.Symbol): boolean {
  return (symbol.flags & ts.SymbolFlags.Class) !== 0;
}

function isInterfaceSymbol(symbol: ts.Symbol): boolean {
  return (symbol.flags & ts.SymbolFlags.Interface) !== 0;
}

function isModuleSymbol(symbol: ts.Symbol): boolean {
  return (symbol.flags & ts.SymbolFlags.Module) !== 0;
}

Advanced Patterns

Declaration Merging

function canMergeWith(symbol1: ts.Symbol, symbol2: ts.Symbol): boolean {
  // Check if symbol2 can merge with symbol1
  const exclusions = getExclusions(symbol1.flags);
  return (symbol2.flags & exclusions) === 0;
}

function getExclusions(flags: ts.SymbolFlags): ts.SymbolFlags {
  if (flags & ts.SymbolFlags.Class) {
    return ts.SymbolFlags.ClassExcludes;
  }
  if (flags & ts.SymbolFlags.Interface) {
    return ts.SymbolFlags.InterfaceExcludes;
  }
  // ... etc
  return ts.SymbolFlags.None;
}

Finding Symbol Kind

function getSymbolKindString(symbol: ts.Symbol): string {
  const flags = symbol.flags;
  
  if (flags & ts.SymbolFlags.Class) return 'class';
  if (flags & ts.SymbolFlags.Interface) return 'interface';
  if (flags & ts.SymbolFlags.TypeAlias) return 'type';
  if (flags & ts.SymbolFlags.Enum) return 'enum';
  if (flags & ts.SymbolFlags.Function) return 'function';
  if (flags & ts.SymbolFlags.Variable) return 'variable';
  if (flags & ts.SymbolFlags.Property) return 'property';
  if (flags & ts.SymbolFlags.Method) return 'method';
  
  return 'unknown';
}

See Also

Build docs developers (and LLMs) love