What happened?
Runtime ACT stores an explicit NULL (see value):
{"type":"null","value":"null"}
But the public type declaration says it must be real null (types.d.ts:358):
type LiteralNull = { type: "null"; value: null };
This mismatch creates a TypeScript break:
This comparison appears to be unintentional because the types '"not null" | null | undefined' and '"null"' have no overlap.ts(2367)
Here's minimal repro:
import Parser from "node-sql-parser";
const sql = 'CREATE TABLE t (c INT NULL);';
const ast = new Parser.Parser().astify(sql) as any;
console.log(JSON.stringify(ast[0].create_definitions[0].nullable));
// => { type: 'null', value: 'null' }
Where it stems
In every dialect grammar (pegks/**/*):
// pegjs/mysql.pegjs:876 is used
column_definition_opt
= n:(literal_not_null / literal_null) {
if (n && !n.value) n.value = 'null' // <- sentinel string
return { nullable: n }
Proposals
The short term fix would be:
- type LiteralNull = { type: "null"; value: null };
+ type LiteralNull = { type: "null"; value: null | "null" };
The long term fix is to teach the printer to emit NULL keeping the real null instead of 'null' (that we currently have).
"node-sql-parser": "^5.3.10"
"typescript": "^5.8.3"
node v24.1.0
What happened?
Runtime ACT stores an explicit
NULL(seevalue):{"type":"null","value":"null"}But the public type declaration says it must be real
null(types.d.ts:358):This mismatch creates a TypeScript break:
Here's minimal repro:
Where it stems
In every dialect grammar (
pegks/**/*):Proposals
The short term fix would be:
The long term fix is to teach the printer to emit NULL keeping the real null instead of 'null' (that we currently have).
"node-sql-parser": "^5.3.10"
"typescript": "^5.8.3"
node v24.1.0