Skip to content

Commit d2b55fa

Browse files
committed
feat: AST type based suggestion
1 parent a44b014 commit d2b55fa

1 file changed

Lines changed: 24 additions & 2 deletions

File tree

src/util/values.util.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,32 @@ import { LiteralValue } from "@code0-tech/sagittarius-graphql-types";
2121
* // { value: "42" }
2222
* // ]
2323
*/
24-
export const getValues = (type: ts.Type): LiteralValue[] => {
24+
const getLiteralsFromTypeNode = (node: ts.TypeNode): LiteralValue[] => {
25+
if (ts.isUnionTypeNode(node)) return node.types.flatMap(getLiteralsFromTypeNode)
26+
if (ts.isLiteralTypeNode(node)) {
27+
const lit = node.literal
28+
if (ts.isStringLiteral(lit)) return [{value: lit.text, __typename: "LiteralValue"}]
29+
if (ts.isNumericLiteral(lit)) return [{value: Number(lit.text)}]
30+
if (lit.kind === ts.SyntaxKind.TrueKeyword) return [{value: true, __typename: "LiteralValue"}]
31+
if (lit.kind === ts.SyntaxKind.FalseKeyword) return [{value: false, __typename: "LiteralValue"}]
32+
}
33+
return []
34+
}
35+
36+
export const getValues = (type: ts.Type, checker?: ts.TypeChecker): LiteralValue[] => {
37+
// When a type comes from an alias (e.g. HTTP_AUTH_TYPE), TypeScript simplifies
38+
// 'Bearer' | string → string, losing the literals. Read them directly from the
39+
// alias declaration's AST instead, which preserves the original union members.
40+
if (checker && type.aliasSymbol) {
41+
const decl = type.aliasSymbol.declarations?.[0]
42+
if (decl && ts.isTypeAliasDeclaration(decl)) {
43+
return getLiteralsFromTypeNode(decl.type)
44+
}
45+
}
46+
2547
// Handle union types by recursively extracting values from each constituent type
2648
if (type.isUnion()) {
27-
return type.types.flatMap(getValues);
49+
return type.types.flatMap(t => getValues(t, checker));
2850
}
2951

3052
// Extract string literal values

0 commit comments

Comments
 (0)