eslint-config-typed 4.0.7 → 4.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/configs/typescript.d.mts.map +1 -1
- package/dist/configs/typescript.mjs +2 -0
- package/dist/configs/typescript.mjs.map +1 -1
- package/dist/plugins/react-coding-style/rules/use-memo-hooks-style.mjs +18 -9
- package/dist/plugins/react-coding-style/rules/use-memo-hooks-style.mjs.map +1 -1
- package/package.json +10 -9
- package/src/configs/typescript.mts +4 -0
- package/src/plugins/react-coding-style/rules/use-memo-hooks-style-named.test.mts +47 -11
- package/src/plugins/react-coding-style/rules/use-memo-hooks-style-namespace.test.mts +47 -11
- package/src/plugins/react-coding-style/rules/use-memo-hooks-style.mts +24 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescript.d.mts","sourceRoot":"","sources":["../../src/configs/typescript.mts"],"names":[],"mappings":"AAkBA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGvE,eAAO,MAAM,yBAAyB,GAAI,8EAMvC,QAAQ,CAAC;IACV,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC,KAAG,SAAS,UAAU,
|
|
1
|
+
{"version":3,"file":"typescript.d.mts","sourceRoot":"","sources":["../../src/configs/typescript.mts"],"names":[],"mappings":"AAkBA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGvE,eAAO,MAAM,yBAAyB,GAAI,8EAMvC,QAAQ,CAAC;IACV,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC,KAAG,SAAS,UAAU,EA6FZ,CAAC"}
|
|
@@ -66,6 +66,8 @@ const eslintConfigForTypeScript = ({ files, packageDirs, tsconfigFileName, tscon
|
|
|
66
66
|
files: ['**/*.d.{ts,mts,cts}'],
|
|
67
67
|
rules: defineKnownRules({
|
|
68
68
|
'@typescript-eslint/triple-slash-reference': 'off',
|
|
69
|
+
// Because interface is often used
|
|
70
|
+
'@typescript-eslint/consistent-type-definitions': 'off',
|
|
69
71
|
'import-x/unambiguous': 'off',
|
|
70
72
|
}),
|
|
71
73
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescript.mjs","sources":["../../src/configs/typescript.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAqBO,MAAM,yBAAyB,GAAG,CAAC,EACxC,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GAOhB,KACA;AACE,IAAA,GAAG,qCAAqC,CAAC;QACvC,gBAAgB;QAChB,eAAe;KAChB,CAAC;AACF,IAAA;AACE,QAAA,KAAK,EAAE,KAAK,IAAI,CAAC,sCAAsC,CAAC;QACxD,KAAK,EAAE,gBAAgB,CAAC;AACtB,YAAA,GAAG,oBAAoB;AACvB,YAAA,GAAG,8BAA8B;AACjC,YAAA,GAAG,qBAAqB;AACxB,YAAA,GAAG,yBAAyB;AAC5B,YAAA,GAAG,kBAAkB;AACrB,YAAA,GAAG,eAAe;AAClB,YAAA,GAAG,kBAAkB;AACrB,YAAA,GAAG,WAAW;AACd,YAAA,GAAG,oBAAoB;AACvB,YAAA,GAAG,mBAAmB;AACtB,YAAA,GAAG,kBAAkB;AACrB,YAAA,GAAG,qBAAqB;AACxB,YAAA,GAAG,uBAAuB;AAC1B,YAAA,GAAG,oCAAoC;AACvC,YAAA,GAAG,yBAAyB;AAE5B,YAAA,yCAAyC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;AAExD,YAAA,qCAAqC,EAAE;gBACrC,OAAO;AACP,gBAAA;AACE,oBAAA,UAAU,EAAE,WAAW;AACxB,iBAAA;AACF,aAAA;YACD,IAAI,gBAAgB,KAAK;AACvB,kBAAE;AACE,oBAAA,iDAAiD,EAAE,KAAK;AACxD,oBAAA,2DAA2D,EACzD,KAAK;AACR;kBACD,EAAE,CAAC;SACR,CAAC;AACH,KAAA;AACD,IAAA;QACE,KAAK,EAAE,CAAC,uBAAuB,CAAC;QAChC,KAAK,EAAE,gBAAgB,CAAC;AACtB,YAAA,kDAAkD,EAAE,KAAK;AACzD,YAAA,8BAA8B,EAAE,KAAK;SACtC,CAAC;AACH,KAAA;AACD,IAAA;QACE,KAAK,EAAE,CAAC,qBAAqB,CAAC;QAC9B,KAAK,EAAE,gBAAgB,CAAC;AACtB,YAAA,2CAA2C,EAAE,KAAK;
|
|
1
|
+
{"version":3,"file":"typescript.mjs","sources":["../../src/configs/typescript.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAqBO,MAAM,yBAAyB,GAAG,CAAC,EACxC,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,gBAAgB,GAOhB,KACA;AACE,IAAA,GAAG,qCAAqC,CAAC;QACvC,gBAAgB;QAChB,eAAe;KAChB,CAAC;AACF,IAAA;AACE,QAAA,KAAK,EAAE,KAAK,IAAI,CAAC,sCAAsC,CAAC;QACxD,KAAK,EAAE,gBAAgB,CAAC;AACtB,YAAA,GAAG,oBAAoB;AACvB,YAAA,GAAG,8BAA8B;AACjC,YAAA,GAAG,qBAAqB;AACxB,YAAA,GAAG,yBAAyB;AAC5B,YAAA,GAAG,kBAAkB;AACrB,YAAA,GAAG,eAAe;AAClB,YAAA,GAAG,kBAAkB;AACrB,YAAA,GAAG,WAAW;AACd,YAAA,GAAG,oBAAoB;AACvB,YAAA,GAAG,mBAAmB;AACtB,YAAA,GAAG,kBAAkB;AACrB,YAAA,GAAG,qBAAqB;AACxB,YAAA,GAAG,uBAAuB;AAC1B,YAAA,GAAG,oCAAoC;AACvC,YAAA,GAAG,yBAAyB;AAE5B,YAAA,yCAAyC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;AAExD,YAAA,qCAAqC,EAAE;gBACrC,OAAO;AACP,gBAAA;AACE,oBAAA,UAAU,EAAE,WAAW;AACxB,iBAAA;AACF,aAAA;YACD,IAAI,gBAAgB,KAAK;AACvB,kBAAE;AACE,oBAAA,iDAAiD,EAAE,KAAK;AACxD,oBAAA,2DAA2D,EACzD,KAAK;AACR;kBACD,EAAE,CAAC;SACR,CAAC;AACH,KAAA;AACD,IAAA;QACE,KAAK,EAAE,CAAC,uBAAuB,CAAC;QAChC,KAAK,EAAE,gBAAgB,CAAC;AACtB,YAAA,kDAAkD,EAAE,KAAK;AACzD,YAAA,8BAA8B,EAAE,KAAK;SACtC,CAAC;AACH,KAAA;AACD,IAAA;QACE,KAAK,EAAE,CAAC,qBAAqB,CAAC;QAC9B,KAAK,EAAE,gBAAgB,CAAC;AACtB,YAAA,2CAA2C,EAAE,KAAK;;AAGlD,YAAA,gDAAgD,EAAE,KAAK;AAEvD,YAAA,sBAAsB,EAAE,KAAK;SAC9B,CAAC;AACH,KAAA;AACD,IAAA;AACE,QAAA,KAAK,EAAE,CAAC,CAAA,UAAA,EAAa,gBAAgB,GAAG,CAAC;QACzC,KAAK,EAAE,gBAAgB,CAAC;AACtB,YAAA,4CAA4C,EAAE,KAAK;SACpD,CAAC;AACH,KAAA;AACD,IAAA;AACE,QAAA,KAAK,EAAE;;;;;;;;YASL,qCAAqC;YAErC,uCAAuC;YAEvC,4CAA4C;YAC5C,gDAAgD;YAChD,qCAAqC;AACtC,SAAA;QACD,KAAK,EAAE,gBAAgB,CAAC;AACtB,YAAA,0CAA0C,EAAE,KAAK;AACjD,YAAA,4BAA4B,EAAE,KAAK;AACnC,YAAA,sCAAsC,EAAE,KAAK;AAC7C,YAAA,8BAA8B,EAAE,KAAK;AACrC,YAAA,8BAA8B,EAAE,KAAK;AACrC,YAAA,oBAAoB,EAAE,KAAK;SAC5B,CAAC;AACH,KAAA;;;;;"}
|
|
@@ -19,9 +19,9 @@ const useMemoHooksStyleRule = {
|
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
const parent = node.parent;
|
|
22
|
-
if (parent.type === AST_NODE_TYPES.TSAsExpression ||
|
|
23
|
-
parent.type === AST_NODE_TYPES.TSTypeAssertion
|
|
24
|
-
parent.
|
|
22
|
+
if ((parent.type === AST_NODE_TYPES.TSAsExpression ||
|
|
23
|
+
parent.type === AST_NODE_TYPES.TSTypeAssertion) &&
|
|
24
|
+
!isConstAssertion(parent.typeAnnotation)) {
|
|
25
25
|
context.report({
|
|
26
26
|
node: castDeepMutable(parent),
|
|
27
27
|
messageId: 'disallowUseMemoTypeAnnotation',
|
|
@@ -50,12 +50,13 @@ const useMemoHooksStyleRule = {
|
|
|
50
50
|
};
|
|
51
51
|
const checkNodeForTypeAnnotations = (context, node) => {
|
|
52
52
|
if (node.type === AST_NODE_TYPES.TSAsExpression ||
|
|
53
|
-
node.type === AST_NODE_TYPES.TSTypeAssertion
|
|
54
|
-
node.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
node.type === AST_NODE_TYPES.TSTypeAssertion) {
|
|
54
|
+
if (!isConstAssertion(node.typeAnnotation)) {
|
|
55
|
+
context.report({
|
|
56
|
+
node: castDeepMutable(node),
|
|
57
|
+
messageId: 'disallowUseMemoTypeAnnotation',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
61
62
|
if (hasKey(node, 'body')) {
|
|
@@ -80,6 +81,14 @@ const checkNodeForTypeAnnotations = (context, node) => {
|
|
|
80
81
|
nodeWithArgument.argument);
|
|
81
82
|
}
|
|
82
83
|
};
|
|
84
|
+
const isConstAssertion = (node) => {
|
|
85
|
+
if (node === undefined) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return (node.type === AST_NODE_TYPES.TSTypeReference &&
|
|
89
|
+
node.typeName.type === AST_NODE_TYPES.Identifier &&
|
|
90
|
+
node.typeName.name === 'const');
|
|
91
|
+
};
|
|
83
92
|
|
|
84
93
|
export { useMemoHooksStyleRule };
|
|
85
94
|
//# sourceMappingURL=use-memo-hooks-style.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-memo-hooks-style.mjs","sources":["../../../../src/plugins/react-coding-style/rules/use-memo-hooks-style.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAUO,MAAM,qBAAqB,GAAoC;AACpE,IAAA,IAAI,EAAE;AACJ,QAAA,IAAI,EAAE,YAAY;AAClB,QAAA,IAAI,EAAE;AACJ,YAAA,WAAW,EACT,oEAAoE;AACvE,SAAA;AACD,QAAA,MAAM,EAAE,EAAE;AACV,QAAA,QAAQ,EAAE;AACR,YAAA,6BAA6B,EAC3B,qGAAqG;AACxG,SAAA;AACF,KAAA;AACD,IAAA,MAAM,EAAE,CAAC,OAAO,MAAM;AACpB,QAAA,cAAc,EAAE,CAAC,IAA2C,KAAI;YAC9D,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE;gBAC7C;YACF;AAEA,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;AAE1B,YAAA,IACE,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"use-memo-hooks-style.mjs","sources":["../../../../src/plugins/react-coding-style/rules/use-memo-hooks-style.mts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-config-typed",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript"
|
|
@@ -58,16 +58,17 @@
|
|
|
58
58
|
"lint": "eslint .",
|
|
59
59
|
"lint:fix": "eslint . --fix",
|
|
60
60
|
"md": "markdownlint-cli2",
|
|
61
|
-
"test": "pnpm run z:vitest run",
|
|
62
|
-
"test:cov": "pnpm run z:vitest run --coverage",
|
|
61
|
+
"test": "pnpm run z:vitest:node run",
|
|
62
|
+
"test:cov": "pnpm run z:vitest:node run --coverage",
|
|
63
63
|
"test:cov:ui": "vite preview --outDir ./coverage",
|
|
64
|
-
"test:ui": "pnpm run z:vitest --ui",
|
|
65
|
-
"testw": "pnpm run z:vitest watch",
|
|
64
|
+
"test:ui": "pnpm run z:vitest:node --ui",
|
|
65
|
+
"testw": "pnpm run z:vitest:node watch",
|
|
66
66
|
"tsc": "tsc --noEmit",
|
|
67
67
|
"tscw": "tsc --noEmit --watch -p ./tsconfig.json",
|
|
68
68
|
"type-check": "tsc --noEmit",
|
|
69
69
|
"update-packages": "pnpm update --latest",
|
|
70
|
-
"z:vitest": "vitest --config ./configs/vitest.config.mts"
|
|
70
|
+
"z:vitest": "vitest --config ./configs/vitest.config.mts",
|
|
71
|
+
"z:vitest:node": "vitest --config ./configs/vitest.config.mts --project='Node.js'"
|
|
71
72
|
},
|
|
72
73
|
"dependencies": {
|
|
73
74
|
"@eslint/js": "9.39.1",
|
|
@@ -138,14 +139,14 @@
|
|
|
138
139
|
"jiti": "2.6.1",
|
|
139
140
|
"json-schema": "0.4.0",
|
|
140
141
|
"json-schema-to-typescript": "15.0.4",
|
|
141
|
-
"markdownlint": "0.
|
|
142
|
+
"markdownlint": "0.40.0",
|
|
142
143
|
"markdownlint-cli2": "0.19.1",
|
|
143
144
|
"npm-run-all2": "8.0.4",
|
|
144
145
|
"prettier": "3.7.4",
|
|
145
146
|
"prettier-plugin-jsdoc": "1.7.0",
|
|
146
147
|
"prettier-plugin-organize-imports": "4.3.0",
|
|
147
148
|
"prettier-plugin-packagejson": "2.5.20",
|
|
148
|
-
"react": "19.2.
|
|
149
|
+
"react": "19.2.1",
|
|
149
150
|
"rollup": "4.53.3",
|
|
150
151
|
"semantic-release": "25.0.2",
|
|
151
152
|
"ts-fortress": "6.1.0",
|
|
@@ -166,6 +167,6 @@
|
|
|
166
167
|
"node": ">=18.0.0"
|
|
167
168
|
},
|
|
168
169
|
"volta": {
|
|
169
|
-
"node": "25.
|
|
170
|
+
"node": "25.2.1"
|
|
170
171
|
}
|
|
171
172
|
}
|
|
@@ -84,6 +84,10 @@ export const eslintConfigForTypeScript = ({
|
|
|
84
84
|
files: ['**/*.d.{ts,mts,cts}'],
|
|
85
85
|
rules: defineKnownRules({
|
|
86
86
|
'@typescript-eslint/triple-slash-reference': 'off',
|
|
87
|
+
|
|
88
|
+
// Because interface is often used
|
|
89
|
+
'@typescript-eslint/consistent-type-definitions': 'off',
|
|
90
|
+
|
|
87
91
|
'import-x/unambiguous': 'off',
|
|
88
92
|
}),
|
|
89
93
|
},
|
|
@@ -28,12 +28,14 @@ describe('use-memo-hooks-style', () => {
|
|
|
28
28
|
import { memo, useMemo } from 'react';
|
|
29
29
|
|
|
30
30
|
type Props = Readonly<{
|
|
31
|
-
|
|
31
|
+
value: number;
|
|
32
32
|
}>;
|
|
33
33
|
|
|
34
34
|
const Component = memo<Props>((props) => {
|
|
35
35
|
const memoized = useMemo<number>(() => props.value, [props.value]);
|
|
36
|
+
|
|
36
37
|
const typed: number = useMemo(() => props.value, [props.value]);
|
|
38
|
+
|
|
37
39
|
return <div />;
|
|
38
40
|
});
|
|
39
41
|
`,
|
|
@@ -54,6 +56,40 @@ describe('use-memo-hooks-style', () => {
|
|
|
54
56
|
const value = useMemo(() => 42) as number;
|
|
55
57
|
`,
|
|
56
58
|
},
|
|
59
|
+
{
|
|
60
|
+
name: 'Allow satisfies expression',
|
|
61
|
+
code: dedent`
|
|
62
|
+
import { memo, useMemo } from 'react';
|
|
63
|
+
|
|
64
|
+
type Props = Readonly<{
|
|
65
|
+
value: number;
|
|
66
|
+
}>;
|
|
67
|
+
|
|
68
|
+
const Component = memo<Props>((props) => {
|
|
69
|
+
const value = useMemo(() => props.value, [props.value]) satisfies number;
|
|
70
|
+
|
|
71
|
+
const inner = useMemo(() => props.value satisfies number, [props.value]);
|
|
72
|
+
|
|
73
|
+
return inner + value;
|
|
74
|
+
});
|
|
75
|
+
`,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'Allow const assertion',
|
|
79
|
+
code: dedent`
|
|
80
|
+
import { memo, useMemo } from 'react';
|
|
81
|
+
|
|
82
|
+
type Props = Readonly<{
|
|
83
|
+
value: number;
|
|
84
|
+
}>;
|
|
85
|
+
|
|
86
|
+
const Component = memo<Props>((props) => {
|
|
87
|
+
const value = useMemo(() => ({ v: props.value }) as const, [props.value]);
|
|
88
|
+
|
|
89
|
+
return value;
|
|
90
|
+
});
|
|
91
|
+
`,
|
|
92
|
+
},
|
|
57
93
|
],
|
|
58
94
|
invalid: [
|
|
59
95
|
{
|
|
@@ -62,7 +98,7 @@ describe('use-memo-hooks-style', () => {
|
|
|
62
98
|
import { memo, useMemo } from 'react';
|
|
63
99
|
|
|
64
100
|
type Props = Readonly<{
|
|
65
|
-
|
|
101
|
+
value: number;
|
|
66
102
|
}>;
|
|
67
103
|
|
|
68
104
|
const Component = memo<Props>((props) => {
|
|
@@ -82,7 +118,7 @@ describe('use-memo-hooks-style', () => {
|
|
|
82
118
|
import { memo, useMemo } from 'react';
|
|
83
119
|
|
|
84
120
|
type Props = Readonly<{
|
|
85
|
-
|
|
121
|
+
value: number;
|
|
86
122
|
}>;
|
|
87
123
|
|
|
88
124
|
const Component = memo<Props>((props) => {
|
|
@@ -102,11 +138,11 @@ describe('use-memo-hooks-style', () => {
|
|
|
102
138
|
import { memo, useMemo } from 'react';
|
|
103
139
|
|
|
104
140
|
type Props = Readonly<{
|
|
105
|
-
|
|
141
|
+
value: number;
|
|
106
142
|
}>;
|
|
107
143
|
|
|
108
144
|
const Component = memo<Props>((props) => {
|
|
109
|
-
const value = useMemo(() => props.value as number, [props.value])
|
|
145
|
+
const value = useMemo(() => props.value as number, [props.value]);
|
|
110
146
|
return value;
|
|
111
147
|
});
|
|
112
148
|
`,
|
|
@@ -117,16 +153,16 @@ describe('use-memo-hooks-style', () => {
|
|
|
117
153
|
],
|
|
118
154
|
},
|
|
119
155
|
{
|
|
120
|
-
name: 'Disallow satisfies
|
|
156
|
+
name: 'Disallow return type annotation even with satisfies',
|
|
121
157
|
code: dedent`
|
|
122
158
|
import { memo, useMemo } from 'react';
|
|
123
159
|
|
|
124
160
|
type Props = Readonly<{
|
|
125
|
-
|
|
161
|
+
value: number;
|
|
126
162
|
}>;
|
|
127
163
|
|
|
128
164
|
const Component = memo<Props>((props) => {
|
|
129
|
-
const value = useMemo(() => props.value, [props.value]) satisfies number;
|
|
165
|
+
const value = useMemo((): number => props.value, [props.value]) satisfies number;
|
|
130
166
|
return value;
|
|
131
167
|
});
|
|
132
168
|
`,
|
|
@@ -137,16 +173,16 @@ describe('use-memo-hooks-style', () => {
|
|
|
137
173
|
],
|
|
138
174
|
},
|
|
139
175
|
{
|
|
140
|
-
name: 'Disallow
|
|
176
|
+
name: 'Disallow return type annotation even with const assertion',
|
|
141
177
|
code: dedent`
|
|
142
178
|
import { memo, useMemo } from 'react';
|
|
143
179
|
|
|
144
180
|
type Props = Readonly<{
|
|
145
|
-
|
|
181
|
+
value: number;
|
|
146
182
|
}>;
|
|
147
183
|
|
|
148
184
|
const Component = memo<Props>((props) => {
|
|
149
|
-
const value = useMemo(() => props.value
|
|
185
|
+
const value = useMemo((): number => props.value, [props.value]) as const;
|
|
150
186
|
return value;
|
|
151
187
|
});
|
|
152
188
|
`,
|
|
@@ -28,12 +28,14 @@ describe('use-memo-hooks-style', () => {
|
|
|
28
28
|
import * as React from 'react';
|
|
29
29
|
|
|
30
30
|
type Props = Readonly<{
|
|
31
|
-
|
|
31
|
+
value: number;
|
|
32
32
|
}>;
|
|
33
33
|
|
|
34
34
|
const Component = React.memo<Props>((props) => {
|
|
35
35
|
const memoized = React.useMemo<number>(() => props.value, [props.value]);
|
|
36
|
+
|
|
36
37
|
const typed: number = React.useMemo(() => props.value, [props.value]);
|
|
38
|
+
|
|
37
39
|
return <div />;
|
|
38
40
|
});
|
|
39
41
|
`,
|
|
@@ -54,6 +56,40 @@ describe('use-memo-hooks-style', () => {
|
|
|
54
56
|
const value = useMemo(() => 42) as number;
|
|
55
57
|
`,
|
|
56
58
|
},
|
|
59
|
+
{
|
|
60
|
+
name: 'Allow satisfies expression',
|
|
61
|
+
code: dedent`
|
|
62
|
+
import * as React from 'react';
|
|
63
|
+
|
|
64
|
+
type Props = Readonly<{
|
|
65
|
+
value: number;
|
|
66
|
+
}>;
|
|
67
|
+
|
|
68
|
+
const Component = React.memo<Props>((props) => {
|
|
69
|
+
const value = React.useMemo(() => props.value, [props.value]) satisfies number;
|
|
70
|
+
|
|
71
|
+
const inner = React.useMemo(() => props.value satisfies number, [props.value]);
|
|
72
|
+
|
|
73
|
+
return inner + value;
|
|
74
|
+
});
|
|
75
|
+
`,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'Allow const assertion',
|
|
79
|
+
code: dedent`
|
|
80
|
+
import * as React from 'react';
|
|
81
|
+
|
|
82
|
+
type Props = Readonly<{
|
|
83
|
+
value: number;
|
|
84
|
+
}>;
|
|
85
|
+
|
|
86
|
+
const Component = React.memo<Props>((props) => {
|
|
87
|
+
const value = React.useMemo(() => ({ v: props.value }) as const, [props.value]);
|
|
88
|
+
|
|
89
|
+
return value;
|
|
90
|
+
});
|
|
91
|
+
`,
|
|
92
|
+
},
|
|
57
93
|
],
|
|
58
94
|
invalid: [
|
|
59
95
|
{
|
|
@@ -62,7 +98,7 @@ describe('use-memo-hooks-style', () => {
|
|
|
62
98
|
import * as React from 'react';
|
|
63
99
|
|
|
64
100
|
type Props = Readonly<{
|
|
65
|
-
|
|
101
|
+
value: number;
|
|
66
102
|
}>;
|
|
67
103
|
|
|
68
104
|
const Component = React.memo<Props>((props) => {
|
|
@@ -82,7 +118,7 @@ describe('use-memo-hooks-style', () => {
|
|
|
82
118
|
import * as React from 'react';
|
|
83
119
|
|
|
84
120
|
type Props = Readonly<{
|
|
85
|
-
|
|
121
|
+
value: number;
|
|
86
122
|
}>;
|
|
87
123
|
|
|
88
124
|
const Component = React.memo<Props>((props) => {
|
|
@@ -102,11 +138,11 @@ describe('use-memo-hooks-style', () => {
|
|
|
102
138
|
import * as React from 'react';
|
|
103
139
|
|
|
104
140
|
type Props = Readonly<{
|
|
105
|
-
|
|
141
|
+
value: number;
|
|
106
142
|
}>;
|
|
107
143
|
|
|
108
144
|
const Component = React.memo<Props>((props) => {
|
|
109
|
-
const value = React.useMemo(() => props.value as number, [props.value])
|
|
145
|
+
const value = React.useMemo(() => props.value as number, [props.value]);
|
|
110
146
|
return value;
|
|
111
147
|
});
|
|
112
148
|
`,
|
|
@@ -117,16 +153,16 @@ describe('use-memo-hooks-style', () => {
|
|
|
117
153
|
],
|
|
118
154
|
},
|
|
119
155
|
{
|
|
120
|
-
name: 'Disallow satisfies
|
|
156
|
+
name: 'Disallow return type annotation even with satisfies',
|
|
121
157
|
code: dedent`
|
|
122
158
|
import * as React from 'react';
|
|
123
159
|
|
|
124
160
|
type Props = Readonly<{
|
|
125
|
-
|
|
161
|
+
value: number;
|
|
126
162
|
}>;
|
|
127
163
|
|
|
128
164
|
const Component = React.memo<Props>((props) => {
|
|
129
|
-
const value = React.useMemo(() => props.value, [props.value]) satisfies number;
|
|
165
|
+
const value = React.useMemo((): number => props.value, [props.value]) satisfies number;
|
|
130
166
|
return value;
|
|
131
167
|
});
|
|
132
168
|
`,
|
|
@@ -137,16 +173,16 @@ describe('use-memo-hooks-style', () => {
|
|
|
137
173
|
],
|
|
138
174
|
},
|
|
139
175
|
{
|
|
140
|
-
name: 'Disallow
|
|
176
|
+
name: 'Disallow return type annotation even with const assertion',
|
|
141
177
|
code: dedent`
|
|
142
178
|
import * as React from 'react';
|
|
143
179
|
|
|
144
180
|
type Props = Readonly<{
|
|
145
|
-
|
|
181
|
+
value: number;
|
|
146
182
|
}>;
|
|
147
183
|
|
|
148
184
|
const Component = React.memo<Props>((props) => {
|
|
149
|
-
const value = React.useMemo(() => props.value
|
|
185
|
+
const value = React.useMemo((): number => props.value, [props.value]) as const;
|
|
150
186
|
return value;
|
|
151
187
|
});
|
|
152
188
|
`,
|
|
@@ -30,9 +30,9 @@ export const useMemoHooksStyleRule: TSESLint.RuleModule<MessageIds> = {
|
|
|
30
30
|
const parent = node.parent;
|
|
31
31
|
|
|
32
32
|
if (
|
|
33
|
-
parent.type === AST_NODE_TYPES.TSAsExpression ||
|
|
34
|
-
|
|
35
|
-
parent.
|
|
33
|
+
(parent.type === AST_NODE_TYPES.TSAsExpression ||
|
|
34
|
+
parent.type === AST_NODE_TYPES.TSTypeAssertion) &&
|
|
35
|
+
!isConstAssertion(parent.typeAnnotation)
|
|
36
36
|
) {
|
|
37
37
|
context.report({
|
|
38
38
|
node: castDeepMutable(parent),
|
|
@@ -72,13 +72,14 @@ const checkNodeForTypeAnnotations = (
|
|
|
72
72
|
): void => {
|
|
73
73
|
if (
|
|
74
74
|
node.type === AST_NODE_TYPES.TSAsExpression ||
|
|
75
|
-
node.type === AST_NODE_TYPES.TSTypeAssertion
|
|
76
|
-
node.type === AST_NODE_TYPES.TSSatisfiesExpression
|
|
75
|
+
node.type === AST_NODE_TYPES.TSTypeAssertion
|
|
77
76
|
) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
if (!isConstAssertion(node.typeAnnotation)) {
|
|
78
|
+
context.report({
|
|
79
|
+
node: castDeepMutable(node),
|
|
80
|
+
messageId: 'disallowUseMemoTypeAnnotation',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
82
83
|
|
|
83
84
|
return;
|
|
84
85
|
}
|
|
@@ -116,3 +117,17 @@ const checkNodeForTypeAnnotations = (
|
|
|
116
117
|
);
|
|
117
118
|
}
|
|
118
119
|
};
|
|
120
|
+
|
|
121
|
+
const isConstAssertion = (
|
|
122
|
+
node: DeepReadonly<TSESTree.Node> | undefined,
|
|
123
|
+
): node is TSESTree.TSTypeReference => {
|
|
124
|
+
if (node === undefined) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
node.type === AST_NODE_TYPES.TSTypeReference &&
|
|
130
|
+
node.typeName.type === AST_NODE_TYPES.Identifier &&
|
|
131
|
+
node.typeName.name === 'const'
|
|
132
|
+
);
|
|
133
|
+
};
|