This commit is contained in:
TypeScript Bot
2023-03-20 23:35:42 +00:00
parent 706a75630b
commit 59764475b8
2 changed files with 27 additions and 20 deletions

View File

@@ -8,7 +8,8 @@ const rule = createRule({
meta: {
type: "problem",
docs: {
description: "Forbids optional parameters from including an explicit `undefined` in their type; requires it in optional properties.",
description:
"Forbids optional parameters from including an explicit `undefined` in their type; requires it in optional properties.",
recommended: "error",
},
messages: {
@@ -21,11 +22,13 @@ const rule = createRule({
// eslint-disable-next-line @typescript-eslint/naming-convention
TSUnionType(node) {
const hasUndefinedType = node.types.some((t) => t.type === AST_NODE_TYPES.TSUndefinedKeyword);
if (node.parent!.type === AST_NODE_TYPES.TSTypeAnnotation
&& isParameter(node.parent!.parent!)
&& node.parent.parent.optional
&& isFunctionLike(node.parent!.parent!.parent!)
&& hasUndefinedType) {
if (
node.parent!.type === AST_NODE_TYPES.TSTypeAnnotation &&
isParameter(node.parent!.parent!) &&
node.parent.parent.optional &&
isFunctionLike(node.parent!.parent!.parent!) &&
hasUndefinedType
) {
context.report({
messageId: "redundantUndefined",
node,
@@ -37,19 +40,23 @@ const rule = createRule({
});
function isFunctionLike(node: TSESTree.Node): node is TSESTree.FunctionLike {
return node.type === AST_NODE_TYPES.ArrowFunctionExpression
|| node.type === AST_NODE_TYPES.FunctionDeclaration
|| node.type === AST_NODE_TYPES.FunctionExpression
|| node.type === AST_NODE_TYPES.TSDeclareFunction
|| node.type === AST_NODE_TYPES.TSEmptyBodyFunctionExpression;
return (
node.type === AST_NODE_TYPES.ArrowFunctionExpression ||
node.type === AST_NODE_TYPES.FunctionDeclaration ||
node.type === AST_NODE_TYPES.FunctionExpression ||
node.type === AST_NODE_TYPES.TSDeclareFunction ||
node.type === AST_NODE_TYPES.TSEmptyBodyFunctionExpression
);
}
/** Note: Does not include parameter properties because those can't be optional */
function isParameter(node: TSESTree.Node): node is Exclude<TSESTree.Parameter, TSESTree.TSParameterProperty> {
return node.type === AST_NODE_TYPES.ArrayPattern
|| node.type === AST_NODE_TYPES.AssignmentPattern
|| node.type === AST_NODE_TYPES.Identifier
|| node.type === AST_NODE_TYPES.ObjectPattern
|| node.type === AST_NODE_TYPES.RestElement;
return (
node.type === AST_NODE_TYPES.ArrayPattern ||
node.type === AST_NODE_TYPES.AssignmentPattern ||
node.type === AST_NODE_TYPES.Identifier ||
node.type === AST_NODE_TYPES.ObjectPattern ||
node.type === AST_NODE_TYPES.RestElement
);
}
export = rule;

View File

@@ -9,7 +9,6 @@ const ruleTester = new ESLintUtils.RuleTester({
ruleTester.run("redundant-undefined", redundantUndefined, {
invalid: [
{
code: `function f(s?: string | undefined): void {}`,
errors: [
{
@@ -19,7 +18,6 @@ ruleTester.run("redundant-undefined", redundantUndefined, {
],
},
{
code: `function f([a, b]?: [number, number] | undefined): void {}`,
errors: [
{
@@ -29,11 +27,13 @@ ruleTester.run("redundant-undefined", redundantUndefined, {
],
},
],
valid: [`
valid: [
`
interface I {
ok?: string | undefined;
s?: string;
almost?: number | string;
}
`],
`,
],
});