Apache Cassandra Node.js Driver TypeScript Migration

20 views
Skip to first unread message

Jane He

unread,
Apr 1, 2025, 1:48:00 PMApr 1
to DataStax Node.js Driver for Apache Cassandra Mailing List
Hi all,

I’m Jane, an Apache Cassandra Node.js Driver maintainer, and I’m excited to announce that we are migrating the project to TypeScript!

This migration will bring several improvements to both the user experience and the developer experience. The main efforts include:
  1. Converting all .js source and test files to .ts extensions
  2. Updating CommonJS import/export syntax to ESM syntax
  3. Refactoring ES5-style classes to ES6-style classes
  4. Consolidating inconsistencies between the JavaScript source, JSDoc comments, and type declaration files
  5. Adopting modern tooling:
    • typescript-eslint for static analysis
    • madge for detecting circular dependencies
    • rollup for bundling
    • api-extractor for tracking public API changes
What this means for users:
  1. No compatibility breaks or major API changes (if all goes as planned). The TypeScript code will be transpiled to JavaScript, and we’ll continue to support applications using ES2015 syntax.
  2. Elimination of type inconsistencies between JavaScript, JSDoc and .d.ts files.
  3. Easier extension and interface implementation, especially for classes previously written in ES5 style.
What this means for driver developers:
  1. Reduced maintenance overhead: Maintaining JSDoc, JavaScript code, and separate .d.ts files has been error-prone and time-consuming. Migrating to TypeScript consolidates everything in one place.
  2. Improved developer productivity: TypeScript enables early error detection and unlocks full IDE support (e.g., IntelliSense).
  3. Better code quality and maintainability: With features like type checking, interfaces, and stricter linting, TypeScript helps enforce best practices and catch bugs earlier.
We’re looking forward to sharing more updates soon — stay tuned for the next release!

Best,
Jane He
Apache Cassandra Node.js Driver Maintainer

Gadisa Teklu

unread,
Aug 4, 2025, 9:49:27 AMAug 4
to DataStax Node.js Driver for Apache Cassandra Mailing List, Jane He
Hello there, I loved the typescript support and it's really life saving. 

As I was implementing an Object Mapper, I wanted to attach custom query. Turns out the only mapWithQuery accepts the Type of the ModelMapper itself. What if you can make it accept a custom type or default back to the T passed to the ModelMapper. The only work around I got is to do 'an unknown as MyType' on the newly attached function. 

Here is my code

import cassandra from 'cassandra-driver';
import { cassandraClient } from '@libs/cassandra-client';

/** Create a mapper for the company balance model. */
const mapper = new cassandra.mapping.Mapper(cassandraClient, {
models: {
CompanyBalance: {
tables: ['company_balance'],
mappings: new cassandra.mapping.UnderscoreCqlToCamelCaseMappings(),
columns: {
company_id: {
name: 'companyId',
toModel: (val) => val.toString(),
},
balance: {
name: 'balance',
toModel: (val) => Number(val),
},
},
},
},
});

type CompanyBalance = {
companyId: string;
balance: number;
};

interface CompanyBalanceMapper
extends cassandra.mapping.ModelMapper<CompanyBalance> {
/**
* Updates the balance of a company.
*
* @param {{ companyId: string; balance: number }} params An object with the
* company ID and the new balance.
*/
updateBalance: (params: {
/**
* The amount to add (+ve) or amount to deduct (-ve) from the current
* balance
*/
balance: number;
/** The ID of the company to update the balance for */
companyId: string;
}) => Promise<cassandra.mapping.Result<null>>;
}

/** Manage Company Balance */
const CompanyBalance = mapper.forModel(
'CompanyBalance',
) as CompanyBalanceMapper;

/**
* Attach update balance to the object. This is composed of the query and
* parameters you want to pass into the query. Make sure the parameters' length
* and the question marks count in your query match.
*/
CompanyBalance.updateBalance = CompanyBalance.mapWithQuery(
'UPDATE company_balance SET balance = balance + ? WHERE company_id = ?;',
(props: { balance: number; companyId: string }) => Object.values(props),
) as unknown as CompanyBalanceMapper['updateBalance'];

export default CompanyBalance;


Thanks.
Reply all
Reply to author
Forward
0 new messages