I have a problem here which i believe it has 2
solutions. Here is my first implementation with function overloading:
type PostgresConnectionOptions = {
dialect: "postgres";
config: pg.PoolConfig;
};
type MysqlConnectionOptions = {
dialect: "mysql";
config: mysql.PoolOptions;
};
type SQLiteConnectionOptions = {
dialect: "sqlite";
config: {
filename: string;
};
};
async function getConnection(
options: PostgresConnectionOptions
): Promise<{ client: pg.PoolClient; dialect: "postgres" }> {
const client = await new pg.Pool({
...options.config,
}).connect();
return {
dialect: "postgres",
client,
};
}
async function getConnection(
options: MysqlConnectionOptions
): Promise<{ client: mysql.PoolConnection; dialect: "mysql" }> {
const client = await mysql
.createPool({
...options.config,
})
.getConnection();
return {
dialect: "mysql",
client,
};
}
async function getConnection(
options: SQLiteConnectionOptions
): Promise<{ client: sqlite3.Database; dialect: "sqlite" }> {
const client = new sqlite3.Database(options.config.filename);
return {
client,
dialect: "sqlite",
};
}
async function getConnection(...args: any[]): Promise<any> {
return {} as any;
}
The error i’m getting reads:
🌋 ‘getConnection’ is declared but its value is never read.ts(6133); Duplicate function implementation.ts(2393)
Which does’t make sense in this case because typescript should know that getConnection
parameters doesn’t have the same datatype.
Getting out of of function overloading i created a function called getConnection
type ConnectionOptions =
| PostgresConnectionOptions
| MysqlConnectionOptions
| SQLiteConnectionOptions;
type ConnectionResult =
| { client: mysql.PoolConnection; dialect: "mysql" }
| { client: pg.PoolClient; dialect: "postgres" }
| { client: sqlite3.Database; dialect: "sqlite" };
export const getConnection = async (
options: ConnectionOptions
): Promise<ConnectionResult> => {
if (options.dialect === "mysql") {
const client = await mysql
.createPool({
...options.config,
})
.getConnection();
return { client, dialect: options.dialect } as const;
} else if (options.dialect === "postgres") {
const client = await new pg.Pool({
...options.config,
}).connect();
return { client, dialect: options.dialect } as const;
} else if (options.dialect === "sqlite") {
}
const client = new sqlite3.Database(options.config.filename);
return { client, dialect: options.dialect } as const;
};
When i call getConnection
it is returning client
is a union of PoolConnection | PoolClient | Database
how can i make it infer the correct type based on the arguments passed. If this can be possible then the function overloading can be out, because the idea here is to get the actual return type of getConnection
2
Answers
Based on @BadPiggie's answer i was able to get what i wanted. Here is the final code:
Now typescript is happy is i do this:
client
is typed correctly as i was expecting.You should not implement all the function declarations. You only have to implement a single function that should handle all overloadings.
Documentation: https://www.tutorialsteacher.com/typescript/function-overloading