Utility functions for working with TypeScript's API. Successor to the wonderful tsutils.
npm i ts-api-utils
import * as tsutils from "ts-api-utils";
ts-api-utils
provides several categories of utility functions:
- Comments
- Compiler Options
- Flags
- Modifiers
- Node Type Guards
- Node Utilities
- Scopes
- Syntax
- Tokens
- Type Getters
- Type Type Guards
- Type Utilities
This package is a partial fork of and replacement for
tsutils
(original license: MIT). See #3 for notes on API coverage compared totsutils
.
Iterates over all comments owned by node
or its children.
type ForEachCommentCallback = (fullText: string, comment: ts.CommentRange) => void
function forEachComment(node: ts.Node, callback: ForEachCommentCallback, sourceFile?: ts.SourceFile): void
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.forEachComment(node, (fullText, comment) => {
console.log(`Found comment at position ${comment.pos}: '${fullText}'.`);
});
Checks if a given compiler option is enabled.
It handles dependencies of options, e.g. declaration
is implicitly enabled by composite
or strictNullChecks
is enabled by strict
.
However, it does not check dependencies that are already checked and reported as errors, e.g. checkJs
without allowJs
.
This function only handles boolean flags.
type BooleanCompilerOptions =
(all keys ofts.CompilerOptions
with aboolean
value)function isCompilerOptionEnabled(options: ts.CompilerOptions, option: BooleanCompilerOptions): boolean
import * as tsutils from "ts-api-utils";
const options = {
allowJs: true,
};
tsutils.isCompilerOptionEnabled(options, "allowJs"); // true
tsutils.isCompilerOptionEnabled(options, "allowSyntheticDefaultImports"); // false
Checks if a given compiler option is enabled, accounting for whether all flags (except strictPropertyInitialization
) have been enabled by strict: true
.
type StrictCompilerOption =
(all keys ofts.CompilerOptions
relevant tostrict
)function isStrictCompilerOptionEnabled(options: ts.CompilerOptions, option: StrictCompilerOption): boolean
import * as tsutils from "ts-api-utils";
const optionsLenient = {
noImplicitAny: true,
};
tsutils.isStrictCompilerOptionEnabled(optionsLenient, "noImplicitAny"); // true
tsutils.isStrictCompilerOptionEnabled(optionsLenient, "noImplicitThis"); // false
const optionsStrict = {
noImplicitThis: false,
strict: true,
};
tsutils.isStrictCompilerOptionEnabled(optionsStrict, "noImplicitAny"); // true
tsutils.isStrictCompilerOptionEnabled(optionsStrict, "noImplicitThis"); // false
function isModifierFlagSet(node: ts.Declaration, flag: ts.ModifierFlags): boolean
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isModifierFlagSet(node, ts.ModifierFlags.Abstract);
function isNodeFlagSet(node: ts.Node, flag: ts.NodeFlags): boolean
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isNodeFlagSet(node, ts.NodeFlags.AwaitContext);
function isObjectFlagSet(node: ts.ObjectType, flag: ts.ObjectFlags): boolean
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isObjectFlagSet(node, ts.ObjectFlags.Anonymous);
function isSymbolFlagSet(symbol: ts.Symbol, flag: ts.SymbolFlags): boolean
import * as tsutils from "ts-api-utils";
declare const symbol: ts.Symbol;
tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Accessor);
function isTypeFlagSet(type: ts.Type, flag: ts.TypeFlags): boolean
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isTypeFlagSet(type, ts.TypeFlags.Any);
function isEntityNameExpression(node: ts.Node): node is ts.EntityNameExpression
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isEntityNameExpression(node);
function isExpression(node: ts.Node): node is ts.Expression
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isExpression(node);
function isNumericOrStringLikeLiteral(node: ts.Node): node is NumericOrStringLikeLiteral
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isNumericOrStringLikeLiteral(node);
function isParameterDeclaration(node: ts.Node): node is ts.ParameterDeclaration
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isParameterDeclaration(node);
function isConstAssertion(node: ts.AssertionExpression): node is ConstAssertionExpression
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isConstAssertion(node);
Determines whether a call to Object.defineProperty
is statically analyzable.
function isBindableObjectDefinePropertyCall(node: ts.CallExpression): boolean
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isBindableObjectDefinePropertyCall(node);
Detects whether an expression is affected by an enclosing 'as const' assertion and therefore treated literally.
function isInConstContext(node: ts.Expression): boolean
import * as tsutils from "ts-api-utils";
declare const node: ts.Expression;
tsutils.isInConstContext(node);
function hasModifier(modifiers: Iterable<ts.Modifier> | undefined, ...kinds: ts.Modifier): boolean
import * as tsutils from "ts-api-utils";
declare const modifiers: ts.Modifier[];
tsutils.hasModifier(modifiers, ts.SyntaxKind.AbstractKeyword);
const enum ScopeBoundary { None, Function }
function isFunctionScopeBoundary(node: ts.Node): ScopeBoundary
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.isFunctionScopeBoundary(node);
function isAssignmentKind(kind: ts.SyntaxKind): boolean
import * as tsutils from "ts-api-utils";
declare const kind: ts.SyntaxKind;
tsutils.isAssignmentKind(kind);
function isNumericPropertyName(name: string | ts.__String): boolean
import * as tsutils from "ts-api-utils";
tsutils.isNumericPropertyName("abc"); // false
tsutils.isNumericPropertyName("123"); // true
Determines whether the given text can be used to access a property with a PropertyAccessExpression while preserving the property's name.
function isValidPropertyAccess(text: string, languageVersion?: ts.ScriptTarget): void
import * as tsutils from "ts-api-utils";
tsutils.isValidPropertyAccess("abc"); // true
tsutils.isValidPropertyAccess("123"); // false
Iterates over all tokens of node
.
type ForEachTokenCallback = (token: ts.Node) => void
function forEachToken(node: ts.Node, callback: ForEachTokenCallback, sourceFile?: ts.SourceFile): void
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
tsutils.forEachToken(node, (token) => {
console.log("Found token:", token.getText());
});
function getCallSignaturesOfType(type: ts.Type): readonly ts.Signature[]
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.getCallSignaturesOfType(type);
function getPropertyOfType(type: ts.Type, name: ts.__String): ts.Symbol | undefined
import * as tsutils from "ts-api-utils";
declare const property: ts.Symbol;
declare const type: ts.Type;
tsutils.getPropertyOfType(type, property.getEscapedName());
function isConditionalType(type: ts.Type): type is ts.ConditionalType
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isConditionalType(type);
function isIntersectionType(type: ts.Type): type is ts.IntersectionType
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isIntersectionType(type);
function isLiteralType(type: ts.Type): type is ts.LiteralType
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isLiteralType(type);
function isObjectType(type: ts.Type): type is ts.ObjectType
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isObjectType(type);
function isUnionOrIntersectionType(type: ts.Type): type is ts.UnionOrIntersectionType
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isUnionOrIntersectionType(type);
function isUnionType(type: ts.Type): type is ts.UnionType
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isUnionType(type);
function isUniqueESSymbolType(type: ts.Type): type is ts.UniqueESSymbolType
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isUniqueESSymbolType(type);
function isTupleType(type: ts.Type): type is ts.TupleType
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isTupleType(type);
function isTupleTypeReference(type: ts.Type): type is TupleTypeReference
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isTupleTypeReference(type);
function isTypeReference(type: ts.Type): type is ts.TypeReference
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isTypeReference(type);
function getWellKnownSymbolPropertyOfType(type: ts.Type, wellKnownSymbolName: string, typeChecker: ts.TypeChecker): ts.Symbol | undefined
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
declare const typeChecker: ts.TypeChecker;
tsutils.getWellKnownSymbolPropertyOfType(type, "asyncIterator", typeChecker);
Determines whether the given type is a boolean literal type and matches the given boolean literal.
function isBooleanLiteralType(type: ts.Type, literal: boolean)
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isBooleanLiteralType(type);
Determines whether a type is definitely falsy. This function doesn't unwrap union types.
function isFalsyType(type: ts.Type): boolean
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.isFalsyType(type);
Determines whether writing to a certain property of a given type is allowed.
function isPropertyReadonlyInType(type: ts.Type, name: ts.__String, typeChecker: ts.TypeChecker): boolean
import * as tsutils from "ts-api-utils";
declare const property: ts.Symbol;
declare const type: ts.Type;
declare const typeChecker: ts.TypeChecker;
tsutils.isPropertyReadonlyInType(type, property.getEscapedName(), typeChecker);
Determines whether a type is thenable and thus can be used with await
.
function isThenableType(typeChecker: ts.TypeChecker, node: ts.Node, type: ts.Type): boolean
function isThenableType(typeChecker: ts.TypeChecker, node: ts.Expression, type?: ts.Type): boolean
import * as tsutils from "ts-api-utils";
declare const node: ts.Node;
declare const type: ts.Type;
declare const typeChecker: ts.TypeChecker;
tsutils.isThenableType(typeChecker, node, type);
declare const expression: ts.Expression;
tsutils.isThenableType(typeChecker, expression);
tsutils.isThenableType(typeChecker, expression, type);
type SomeTypePartPredicate = (type: ts.Type) => type is ts.UnionOrIntersectionType
type SomeTypePartCallback = (type: ts.Type) => boolean
function someTypePart(type: ts.Type, predicate: SomeTypePartPredicate, callback: SomeTypePartCallback): boolean
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
declare const typeChecker: ts.TypeChecker;
tsutils.someTypePart(type, tsutils.isUnionOrIntersectionType, (subType) => {
console.log("Got a literal type:", typeChecker.typeToString(subType));
});
function symbolHasReadonlyDeclaration(symbol: ts.Symbol, typeChecker: ts.TypeChecker): boolean
import * as tsutils from "ts-api-utils";
declare const symbol: ts.Symbol;
declare const typeChecker: ts.TypeChecker;
tsutils.symbolHasReadonlyDeclaration(symbol, typeChecker);
function unionTypeParts(type: ts.Type): ts.Type[]
import * as tsutils from "ts-api-utils";
declare const type: ts.Type;
tsutils.unionTypeParts(type);
See .github/CONTRIBUTING.md
.
Thanks! π
Many thanks to @ajafff for creating the original tsutils
that this project is based on and uses a significant majority of code from! π
Josh Goldberg π π» π π |
Rebecca Stevens π π» π π |
Klaus Meinhardt π» |
π This package is templated from @JoshuaKGoldberg's template-typescript-node-package.
"My tools! I have to have my tools!" - Dennis Reynolds