private bool IsTypeAccessible(ITypeNode type) { // type not declared --> treat it as accessible if (type == null) { return(true); } // predefined types are always accessible if (type.IsPredefinedType()) { return(true); } // descend into ParenthesizedType if (type.Kind == TypeScript.Net.Types.SyntaxKind.ParenthesizedType) { return(IsTypeAccessible(type.Cast <IParenthesizedTypeNode>().Type)); } // an array type is accessible iff its element type is accessible if (type.Kind == TypeScript.Net.Types.SyntaxKind.ArrayType) { return(IsTypeAccessible(type.Cast <IArrayTypeNode>().ElementType)); } // a union type is accessible iff all its types are accessible if (type.Kind == TypeScript.Net.Types.SyntaxKind.UnionType) { return(type.Cast <IUnionOrIntersectionTypeNode>().Types.All(t => IsTypeAccessible(t))); } // a function type is accessible iff its return type and its type parameters are accessible if (type.Kind == TypeScript.Net.Types.SyntaxKind.FunctionType) { var fnType = type.Cast <IFunctionOrConstructorTypeNode>(); var fnParameters = fnType.Parameters ?? NodeArray.Empty <IParameterDeclaration>(); return (IsTypeAccessible(fnType.Type) && fnParameters.All(tp => IsTypeAccessible(tp.Type))); } // a type literal is accessible iff all its members are accessible if (type.Kind == TypeScript.Net.Types.SyntaxKind.TypeLiteral) { return(type.Cast <ITypeLiteralNode>().Members.All(m => IsMemberAccessible(m))); bool IsMemberAccessible(ITypeElement e) { var memberTypes = e.Kind == TypeScript.Net.Types.SyntaxKind.PropertySignature ? new[] { e.Cast <IPropertySignature>().Type } : null; // handle other kinds if needed return(memberTypes != null && memberTypes.All(t => IsTypeAccessible(t))); } } // if any type argument is inaccessible, this type is not accessible either var typeArguments = type.GetTypeArguments(); if (!typeArguments.All(t => IsTypeAccessible(t))) { return(false); } // if this type couldn't be resolved, treat it as inaccessible var resolvedSymbol = type.ResolvedSymbol; if (resolvedSymbol == null) { return(false); } // otherwise, a type is accessible if any of its declarations is either explicitly exported or defined in the prelude return(resolvedSymbol .GetDeclarations() .Any(d => d.IsExported() || m_semanticModel.TypeChecker.IsPreludeDeclaration(d))); }