Type bug with insert
paymog opened this issue · 6 comments
Describe the bug
I would expect the following code to have type issues
import { createClient } from "@clickhouse/client";
const clickhouseClient = createClient({
host: CLICKHOUSE_URL,
username: CLICKHOUSE_USER,
password: CLICKHOUSE_PASSWORD,
application: "my-application",
database: CLICKHOUSE_DATABASE,
});
await clickhouseClient.insert<{ a: number }>({
table: CLICKHOUSE_SUBGRAPH_STATUS_TABLE,
format: "JSONEachRow",
values: statuses.map((status) => ({
db_name: status.dbName,
ipfs_hash: status.ipfsHash,
synced: status.synced,
failed: status.failed,
})),
});
and when I hover of values
in my IDE I’m told it has a type of unknown
Expected behaviour
I expect the generic of the insert
method to be applied to the shape of the args for the values
property
Configuration
Environment
- Client version:
^0.2.0
Can you please provide the entire code snippet, including imports?
Can you please provide the entire code snippet, including imports?
I just updated the code snippet with more context. If you need more information please let me know.
EDIT: looks like there's probably something wrong with my setup. I just tried this in replit and tsc is in fact catching the typing issue.
Yep, it does not reproduce on my machine as well. For example:
WebStorm 2023.1.2
TS 4.9.5
tsconfig.json
I think I got it. I was trying to simplify the code in the example. Here's a much fuller code sample which had the issue:
async function saveStatusesToDb(
statuses: SubgraphStatus[],
clickhouseClient: ClickHouseClient,
logger: Logger
) {
// stuff
await clickhouseClient.insert<{ a: number }>({
table: CLICKHOUSE_SUBGRAPH_STATUS_TABLE,
format: "JSONEachRow",
values: statuses.map((status) => ({
db_name: status.dbName,
ipfs_hash: status.ipfsHash,
synced: status.synced,
failed: status.failed,
})),
});
}
When I hovered over the clickhouseClient
I saw that it had a generic of unknown
I checked the repl and saw that the client had a generic of Readable
When I update my function parameter declaration like so (with a <Readable>
generic)
async function saveStatusesToDb(
statuses: SubgraphStatus[],
clickhouseClient: ClickHouseClient<Readable>,
logger: Logger
The types start getting inferred correctly
So tldr: when accepting a client as a function parameter, it must be typed with a <Readable>
generic for the type system to work properly. Not sure why that's the case.
Here's an example which demonstrates the issue (at least in my repl):
import { ClickHouseClient } from "@clickhouse/client";
function test(c: ClickHouseClient) {
c.insert<{ a: number }>({
table: "my-table",
values: { c: "b" }
})
}
Yep, ClickHouseClient
is now (after 0.2.0) a generic type with different stream types depending on the implementation.