Core Angular Language Service interface that extends TypeScript's language service with Angular-specific methods for template analysis, navigation, and refactoring.
Main interface that extends TypeScript's LanguageService with Angular-specific functionality.
/**
* Angular Language Service interface extending TypeScript's LanguageService
* Provides Angular-specific methods for template analysis and navigation
*/
interface NgLanguageService extends ts.LanguageService {
/**
* Get Type Check Block information for a template position
* @param fileName - Template or component file name
* @param position - Character position in the file
* @returns TCB information or undefined if not available
*/
getTcb(fileName: string, position: number): GetTcbResponse | undefined;
/**
* Get component locations for a given template file
* @param fileName - Template file name
* @returns Array of document spans pointing to components using this template
*/
getComponentLocationsForTemplate(fileName: string): GetComponentLocationsForTemplateResponse;
/**
* Get template location for a component at a specific position
* @param fileName - Component file name
* @param position - Character position in the component file
* @returns Document span pointing to template location or undefined
*/
getTemplateLocationForComponent(fileName: string, position: number): GetTemplateLocationForComponentResponse;
/**
* Get the underlying TypeScript language service
* @returns Original TypeScript LanguageService instance
*/
getTypescriptLanguageService(): ts.LanguageService;
/**
* Apply a refactoring operation
* @param fileName - File name where refactoring is applied
* @param positionOrRange - Position or text range for refactoring
* @param refactorName - Name of the refactoring to apply
* @param reportProgress - Progress callback function
* @returns Promise resolving to refactoring result or undefined
*/
applyRefactoring(
fileName: string,
positionOrRange: number | ts.TextRange,
refactorName: string,
reportProgress: ApplyRefactoringProgressFn
): Promise<ApplyRefactoringResult | undefined>;
/**
* Check if code fixes are available for a specific error code
* @param errorCode - TypeScript or Angular error code
* @returns True if code fixes are available
*/
hasCodeFixesForErrorCode(errorCode: number): boolean;
/**
* Get token type from semantic classification
* @param classification - Semantic classification number
* @returns Token type number or undefined
*/
getTokenTypeFromClassification(classification: number): number | undefined;
/**
* Get token modifier from semantic classification
* @param classification - Semantic classification number
* @returns Token modifier number
*/
getTokenModifierFromClassification(classification: number): number;
}Response type for Type Check Block queries containing generated TypeScript code for template type checking.
/**
* Response from getTcb method containing Type Check Block information
*/
type GetTcbResponse = {
/**
* Filename of the SourceFile containing the typecheck block
* This filename is opaque and unstable, useful only for debugging
*/
fileName: string;
/**
* Content of the SourceFile containing the typecheck block
* This is generated TypeScript code that represents the template
*/
content: string;
/**
* Text spans corresponding to the template node under the cursor position
* When cursor is over a source with no generated code, selections is empty
*/
selections: ts.TextSpan[];
};Response types for component-template navigation operations.
/**
* Response from getComponentLocationsForTemplate
* Array of document spans pointing to components using the template
*/
type GetComponentLocationsForTemplateResponse = ts.DocumentSpan[];
/**
* Response from getTemplateLocationForComponent
* Document span pointing to template location or undefined if not found
*/
type GetTemplateLocationForComponentResponse = ts.DocumentSpan | undefined;Types related to refactoring operations and progress reporting.
/**
* Progress callback function for refactoring operations
* @param percentage - Completion percentage (0-100)
* @param updateMessage - Status message describing current operation
*/
type ApplyRefactoringProgressFn = (percentage: number, updateMessage: string) => void;
/**
* Result of applying a refactoring operation
* Extends TypeScript's RefactorEditInfo with additional error/warning messages
*/
interface ApplyRefactoringResult extends Omit<ts.RefactorEditInfo, 'notApplicableReason'> {
/** Error message if refactoring failed */
errorMessage?: string;
/** Warning message for successful refactoring with caveats */
warningMessage?: string;
}Utility function to check if a language service instance is Angular-enhanced.
/**
* Type guard to check if a language service is an Angular Language Service
* @param ls - Language service instance to check
* @returns True if the language service is NgLanguageService
*/
function isNgLanguageService(
ls: ts.LanguageService | NgLanguageService
): ls is NgLanguageService;import { NgLanguageService, isNgLanguageService } from "@angular/language-service/api";
function processLanguageService(ls: ts.LanguageService) {
if (isNgLanguageService(ls)) {
// Access Angular-specific methods
const tcb = ls.getTcb("app.component.html", 150);
if (tcb) {
console.log("Generated TypeScript:", tcb.content);
console.log("Template selections:", tcb.selections);
}
// Navigate between component and template
const templateLocation = ls.getTemplateLocationForComponent("app.component.ts", 200);
if (templateLocation) {
console.log("Template file:", templateLocation.fileName);
console.log("Template position:", templateLocation.textSpan);
}
}
}import { NgLanguageService, ApplyRefactoringProgressFn } from "@angular/language-service/api";
async function applySignalRefactoring(ls: NgLanguageService, fileName: string, position: number) {
const progressCallback: ApplyRefactoringProgressFn = (percentage, message) => {
console.log(`${percentage}%: ${message}`);
};
const result = await ls.applyRefactoring(
fileName,
position,
"convert-field-to-signal-input-safe-mode",
progressCallback
);
if (result?.errorMessage) {
console.error("Refactoring failed:", result.errorMessage);
} else if (result?.warningMessage) {
console.warn("Refactoring completed with warnings:", result.warningMessage);
} else if (result) {
console.log("Refactoring completed successfully");
console.log("Edit info:", result.edits);
}
}
// Example: Converting all inputs in a class to signal inputs
async function convertClassToSignalInputs(ls: NgLanguageService, fileName: string, position: number) {
const result = await ls.applyRefactoring(
fileName,
position,
"convert-full-class-to-signal-inputs-safe-mode",
(percentage, message) => console.log(`${percentage}%: ${message}`)
);
return result;
}
// Example: Converting a query to signal query
async function convertToSignalQuery(ls: NgLanguageService, fileName: string, position: number) {
const result = await ls.applyRefactoring(
fileName,
position,
"convert-field-to-signal-query-safe-mode",
(percentage, message) => console.log(`${percentage}%: ${message}`)
);
return result;
}import { NgLanguageService } from "@angular/language-service/api";
function checkCodeFixes(ls: NgLanguageService, errorCode: number) {
if (ls.hasCodeFixesForErrorCode(errorCode)) {
console.log(`Code fixes available for error ${errorCode}`);
// Use standard TypeScript language service methods to get fixes
const fixes = ls.getCodeFixesAtPosition(
"app.component.ts",
100,
200,
[errorCode],
{}, // format options
{} // preferences
);
console.log("Available fixes:", fixes);
}
}import { NgLanguageService } from "@angular/language-service/api";
function processSemanticTokens(ls: NgLanguageService, classification: number) {
const tokenType = ls.getTokenTypeFromClassification(classification);
const tokenModifier = ls.getTokenModifierFromClassification(classification);
console.log("Token type:", tokenType);
console.log("Token modifier:", tokenModifier);
}