Skip to content

Commit 8320241

Browse files
feat: support TypeScript syntax in default-param-last (#19431)
* feat: support TypeScript syntax in `default-param-last` * Apply suggestions from code review Co-authored-by: Nicholas C. Zakas <[email protected]> * Simplify naming and runtime logic * Added ```ts support to rule docs examples * nit: parser name * meta.docs.typescript: 'syntax' * fix: example tooling tests * Add: meta.dialects, language * Remove the typescript: syntax * Don't render playground links for ts code blocks --------- Co-authored-by: Nicholas C. Zakas <[email protected]>
1 parent 280128f commit 8320241

File tree

7 files changed

+612
-14
lines changed

7 files changed

+612
-14
lines changed

docs/.eleventy.js

+8
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,14 @@ module.exports = function(eleventyConfig) {
202202
const ruleExampleOptions = markdownItRuleExample({
203203
open({ type, code, languageOptions, env, codeBlockToken }) {
204204

205+
/*
206+
* TypeScript isn't yet supported on the playground:
207+
* https://github.com/eslint/eslint.org/issues/709
208+
*/
209+
if (codeBlockToken.info === "ts") {
210+
return `<div class="${type}">`;
211+
}
212+
205213
prismESLintHook.addContentMustBeMarked(codeBlockToken.content, languageOptions);
206214

207215
const isRuleRemoved = !Object.hasOwn(env.rules_meta, env.title);

docs/src/rules/default-param-last.md

+28
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,34 @@ Examples of **correct** code for this rule:
4141
/* eslint default-param-last: ["error"] */
4242

4343
function f(a, b = 0) {}
44+
45+
function g(a, b = 0, c = 0) {}
46+
```
47+
48+
:::
49+
50+
This rule additionally supports TypeScript type syntax.
51+
52+
Examples of **incorrect** TypeScript code for this rule:
53+
54+
::: incorrect
55+
56+
```ts
57+
/* eslint default-param-last: ["error"] */
58+
59+
function h(a = 0, b: number) {}
60+
```
61+
62+
:::
63+
64+
Examples of **correct** TypeScript code for this rule:
65+
66+
::: correct
67+
68+
```ts
69+
/* eslint default-param-last: ["error"] */
70+
71+
function h(a = 0, b?: number) {}
4472
```
4573

4674
:::

lib/rules/default-param-last.js

+25-9
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,24 @@
55

66
"use strict";
77

8+
/**
9+
* Checks if node is required: i.e. does not have a default value or ? optional indicator.
10+
* @param {ASTNode} node the node to be evaluated
11+
* @returns {boolean} true if the node is required, false if not.
12+
*/
13+
function isRequiredParameter(node) {
14+
return !(
15+
node.type === "AssignmentPattern" ||
16+
node.type === "RestElement" ||
17+
node.optional
18+
);
19+
}
20+
821
/** @type {import('../shared/types').Rule} */
922
module.exports = {
1023
meta: {
24+
dialects: ["javascript", "typescript"],
25+
language: "javascript",
1126
type: "suggestion",
1227

1328
docs: {
@@ -32,22 +47,23 @@ module.exports = {
3247
* @returns {void}
3348
*/
3449
function handleFunction(node) {
35-
let hasSeenPlainParam = false;
50+
let hasSeenRequiredParameter = false;
3651

3752
for (let i = node.params.length - 1; i >= 0; i -= 1) {
38-
const param = node.params[i];
53+
const current = node.params[i];
54+
const param =
55+
current.type === "TSParameterProperty"
56+
? current.parameter
57+
: current;
3958

40-
if (
41-
param.type !== "AssignmentPattern" &&
42-
param.type !== "RestElement"
43-
) {
44-
hasSeenPlainParam = true;
59+
if (isRequiredParameter(param)) {
60+
hasSeenRequiredParameter = true;
4561
continue;
4662
}
4763

48-
if (hasSeenPlainParam && param.type === "AssignmentPattern") {
64+
if (hasSeenRequiredParameter) {
4965
context.report({
50-
node: param,
66+
node: current,
5167
messageId: "shouldBeLast"
5268
});
5369
}

tests/fixtures/bad-examples.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default "foo";
1717

1818
:::correct
1919

20-
````ts
20+
````rs
2121
const foo = "bar";
2222

2323
const foo = "baz";

0 commit comments

Comments
 (0)