From 344d921fea0b86a0a00e60bfbbb242d2dadeff6a Mon Sep 17 00:00:00 2001 From: luo2430 Date: Tue, 14 Jul 2026 17:58:11 +0800 Subject: [PATCH] feat(keep-sorted): support `as const` expressions Extend keep-sorted to handle TSAsExpression nodes, enabling sorting of objects and arrays annotated with `as const` (e.g. `const x = { ... } as const`). Also add test coverage for: - `export const` with `as const` - `const` with `as const` (no export) - `export const` with `satisfies` --- src/commands/keep-sorted.test.ts | 66 ++++++++++++++++++++++++++++++++ src/commands/keep-sorted.ts | 7 ++-- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/commands/keep-sorted.test.ts b/src/commands/keep-sorted.test.ts index ba1c870..0a5f251 100644 --- a/src/commands/keep-sorted.test.ts +++ b/src/commands/keep-sorted.test.ts @@ -427,4 +427,70 @@ run( `, errors: ['command-fix'], }, + { + description: 'export const with as const', + code: $` + /// keep-sorted + export const statusMap = { + timeout: 'timeout', + rejected: 'rejected', + fulfilled: 'fulfilled', + pending: 'pending', + } as const; + `, + output: $` + /// keep-sorted + export const statusMap = { + fulfilled: 'fulfilled', + pending: 'pending', + rejected: 'rejected', + timeout: 'timeout', + } as const; + `, + errors: ['command-fix'], + }, + { + description: 'const with as const (no export)', + code: $` + /// keep-sorted + const statusMap = { + timeout: 'timeout', + rejected: 'rejected', + fulfilled: 'fulfilled', + pending: 'pending', + } as const; + `, + output: $` + /// keep-sorted + const statusMap = { + fulfilled: 'fulfilled', + pending: 'pending', + rejected: 'rejected', + timeout: 'timeout', + } as const; + `, + errors: ['command-fix'], + }, + { + description: 'export const with satisfies', + code: $` + /// keep-sorted + export const statusMap = { + timeout: 'timeout', + rejected: 'rejected', + fulfilled: 'fulfilled', + pending: 'pending', + } satisfies Record; + `, + output: $` + /// keep-sorted + export const statusMap = { + fulfilled: 'fulfilled', + pending: 'pending', + rejected: 'rejected', + timeout: 'timeout', + } satisfies Record; + `, + errors: ['command-fix'], + }, ) diff --git a/src/commands/keep-sorted.ts b/src/commands/keep-sorted.ts index 77dc77d..85fad82 100644 --- a/src/commands/keep-sorted.ts +++ b/src/commands/keep-sorted.ts @@ -29,6 +29,7 @@ export const keepSorted: Command = { 'TSInterfaceBody', 'TSTypeLiteral', 'TSSatisfiesExpression', + 'TSAsExpression', ) || ctx.findNodeBelow( 'ExportNamedDeclaration', 'TSInterfaceDeclaration', @@ -49,13 +50,13 @@ export const keepSorted: Command = { } else { node = Array.isArray(dec.init) ? dec.init[0] : dec.init - if (node && node.type !== 'ObjectExpression' && node.type !== 'ArrayExpression' && node.type !== 'TSSatisfiesExpression') + if (node && node.type !== 'ObjectExpression' && node.type !== 'ArrayExpression' && node.type !== 'TSSatisfiesExpression' && node.type !== 'TSAsExpression') node = undefined } } - // Unwrap TSSatisfiesExpression - if (node?.type === 'TSSatisfiesExpression') { + // Unwrap TSSatisfiesExpression / TSAsExpression (e.g. `satisfies`, `as const`) + if (node?.type === 'TSSatisfiesExpression' || node?.type === 'TSAsExpression') { if (node.expression.type !== 'ArrayExpression' && node.expression.type !== 'ObjectExpression') { node = undefined }