Skip to content

Commit

Permalink
feat: allow to pass conditional expression with null (#367)
Browse files Browse the repository at this point in the history
  • Loading branch information
Newbie012 authored Jan 8, 2025
1 parent 7905ebb commit 2017404
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-cameras-poke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@ts-safeql/eslint-plugin": patch
---

allow to pass conditional expression which involves null such as `condition ? col : null`
12 changes: 12 additions & 0 deletions packages/eslint-plugin/src/rules/check-sql.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,18 @@ RuleTester.describe("check-sql", () => {
}
`,
},
{
name: "select statement with conditional expression of ? x : null",
filename,
options: withConnection(connections.base),
code: `
function run(flag: boolean) {
const result = conn.query<{ col: string | null }>(sql\`
select \${flag ? 'value' : null } as col
\`);
}
`,
},
{
name: "select statement with type reference",
filename,
Expand Down
31 changes: 26 additions & 5 deletions packages/eslint-plugin/src/utils/ts-pg.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,19 +232,33 @@ function getPgTypeFromTsType(params: {
const whenTrueType = getPgTypeFromFlags(checker.getTypeAtLocation(node.whenTrue).flags);
const whenFalseType = getPgTypeFromFlags(checker.getTypeAtLocation(node.whenFalse).flags);

if (!whenTrueType || !whenFalseType) {
if (whenTrueType === undefined || whenFalseType === undefined) {
return E.left(
`Unsupported conditional expression flags (true = ${whenTrueType}, false = ${whenFalseType})`,
);
}

if (whenTrueType !== whenFalseType) {
if (whenTrueType === null && whenFalseType === null) {
return E.right(null);
}

const bothNonNullable = whenTrueType !== null && whenFalseType !== null;

if (bothNonNullable && whenTrueType !== whenFalseType) {
return E.left(
`Conditional expression must have the same type (true = ${whenTrueType}, false = ${whenFalseType})`,
);
}

return E.right({ kind: "cast", cast: whenTrueType });
if (whenTrueType !== null) {
return E.right({ kind: "cast", cast: whenTrueType });
}

if (whenFalseType !== null) {
return E.right({ kind: "cast", cast: whenFalseType });
}

return E.right(null);
}

// Check for identifier
Expand Down Expand Up @@ -310,7 +324,11 @@ function getPgTypeFromTsType(params: {
return checkType({ checker, type, options });
}

function getPgTypeFromFlags(flags: ts.TypeFlags) {
function getPgTypeFromFlags(flags: ts.TypeFlags): string | null | undefined {
if (flags === ts.TypeFlags.Null) {
return null;
}

return tsFlagToPgTypeMap[flags];
}

Expand All @@ -337,7 +355,10 @@ function checkType(params: {
elementType?.isUnion() &&
elementType.types.every((t) => t.flags === elementType.types[0].flags)
) {
return E.right({ kind: "cast", cast: `${getPgTypeFromFlags(elementType.types[0].flags)}[]` });
return E.right({
kind: "cast",
cast: `${getPgTypeFromFlags(elementType.types[0].flags)}[]`,
});
}
}

Expand Down

0 comments on commit 2017404

Please sign in to comment.