diff --git a/packages/eslint-plugin/docs/rules/consistent-type-assertions.mdx b/packages/eslint-plugin/docs/rules/consistent-type-assertions.mdx index 0b13d9df2677..9445bcf8b19b 100644 --- a/packages/eslint-plugin/docs/rules/consistent-type-assertions.mdx +++ b/packages/eslint-plugin/docs/rules/consistent-type-assertions.mdx @@ -115,6 +115,79 @@ const foo = ; +### `arrayLiteralTypeAssertions` + +{/* insert option description */} + +Always prefer `const x: T[] = [ ... ];` to `const x = [ ... ] as T[];` (or similar with angle brackets). + +The compiler will warn for excess properties of elements with this syntax, but not missing _required_ fields of those objects. +For example: `const x: {foo: number}[] = [{}];` will fail to compile, but `const x = [{}] as [{ foo: number }]` will succeed. + +The const assertion `const x = [1, 2, 3] as const`, introduced in TypeScript 3.4, is considered beneficial and is ignored by this option. + +Assertions to `any` are also ignored by this option. + +Examples of code for `{ assertionStyle: 'as', arrayLiteralTypeAssertions: 'never' }`: + + + + +```ts option='{ "assertionStyle": "as", "arrayLiteralTypeAssertions": "never" }' +const x = ['foo'] as T; + +function bar() { + return ['foo'] as T; +} +``` + + + + +```ts option='{ "assertionStyle": "as", "arrayLiteralTypeAssertions": "never" }' +const x: T = ['foo']; +const y = ['foo'] as any; +const z = ['foo'] as unknown; + +function bar(): T { + return ['foo']; +} +``` + + + + +Examples of code for `{ assertionStyle: 'as', arrayLiteralTypeAssertions: 'allow-as-parameter' }`: + + + + +```ts option='{ "assertionStyle": "as", "arrayLiteralTypeAssertions": "allow-as-parameter" }' +const x = ['foo'] as T; + +function bar() { + return ['foo'] as T; +} +``` + + + + +```tsx option='{ "assertionStyle": "as", "arrayLiteralTypeAssertions": "allow-as-parameter" }' +const x: T = ['foo']; +const y = ['foo'] as any; +const z = ['foo'] as unknown; +bar(['foo'] as T); +new Clazz(['foo'] as T); +function bar() { + throw ['foo'] as Foo; +} +const foo = ; +``` + + + + ## When Not To Use It If you do not want to enforce consistent type assertions. diff --git a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts index 8713405115d9..3f460f7d11da 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-assertions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-assertions.ts @@ -18,19 +18,27 @@ export type MessageIds = | 'angle-bracket' | 'as' | 'never' + | 'replaceArrayTypeAssertionWithAnnotation' + | 'replaceArrayTypeAssertionWithSatisfies' | 'replaceObjectTypeAssertionWithAnnotation' | 'replaceObjectTypeAssertionWithSatisfies' + | 'unexpectedArrayTypeAssertion' | 'unexpectedObjectTypeAssertion'; type OptUnion = | { assertionStyle: 'angle-bracket' | 'as'; objectLiteralTypeAssertions?: 'allow' | 'allow-as-parameter' | 'never'; + arrayLiteralTypeAssertions?: 'allow' | 'allow-as-parameter' | 'never'; } | { assertionStyle: 'never'; }; export type Options = readonly [OptUnion]; +type AsExpressionOrTypeAssertion = + | TSESTree.TSAsExpression + | TSESTree.TSTypeAssertion; + export default createRule({ name: 'consistent-type-assertions', meta: { @@ -45,10 +53,15 @@ export default createRule({ 'angle-bracket': "Use '<{{cast}}>' instead of 'as {{cast}}'.", as: "Use 'as {{cast}}' instead of '<{{cast}}>'.", never: 'Do not use any type assertions.', + replaceArrayTypeAssertionWithAnnotation: + 'Use const x: {{cast}} = [ ... ] instead.', + replaceArrayTypeAssertionWithSatisfies: + 'Use const x = [ ... ] satisfies {{cast}} instead.', replaceObjectTypeAssertionWithAnnotation: 'Use const x: {{cast}} = { ... } instead.', replaceObjectTypeAssertionWithSatisfies: 'Use const x = { ... } satisfies {{cast}} instead.', + unexpectedArrayTypeAssertion: 'Always prefer const x: T[] = [ ... ].', unexpectedObjectTypeAssertion: 'Always prefer const x: T = { ... }.', }, schema: [ @@ -70,6 +83,12 @@ export default createRule({ type: 'object', additionalProperties: false, properties: { + arrayLiteralTypeAssertions: { + type: 'string', + description: + 'Whether to always prefer type declarations for array literals used as variable initializers, rather than type assertions.', + enum: ['allow', 'allow-as-parameter', 'never'], + }, assertionStyle: { type: 'string', description: 'The expected assertion style to enforce.', @@ -89,6 +108,7 @@ export default createRule({ }, defaultOptions: [ { + arrayLiteralTypeAssertions: 'allow', assertionStyle: 'as', objectLiteralTypeAssertions: 'allow', }, @@ -106,7 +126,7 @@ export default createRule({ } function reportIncorrectAssertionType( - node: TSESTree.TSAsExpression | TSESTree.TSTypeAssertion, + node: AsExpressionOrTypeAssertion, ): void { const messageId = options.assertionStyle; @@ -192,8 +212,63 @@ export default createRule({ } } - function checkExpression( - node: TSESTree.TSAsExpression | TSESTree.TSTypeAssertion, + function getSuggestions( + node: AsExpressionOrTypeAssertion, + annotationMessageId: MessageIds, + satisfiesMessageId: MessageIds, + ): TSESLint.ReportSuggestionArray { + const suggestions: TSESLint.ReportSuggestionArray = []; + if ( + node.parent.type === AST_NODE_TYPES.VariableDeclarator && + !node.parent.id.typeAnnotation + ) { + const { parent } = node; + suggestions.push({ + messageId: annotationMessageId, + data: { cast: context.sourceCode.getText(node.typeAnnotation) }, + fix: fixer => [ + fixer.insertTextAfter( + parent.id, + `: ${context.sourceCode.getText(node.typeAnnotation)}`, + ), + fixer.replaceText( + node, + getTextWithParentheses(context.sourceCode, node.expression), + ), + ], + }); + } + suggestions.push({ + messageId: satisfiesMessageId, + data: { cast: context.sourceCode.getText(node.typeAnnotation) }, + fix: fixer => [ + fixer.replaceText( + node, + getTextWithParentheses(context.sourceCode, node.expression), + ), + fixer.insertTextAfter( + node, + ` satisfies ${context.sourceCode.getText(node.typeAnnotation)}`, + ), + ], + }); + return suggestions; + } + + function isAsParameter(node: AsExpressionOrTypeAssertion): boolean { + return ( + node.parent.type === AST_NODE_TYPES.NewExpression || + node.parent.type === AST_NODE_TYPES.CallExpression || + node.parent.type === AST_NODE_TYPES.ThrowStatement || + node.parent.type === AST_NODE_TYPES.AssignmentPattern || + node.parent.type === AST_NODE_TYPES.JSXExpressionContainer || + (node.parent.type === AST_NODE_TYPES.TemplateLiteral && + node.parent.parent.type === AST_NODE_TYPES.TaggedTemplateExpression) + ); + } + + function checkExpressionForObjectAssertion( + node: AsExpressionOrTypeAssertion, ): void { if ( options.assertionStyle === 'never' || @@ -205,54 +280,17 @@ export default createRule({ if ( options.objectLiteralTypeAssertions === 'allow-as-parameter' && - (node.parent.type === AST_NODE_TYPES.NewExpression || - node.parent.type === AST_NODE_TYPES.CallExpression || - node.parent.type === AST_NODE_TYPES.ThrowStatement || - node.parent.type === AST_NODE_TYPES.AssignmentPattern || - node.parent.type === AST_NODE_TYPES.JSXExpressionContainer || - (node.parent.type === AST_NODE_TYPES.TemplateLiteral && - node.parent.parent.type === - AST_NODE_TYPES.TaggedTemplateExpression)) + isAsParameter(node) ) { return; } if (checkType(node.typeAnnotation)) { - const suggest: TSESLint.ReportSuggestionArray = []; - if ( - node.parent.type === AST_NODE_TYPES.VariableDeclarator && - !node.parent.id.typeAnnotation - ) { - const { parent } = node; - suggest.push({ - messageId: 'replaceObjectTypeAssertionWithAnnotation', - data: { cast: context.sourceCode.getText(node.typeAnnotation) }, - fix: fixer => [ - fixer.insertTextAfter( - parent.id, - `: ${context.sourceCode.getText(node.typeAnnotation)}`, - ), - fixer.replaceText( - node, - getTextWithParentheses(context.sourceCode, node.expression), - ), - ], - }); - } - suggest.push({ - messageId: 'replaceObjectTypeAssertionWithSatisfies', - data: { cast: context.sourceCode.getText(node.typeAnnotation) }, - fix: fixer => [ - fixer.replaceText( - node, - getTextWithParentheses(context.sourceCode, node.expression), - ), - fixer.insertTextAfter( - node, - ` satisfies ${context.sourceCode.getText(node.typeAnnotation)}`, - ), - ], - }); + const suggest = getSuggestions( + node, + 'replaceObjectTypeAssertionWithAnnotation', + 'replaceObjectTypeAssertionWithSatisfies', + ); context.report({ node, @@ -262,6 +300,39 @@ export default createRule({ } } + function checkExpressionForArrayAssertion( + node: AsExpressionOrTypeAssertion, + ): void { + if ( + options.assertionStyle === 'never' || + options.arrayLiteralTypeAssertions === 'allow' || + node.expression.type !== AST_NODE_TYPES.ArrayExpression + ) { + return; + } + + if ( + options.arrayLiteralTypeAssertions === 'allow-as-parameter' && + isAsParameter(node) + ) { + return; + } + + if (checkType(node.typeAnnotation)) { + const suggest = getSuggestions( + node, + 'replaceArrayTypeAssertionWithAnnotation', + 'replaceArrayTypeAssertionWithSatisfies', + ); + + context.report({ + node, + messageId: 'unexpectedArrayTypeAssertion', + suggest, + }); + } + } + return { TSAsExpression(node): void { if (options.assertionStyle !== 'as') { @@ -269,7 +340,8 @@ export default createRule({ return; } - checkExpression(node); + checkExpressionForObjectAssertion(node); + checkExpressionForArrayAssertion(node); }, TSTypeAssertion(node): void { if (options.assertionStyle !== 'angle-bracket') { @@ -277,7 +349,8 @@ export default createRule({ return; } - checkExpression(node); + checkExpressionForObjectAssertion(node); + checkExpressionForArrayAssertion(node); }, }; }, diff --git a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/consistent-type-assertions.shot b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/consistent-type-assertions.shot index 755dc6eb472d..7289fa881592 100644 --- a/packages/eslint-plugin/tests/docs-eslint-output-snapshots/consistent-type-assertions.shot +++ b/packages/eslint-plugin/tests/docs-eslint-output-snapshots/consistent-type-assertions.shot @@ -57,3 +57,61 @@ function bar() { const foo = ; " `; + +exports[`Validating rule docs consistent-type-assertions.mdx code examples ESLint output 5`] = ` +"Incorrect +Options: { "assertionStyle": "as", "arrayLiteralTypeAssertions": "never" } + +const x = ['foo'] as T; + ~~~~~~~~~~~~ Always prefer const x: T[] = [ ... ]. + +function bar() { + return ['foo'] as T; + ~~~~~~~~~~~~ Always prefer const x: T[] = [ ... ]. +} +" +`; + +exports[`Validating rule docs consistent-type-assertions.mdx code examples ESLint output 6`] = ` +"Correct +Options: { "assertionStyle": "as", "arrayLiteralTypeAssertions": "never" } + +const x: T = ['foo']; +const y = ['foo'] as any; +const z = ['foo'] as unknown; + +function bar(): T { + return ['foo']; +} +" +`; + +exports[`Validating rule docs consistent-type-assertions.mdx code examples ESLint output 7`] = ` +"Incorrect +Options: { "assertionStyle": "as", "arrayLiteralTypeAssertions": "allow-as-parameter" } + +const x = ['foo'] as T; + ~~~~~~~~~~~~ Always prefer const x: T[] = [ ... ]. + +function bar() { + return ['foo'] as T; + ~~~~~~~~~~~~ Always prefer const x: T[] = [ ... ]. +} +" +`; + +exports[`Validating rule docs consistent-type-assertions.mdx code examples ESLint output 8`] = ` +"Correct +Options: { "assertionStyle": "as", "arrayLiteralTypeAssertions": "allow-as-parameter" } + +const x: T = ['foo']; +const y = ['foo'] as any; +const z = ['foo'] as unknown; +bar(['foo'] as T); +new Clazz(['foo'] as T); +function bar() { + throw ['foo'] as Foo; +} +const foo = ; +" +`; diff --git a/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts index efd24bd7c4ba..b2a1c47fff3f 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-assertions.test.ts @@ -136,6 +136,182 @@ ruleTester.run('consistent-type-assertions', rule, { }, ], }), + { + code: 'const x = [] as string[];', + options: [ + { + assertionStyle: 'as', + }, + ], + }, + { + code: "const x = ['a'] as Array;", + options: [ + { + assertionStyle: 'as', + }, + ], + }, + { + code: 'const x = [];', + options: [ + { + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'const x = >[];', + options: [ + { + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'print([5] as Foo);', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: ` +function foo() { + throw [5] as Foo; +} + `, + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: 'function b(x = [5] as Foo.Bar) {}', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: 'print?.([5] as Foo);', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: 'print?.call([5] as Foo);', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: 'print`${[5] as Foo}`;', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: 'new Print([5] as Foo);', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: 'const bar = ;', + languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } }, + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: 'print([5]);', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: ` +function foo() { + throw [5]; +} + `, + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'function b(x = [5]) {}', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'print?.([5]);', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'print?.call([5]);', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'print`${[5]}`;', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'new Print([5]);', + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'angle-bracket', + }, + ], + }, { code: 'const x = [1];', options: [{ assertionStyle: 'never' }] }, { code: 'const x = [1] as const;', options: [{ assertionStyle: 'never' }] }, { @@ -671,5 +847,362 @@ const bs = (x <<= y) as any; ], output: 'const ternary = (true ? x : y) as any;', }, + { + code: 'const x = [] as string[];', + errors: [ + { + messageId: 'never', + }, + ], + options: [ + { + assertionStyle: 'never', + }, + ], + }, + { + code: 'const x = [];', + errors: [ + { + messageId: 'never', + }, + ], + options: [ + { + assertionStyle: 'never', + }, + ], + }, + { + code: 'const x = [] as string[];', + errors: [ + { + messageId: 'angle-bracket', + }, + ], + options: [ + { + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'const x = [];', + errors: [ + { + messageId: 'as', + }, + ], + options: [ + { + assertionStyle: 'as', + }, + ], + output: 'const x = [] as string[];', + }, + { + code: 'const x = [] as string[];', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'string[]' }, + messageId: 'replaceArrayTypeAssertionWithAnnotation', + output: 'const x: string[] = [];', + }, + { + data: { cast: 'string[]' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: 'const x = [] satisfies string[];', + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'as', + }, + ], + }, + { + code: 'const x = [];', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'string[]' }, + messageId: 'replaceArrayTypeAssertionWithAnnotation', + output: 'const x: string[] = [];', + }, + { + data: { cast: 'string[]' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: 'const x = [] satisfies string[];', + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'print([5] as Foo);', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: `print([5] satisfies Foo);`, + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'as', + }, + ], + }, + { + code: 'new print([5] as Foo);', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: `new print([5] satisfies Foo);`, + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'as', + }, + ], + }, + { + code: 'function b(x = [5] as Foo.Bar) {}', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo.Bar' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: `function b(x = [5] satisfies Foo.Bar) {}`, + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'as', + }, + ], + }, + { + code: ` +function foo() { + throw [5] as Foo; +} + `, + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: ` +function foo() { + throw [5] satisfies Foo; +} + `, + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'as', + }, + ], + }, + { + code: 'print`${[5] as Foo}`;', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: 'print`${[5] satisfies Foo}`;', + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'as', + }, + ], + }, + { + code: 'const foo = () => [5] as Foo;', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: 'const foo = () => [5] satisfies Foo;', + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'as', + }, + ], + }, + { + code: 'new print([5]);', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: `new print([5] satisfies Foo);`, + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'function b(x = [5]) {}', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo.Bar' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: `function b(x = [5] satisfies Foo.Bar) {}`, + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: ` +function foo() { + throw [5]; +} + `, + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: ` +function foo() { + throw [5] satisfies Foo; +} + `, + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'print`${[5]}`;', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: 'print`${[5] satisfies Foo}`;', + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'never', + assertionStyle: 'angle-bracket', + }, + ], + }, + { + code: 'const foo = [5];', + errors: [ + { + messageId: 'unexpectedArrayTypeAssertion', + suggestions: [ + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithAnnotation', + output: 'const foo: Foo = [5];', + }, + { + data: { cast: 'Foo' }, + messageId: 'replaceArrayTypeAssertionWithSatisfies', + output: 'const foo = [5] satisfies Foo;', + }, + ], + }, + ], + options: [ + { + arrayLiteralTypeAssertions: 'allow-as-parameter', + assertionStyle: 'angle-bracket', + }, + ], + }, ], }); diff --git a/packages/eslint-plugin/tests/schema-snapshots/consistent-type-assertions.shot b/packages/eslint-plugin/tests/schema-snapshots/consistent-type-assertions.shot index 7845d5b791bb..a999506e695e 100644 --- a/packages/eslint-plugin/tests/schema-snapshots/consistent-type-assertions.shot +++ b/packages/eslint-plugin/tests/schema-snapshots/consistent-type-assertions.shot @@ -22,6 +22,11 @@ exports[`Rule schemas should be convertible to TS types for documentation purpos { "additionalProperties": false, "properties": { + "arrayLiteralTypeAssertions": { + "description": "Whether to always prefer type declarations for array literals used as variable initializers, rather than type assertions.", + "enum": ["allow", "allow-as-parameter", "never"], + "type": "string" + }, "assertionStyle": { "description": "The expected assertion style to enforce.", "enum": ["angle-bracket", "as"], @@ -49,6 +54,12 @@ type Options = [ 'never'; } | { + /** Whether to always prefer type declarations for array literals used as variable initializers, rather than type assertions. */ + arrayLiteralTypeAssertions?: + | 'allow-as-parameter' + | 'never' + /** Whether to always prefer type declarations for array literals used as variable initializers, rather than type assertions. */ + | 'allow'; /** The expected assertion style to enforce. */ assertionStyle?: | 'as'