diff --git a/specification/eslint.config.js b/specification/eslint.config.js index 398377dbad..be1c5a2836 100644 --- a/specification/eslint.config.js +++ b/specification/eslint.config.js @@ -33,6 +33,7 @@ export default defineConfig({ rules: { 'es-spec-validator/single-key-dictionary-key-is-string': 'error', 'es-spec-validator/dictionary-key-is-string': 'error', + 'es-spec-validator/no-native-types': 'error', 'es-spec-validator/invalid-node-types': 'warn' } }) diff --git a/validator/README.md b/validator/README.md index d64b769259..5b57085972 100644 --- a/validator/README.md +++ b/validator/README.md @@ -5,11 +5,12 @@ It is configured [in the specification directory](../specification/eslint.config ## Rules -| Name | Description | -| - | - | +| Name | Description | +|---------------------------------------| - | | `single-key-dictionary-key-is-string` | `SingleKeyDictionary` keys must be strings. | -| `dictionary-key-is-string` | `Dictionary` keys must be strings. | -| `invalid-node-types` | The spec uses a subset of TypeScript, so some types, clauses and expressions are not allowed. | +| `dictionary-key-is-string` | `Dictionary` keys must be strings. | +| `no-native-types` | `Typescript native types not allowed, use aliases. | +| `invalid-node-types` | The spec uses a subset of TypeScript, so some types, clauses and expressions are not allowed. | ## Usage diff --git a/validator/eslint-plugin-es-spec.js b/validator/eslint-plugin-es-spec.js index e74b363579..aba3042515 100644 --- a/validator/eslint-plugin-es-spec.js +++ b/validator/eslint-plugin-es-spec.js @@ -18,12 +18,14 @@ */ import singleKeyDict from './rules/single-key-dictionary-key-is-string.js' import dict from './rules/dictionary-key-is-string.js' +import noNativeTypes from './rules/no-native-types.js' import invalidNodeTypes from './rules/invalid-node-types.js' export default { rules: { 'single-key-dictionary-key-is-string': singleKeyDict, 'dictionary-key-is-string': dict, + 'no-native-types': noNativeTypes, 'invalid-node-types': invalidNodeTypes, } } diff --git a/validator/rules/no-native-types.js b/validator/rules/no-native-types.js new file mode 100644 index 0000000000..b21c2fa96a --- /dev/null +++ b/validator/rules/no-native-types.js @@ -0,0 +1,46 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { ESLintUtils } from '@typescript-eslint/utils'; + +const createRule = ESLintUtils.RuleCreator(name => `https://example.com/rule/${name}`) + +const TYPES_TO_AVOID = ['Record', 'Partial', 'Required', 'Pick', 'Omit']; + +export default createRule({ + name: 'no-native-types', + create(context) { + return { + TSTypeReference(node) { + if (TYPES_TO_AVOID.includes(node.typeName.name)) { + context.report({ node, messageId: 'stringKey' }) + } + }, + } + }, + meta: { + docs: { + description: 'Typescript native types not allowed, use aliases', + }, + messages: { + stringKey: "Typescript native types not allowed, use aliases" + }, + type: 'suggestion', + }, + defaultOptions: [] +}) diff --git a/validator/test/no-native-types.test.js b/validator/test/no-native-types.test.js new file mode 100644 index 0000000000..ef30f764ca --- /dev/null +++ b/validator/test/no-native-types.test.js @@ -0,0 +1,63 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { RuleTester } from '@typescript-eslint/rule-tester' +import rule from '../rules/dictionary-key-is-string.js' + +const ruleTester = new RuleTester({ + languageOptions: { + parserOptions: { + projectService: { + allowDefaultProject: ['*.ts*'], + }, + tsconfigRootDir: import.meta.dirname, + }, + }, +}) + +ruleTester.run('no-native-types', rule, { + valid: [ + `type MyRecord = Record`, + `type MyPart = Partial`, + `type MyReq = Required`, + `type MyPick Pick`, + `type MyOmit = Omit`, + ], + invalid: [ + { + code: `type MyRecord = Record`, + errors: [{ messageId: 'stringKey' }] + }, + { + code: `type MyPart = Partial`, + errors: [{ messageId: 'stringKey' }] + }, + { + code: `type MyReq = Required`, + errors: [{ messageId: 'stringKey' }] + }, + { + code: `type MyPick Pick`, + errors: [{ messageId: 'stringKey' }] + }, + { + code: `type MyOmit = Omit`, + errors: [{ messageId: 'stringKey' }] + } + ], +})