📄 FunctionSignature¶
📊 Analysis Summary¶
| Metric | Count |
|---|---|
| 🔧 Functions | 3 |
| 🧱 Classes | 1 |
| 📦 Imports | 2 |
| 📑 Type Aliases | 1 |
| 🎯 Enums | 1 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/eslint-plugin/src/util/FunctionSignature.ts
📦 Imports¶
| Name | Source |
|---|---|
ESLintUtils |
@typescript-eslint/utils |
isRestParameterDeclaration |
./misc |
Functions¶
FunctionSignature.create(checker: ts.TypeChecker, tsNode: ts.CallLikeExpression): FunctionSignature¶
Parameters:
checkerts.TypeCheckertsNodets.CallLikeExpression
Returns: FunctionSignature
Calls:
nullThrowschecker.getResolvedSignaturesignature.getParametersparam.getDeclarationschecker.getTypeOfSymbolAtLocationchecker.getBaseConstraintOfTypeisRestParameterDeclaration (from ./misc)checker.isTupleTypechecker.getTypeArgumentschecker.getIndexTypeOfTypeparamTypes.push
Internal Comments:
// getResolvedSignature only returns undefined for nodes outside the parse (x2)
// tree, and tsNode always comes from the AST node map. (x2)
Code
public static create(
checker: ts.TypeChecker,
tsNode: ts.CallLikeExpression,
): FunctionSignature {
// getResolvedSignature only returns undefined for nodes outside the parse
// tree, and tsNode always comes from the AST node map.
const signature = nullThrows(
checker.getResolvedSignature(tsNode),
'Expected the call-like node to resolve to a signature.',
);
const paramTypes = [];
let restType: RestType | null = null;
const parameters = signature.getParameters();
for (let index = 0; index < parameters.length; index += 1) {
const param = parameters[index];
const declaration = param.getDeclarations()?.[0];
const type = checker.getTypeOfSymbolAtLocation(param, tsNode);
const constrainedType = checker.getBaseConstraintOfType(type) ?? type;
if (declaration && isRestParameterDeclaration(declaration)) {
if (checker.isTupleType(constrainedType)) {
restType = {
index,
kind: RestTypeKind.Tuple,
typeArguments: checker.getTypeArguments(constrainedType),
};
} else {
const elementType = checker.getIndexTypeOfType(
constrainedType,
ts.IndexKind.Number,
);
restType = elementType
? { index, kind: RestTypeKind.Array, type: elementType }
: { index, kind: RestTypeKind.Other, type: constrainedType };
}
break;
}
paramTypes.push(type);
}
return new FunctionSignature(paramTypes, restType);
}
FunctionSignature.consumeRemainingArguments(): void¶
Returns: void
FunctionSignature.getNextParameterType(): ts.Type | null¶
Returns: ts.Type | null
Code
public getNextParameterType(): ts.Type | null {
const index = this.parameterTypeIndex;
this.parameterTypeIndex += 1;
if (index >= this.paramTypes.length || this.hasConsumedArguments) {
if (this.restType == null) {
return null;
}
switch (this.restType.kind) {
case RestTypeKind.Tuple: {
const { typeArguments } = this.restType;
if (this.hasConsumedArguments) {
return typeArguments[typeArguments.length - 1];
}
const typeIndex = index - this.restType.index;
if (typeIndex >= typeArguments.length) {
return typeArguments[typeArguments.length - 1];
}
return typeArguments[typeIndex];
}
case RestTypeKind.Array:
case RestTypeKind.Other:
return this.restType.type;
}
}
return this.paramTypes[index];
}
Classes¶
FunctionSignature¶
Tracks checking the parameters of a single function signature. This allows rules to "consume" parameters and check for unsafe comparisons.
Class Code
export class FunctionSignature {
private hasConsumedArguments = false;
private parameterTypeIndex = 0;
private constructor(
private readonly paramTypes: ts.Type[],
private readonly restType: RestType | null,
) {}
public static create(
checker: ts.TypeChecker,
tsNode: ts.CallLikeExpression,
): FunctionSignature {
// getResolvedSignature only returns undefined for nodes outside the parse
// tree, and tsNode always comes from the AST node map.
const signature = nullThrows(
checker.getResolvedSignature(tsNode),
'Expected the call-like node to resolve to a signature.',
);
const paramTypes = [];
let restType: RestType | null = null;
const parameters = signature.getParameters();
for (let index = 0; index < parameters.length; index += 1) {
const param = parameters[index];
const declaration = param.getDeclarations()?.[0];
const type = checker.getTypeOfSymbolAtLocation(param, tsNode);
const constrainedType = checker.getBaseConstraintOfType(type) ?? type;
if (declaration && isRestParameterDeclaration(declaration)) {
if (checker.isTupleType(constrainedType)) {
restType = {
index,
kind: RestTypeKind.Tuple,
typeArguments: checker.getTypeArguments(constrainedType),
};
} else {
const elementType = checker.getIndexTypeOfType(
constrainedType,
ts.IndexKind.Number,
);
restType = elementType
? { index, kind: RestTypeKind.Array, type: elementType }
: { index, kind: RestTypeKind.Other, type: constrainedType };
}
break;
}
paramTypes.push(type);
}
return new FunctionSignature(paramTypes, restType);
}
public consumeRemainingArguments(): void {
this.hasConsumedArguments = true;
}
public getNextParameterType(): ts.Type | null {
const index = this.parameterTypeIndex;
this.parameterTypeIndex += 1;
if (index >= this.paramTypes.length || this.hasConsumedArguments) {
if (this.restType == null) {
return null;
}
switch (this.restType.kind) {
case RestTypeKind.Tuple: {
const { typeArguments } = this.restType;
if (this.hasConsumedArguments) {
return typeArguments[typeArguments.length - 1];
}
const typeIndex = index - this.restType.index;
if (typeIndex >= typeArguments.length) {
return typeArguments[typeArguments.length - 1];
}
return typeArguments[typeIndex];
}
case RestTypeKind.Array:
case RestTypeKind.Other:
return this.restType.type;
}
}
return this.paramTypes[index];
}
}
Methods (3) — full entries under Functions
| Method | Signature |
|---|---|
create |
(checker: ts.TypeChecker, tsNode: ts.CallLikeExpression): FunctionSignature |
consumeRemainingArguments |
(): void |
getNextParameterType |
(): ts.Type \| null |
Type Aliases¶
RestType¶
type RestType = | {
index: number;
kind: RestTypeKind.Array;
type: ts.Type;
}
| {
index: number;
kind: RestTypeKind.Other;
type: ts.Type;
}
| {
index: number;
kind: RestTypeKind.Tuple;
typeArguments: readonly ts.Type[];
};
Enums¶
const enum RestTypeKind¶
Members¶
| Name | Value | Description |
|---|---|---|
Array |
auto | not shown |
Other |
auto | not shown |
Tuple |
auto | not shown |
Generated by Syntax Scribe