Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper way of typing results #140

Open
jbuiquan opened this issue Feb 6, 2025 · 3 comments
Open

Proper way of typing results #140

jbuiquan opened this issue Feb 6, 2025 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@jbuiquan
Copy link

jbuiquan commented Feb 6, 2025

Hi,

From the documentation and especially the "Inspect Data Values" section, it's not clear for me how to get proper value typings based on column types.
From what I understand columnType and columnValue are coming from different function return (probably from getColumnTypes() and value() for instance).

I don't think there's a trivial way to get the data type inferred like that, so in your example do you suggest to cast the corresponding column value based on its column type ?

Example :

if (columnTypes[0].typeId === DuckDBTypeId.VARCHAR) {
      const value = result.value(0, 1) as DuckDBArrayValue;   //fetching same column, row: 1
     value.items // ok
 }

Is there a better way using your api ?

@jraymakers
Copy link
Contributor

Great question. The API doesn't currently provide a lot of help here. It's a tricky problem, and the best approach probably depends on context.

Because the column types of a result exist only at runtime, it's not possible to infer compile-time types for them. However, perhaps a library such as Zod could be used to declare an expected list of column names & types, validate the result, and return a typed result. Making that work robustly and in general will take some thought & work.

In the meantime, if you know the expected column type, you can use a type assertion (as above) to get values of the expected TypeScript type. The type of a generic value, DuckDBValue is a type union of all valid value types, so the compiler should let you know if you try to make a type assertion that can't ever be true.

Another option is to use one of the provided convenience functions to convert the result data into JSON-serializable objects (i.e. get...Json). This has some cost, but reduces the number of types you have to deal with.

@jbuiquan
Copy link
Author

Thanks for your answer!
Indeed get...Json could be the way to go :)

Maybe the documentation could be modified ? For me, it looked liked the columnValue was properly inferred by typescript in your example but it's not.

if (columnType.typeId === DuckDBTypeId.ARRAY) {
  const arrayItems = columnValue.items; // array of values
  const arrayString = columnValue.toString();
}

@jraymakers
Copy link
Contributor

That's a good point about the documentation. The type inference should work for the columnType examples, but not the columnValue examples the way I've written them. I'll think of how to improve that.

It is possible to get type inference for values by using instanceof on the vector. For example:

const columnVector = chunk.getColumnVector(columnIndex);
if (columnVector instanceof DuckDBIntegerVector) {
  const value = columnVector.getItem(rowIndex);
   // The type of value is inferred correctly here.
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants