Skip to content

Commit 26fdeef

Browse files
authored
No native utility types validation lint (#4567)
* hardcoded rule * a bit less hardcoded (still) * test
1 parent 9405b85 commit 26fdeef

File tree

5 files changed

+117
-4
lines changed

5 files changed

+117
-4
lines changed

specification/eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export default defineConfig({
3333
rules: {
3434
'es-spec-validator/single-key-dictionary-key-is-string': 'error',
3535
'es-spec-validator/dictionary-key-is-string': 'error',
36+
'es-spec-validator/no-native-types': 'error',
3637
'es-spec-validator/invalid-node-types': 'warn'
3738
}
3839
})

validator/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ It is configured [in the specification directory](../specification/eslint.config
55

66
## Rules
77

8-
| Name | Description |
9-
| - | - |
8+
| Name | Description |
9+
|---------------------------------------| - |
1010
| `single-key-dictionary-key-is-string` | `SingleKeyDictionary` keys must be strings. |
11-
| `dictionary-key-is-string` | `Dictionary` keys must be strings. |
12-
| `invalid-node-types` | The spec uses a subset of TypeScript, so some types, clauses and expressions are not allowed. |
11+
| `dictionary-key-is-string` | `Dictionary` keys must be strings. |
12+
| `no-native-types` | `Typescript native types not allowed, use aliases. |
13+
| `invalid-node-types` | The spec uses a subset of TypeScript, so some types, clauses and expressions are not allowed. |
1314

1415
## Usage
1516

validator/eslint-plugin-es-spec.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
*/
1919
import singleKeyDict from './rules/single-key-dictionary-key-is-string.js'
2020
import dict from './rules/dictionary-key-is-string.js'
21+
import noNativeTypes from './rules/no-native-types.js'
2122
import invalidNodeTypes from './rules/invalid-node-types.js'
2223

2324
export default {
2425
rules: {
2526
'single-key-dictionary-key-is-string': singleKeyDict,
2627
'dictionary-key-is-string': dict,
28+
'no-native-types': noNativeTypes,
2729
'invalid-node-types': invalidNodeTypes,
2830
}
2931
}

validator/rules/no-native-types.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import { ESLintUtils } from '@typescript-eslint/utils';
20+
21+
const createRule = ESLintUtils.RuleCreator(name => `https://example.com/rule/${name}`)
22+
23+
const TYPES_TO_AVOID = ['Record', 'Partial', 'Required', 'Pick', 'Omit'];
24+
25+
export default createRule({
26+
name: 'no-native-types',
27+
create(context) {
28+
return {
29+
TSTypeReference(node) {
30+
if (TYPES_TO_AVOID.includes(node.typeName.name)) {
31+
context.report({ node, messageId: 'stringKey' })
32+
}
33+
},
34+
}
35+
},
36+
meta: {
37+
docs: {
38+
description: 'Typescript native types not allowed, use aliases',
39+
},
40+
messages: {
41+
stringKey: "Typescript native types not allowed, use aliases"
42+
},
43+
type: 'suggestion',
44+
},
45+
defaultOptions: []
46+
})
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import { RuleTester } from '@typescript-eslint/rule-tester'
20+
import rule from '../rules/dictionary-key-is-string.js'
21+
22+
const ruleTester = new RuleTester({
23+
languageOptions: {
24+
parserOptions: {
25+
projectService: {
26+
allowDefaultProject: ['*.ts*'],
27+
},
28+
tsconfigRootDir: import.meta.dirname,
29+
},
30+
},
31+
})
32+
33+
ruleTester.run('no-native-types', rule, {
34+
valid: [
35+
`type MyRecord = Record<string, object>`,
36+
`type MyPart = Partial<Record>`,
37+
`type MyReq = Required<string>`,
38+
`type MyPick Pick<integer,"something">`,
39+
`type MyOmit = Omit<Record, "something">`,
40+
],
41+
invalid: [
42+
{
43+
code: `type MyRecord = Record<string, object>`,
44+
errors: [{ messageId: 'stringKey' }]
45+
},
46+
{
47+
code: `type MyPart = Partial<Record>`,
48+
errors: [{ messageId: 'stringKey' }]
49+
},
50+
{
51+
code: `type MyReq = Required<string>`,
52+
errors: [{ messageId: 'stringKey' }]
53+
},
54+
{
55+
code: `type MyPick Pick<integer,"something">`,
56+
errors: [{ messageId: 'stringKey' }]
57+
},
58+
{
59+
code: `type MyOmit = Omit<Record, "something">`,
60+
errors: [{ messageId: 'stringKey' }]
61+
}
62+
],
63+
})

0 commit comments

Comments
 (0)