Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
| TSESTree.VariableDeclarator
| TSESTree.Parameter
| TSESTree.ClassProperty,
typeNode: TSESTree.TSTypeAnnotation | undefined,
initNode: TSESTree.Expression | null | undefined,
): void {
if (!typeNode || !initNode || !typeNode.typeAnnotation) {
return;
}
if (!isInferrable(typeNode.typeAnnotation, initNode)) {
return;
}
const type =
typeNode.typeAnnotation.type === AST_NODE_TYPES.TSTypeReference
? // TODO - if we add more references
'RegExp'
: keywordMap[typeNode.typeAnnotation.type];
context.report({
node,
messageId: 'noInferrableType',
data: {
type,
},
fix: fixer => fixer.remove(typeNode),
});
}
function checkType(node: TSESTree.TypeNode): boolean {
switch (node.type) {
case AST_NODE_TYPES.TSAnyKeyword:
case AST_NODE_TYPES.TSUnknownKeyword:
return false;
case AST_NODE_TYPES.TSTypeReference:
return (
// Ignore `as const` and ``
(node.typeName.type === AST_NODE_TYPES.Identifier &&
node.typeName.name !== 'const') ||
// Allow qualified names which have dots between identifiers, `Foo.Bar`
node.typeName.type === AST_NODE_TYPES.TSQualifiedName
);
default:
return true;
}
}
AST_NODE_TYPES.TSParameterProperty,
AST_NODE_TYPES.TSParenthesizedType,
'TSPlusToken',
AST_NODE_TYPES.TSPropertySignature,
AST_NODE_TYPES.TSQualifiedName,
'TSQuestionToken',
AST_NODE_TYPES.TSRestType,
AST_NODE_TYPES.TSThisType,
AST_NODE_TYPES.TSTupleType,
AST_NODE_TYPES.TSTypeAnnotation,
AST_NODE_TYPES.TSTypeLiteral,
AST_NODE_TYPES.TSTypeOperator,
AST_NODE_TYPES.TSTypeParameter,
AST_NODE_TYPES.TSTypeParameterDeclaration,
AST_NODE_TYPES.TSTypeParameterInstantiation,
AST_NODE_TYPES.TSTypeReference,
AST_NODE_TYPES.TSUnionType,
AST_NODE_TYPES.Decorator,
]);
export default util.createRule({
name: 'indent',
meta: {
type: 'layout',
docs: {
description: 'Enforce consistent indentation',
category: 'Stylistic Issues',
// too opinionated to be recommended
recommended: false,
},
fixable: 'whitespace',
schema: baseRule.meta.schema,
function isNodeValidArrayTSTypeReference(node: TSESTree.Node): boolean {
return (
node.type === AST_NODE_TYPES.TSTypeReference &&
typeof node.typeName !== 'undefined' &&
node.typeName.type === AST_NODE_TYPES.Identifier &&
['Array', 'ReadonlyArray'].includes(node.typeName.name)
);
}
AST_NODE_TYPES.TSParameterProperty,
AST_NODE_TYPES.TSParenthesizedType,
'TSPlusToken',
AST_NODE_TYPES.TSPropertySignature,
AST_NODE_TYPES.TSQualifiedName,
'TSQuestionToken',
AST_NODE_TYPES.TSRestType,
AST_NODE_TYPES.TSThisType,
AST_NODE_TYPES.TSTupleType,
AST_NODE_TYPES.TSTypeAnnotation,
AST_NODE_TYPES.TSTypeLiteral,
AST_NODE_TYPES.TSTypeOperator,
AST_NODE_TYPES.TSTypeParameter,
AST_NODE_TYPES.TSTypeParameterDeclaration,
AST_NODE_TYPES.TSTypeParameterInstantiation,
AST_NODE_TYPES.TSTypeReference,
AST_NODE_TYPES.TSUnionType,
]);
const STATEMENT_LIST_PARENTS = new Set([
AST_NODE_TYPES.Program,
AST_NODE_TYPES.BlockStatement,
AST_NODE_TYPES.SwitchCase,
]);
const DEFAULT_VARIABLE_INDENT = 1;
const DEFAULT_PARAMETER_INDENT = 1;
const DEFAULT_FUNCTION_BODY_INDENT = 1;
/*
* General rule strategy:
* 1. An OffsetStorage instance stores a map of desired offsets, where each token has a specified offset from another
* specified token or to the first column.
* 2. As the AST is traversed, modify the desired offsets of tokens accordingly. For example, when entering a
function returnsConstAssertionDirectly(
node: TSESTree.ArrowFunctionExpression,
): boolean {
const { body } = node;
if (util.isTypeAssertion(body)) {
const { typeAnnotation } = body;
if (typeAnnotation.type === AST_NODE_TYPES.TSTypeReference) {
const { typeName } = typeAnnotation;
if (
typeName.type === AST_NODE_TYPES.Identifier &&
typeName.name === 'const'
) {
return true;
}
}
}
return false;
}
],
) {
const unions = ['always', 'in-unions', 'in-unions-and-intersections'];
const intersections = [
'always',
'in-intersections',
'in-unions-and-intersections',
];
const compositions = [
'in-unions',
'in-intersections',
'in-unions-and-intersections',
];
const aliasTypes = new Set([
AST_NODE_TYPES.TSArrayType,
AST_NODE_TYPES.TSTypeReference,
AST_NODE_TYPES.TSLiteralType,
AST_NODE_TYPES.TSTypeQuery,
AST_NODE_TYPES.TSIndexedAccessType,
]);
/**
* Determines if the composition type is supported by the allowed flags.
* @param isTopLevel a flag indicating this is the top level node.
* @param compositionType the composition type (either TSUnionType or TSIntersectionType)
* @param allowed the currently allowed flags.
*/
function isSupportedComposition(
isTopLevel: boolean,
compositionType: CompositionType | null,
allowed: string,
): boolean {
function typeContainsTypeParameter(
type?: TSESTree.TSTypeAnnotation | TSESTree.TypeNode,
): boolean {
if (!type) {
return false;
}
if (type.type === AST_NODE_TYPES.TSTypeReference) {
const typeName = type.typeName;
if (isIdentifier(typeName) && isTypeParameter(typeName.name)) {
return true;
}
}
return typeContainsTypeParameter(
(type as TSESTree.TSTypeAnnotation).typeAnnotation ||
(type as TSESTree.TSArrayType).elementType,
);
}
}
export function isTSTypeReference(
node: TSESTree.Node
): node is TSESTree.TSTypeReference {
return node.type === AST_NODE_TYPES.TSTypeReference;
}
function typeNeedsParentheses(node: TSESTree.Node): boolean {
switch (node.type) {
case AST_NODE_TYPES.TSTypeReference:
return typeNeedsParentheses(node.typeName);
case AST_NODE_TYPES.TSUnionType:
case AST_NODE_TYPES.TSFunctionType:
case AST_NODE_TYPES.TSIntersectionType:
case AST_NODE_TYPES.TSTypeOperator:
case AST_NODE_TYPES.TSInferType:
return true;
case AST_NODE_TYPES.Identifier:
return node.name === 'ReadonlyArray';
default:
return false;
}
}