#Is there any way I don't have to use "unknown"?

14 messages · Page 1 of 1 (latest)

split latch
#
import { QueryResult, QueryResultRow} from "pg"
import client from "./config"

export const execute = async <T>(
  query: string,
  prepared?: T[]
): Promise<{
  data: QueryResult<T[]>
  count: number | null
}> => {
  try {
    const pool = await client.connect()
    const res: QueryResultRow = await pool.query(query, prepared)
    pool.release()

    return {
      data: res.rows,
      count: res.rowCount,
    }
  } catch (error: any) {
    throw new Error(error)
  }
}

this is my function I created to do queries

  const result = <{ data: User }>(
    (<unknown>(
      await execute(`SELECT username, password FROM users WHERE username=$1`, [
        username,
      ])
    ))
  )

This is how I am using the function.

Is there anyway I can do this without using "unknown"?

rapid mesa
#

you shouldn't be doing that, that's a really unsafe cast

olive bone
#

sidenote: there's no point using a try catch if you're just going to rethrow the error

rapid mesa
#

if you need to sidecast, then seems like your return type is maybe just wrong then?

#

or you might be misusing your function, i can't really tell

split latch
#

sorry, I'm new to typescript. I just want to make sure when I do result.data.whatever it comes up in the options while I am typing

split latch
olive bone
#

no you just shouldn't use a try catch unless you intend to properly handle the error

split latch
olive bone
#

you're misusing generics

split latch
#

I thought you use a generic when you don’t know what type is going to be used

pure prawn
#

you use generics when the caller has a specific type they want to use and your function can operate generically on that type without knowing what it is (like to implement <T>(x: T) => [T] we don't need to know what T is)

#

i haven't used pg, but it looks like QueryResultRow is just Record<string, any>, so it's already wildly unsafe. the res.rows and res.rowCount are not being checked at all and execute's return value can't really be relied on. that being said, even if you "know" that data will have a certain shape, i doubt that shape is supposed to be QueryResult<T[]>, since T seems to be the type of the query's parameters

the only 100% safe way to do this is to return Promise<unknown> and narrow the result via runtime checks at the call site. if you don't care to be safe you should probably still return something like Promise<unknown> and assert that the type is what you expect, then you wouldn't need to artificially go through unknown

#

seems like pg isn't designed with typescript in mind. are you stuck with that library? there are other postgres drivers out there that may be easier to use from typescript (not to mention higher-level libraries like drizzle or slonik)