supabase / supabase-js

An isomorphic Javascript client for Supabase. Query your Supabase database, subscribe to realtime events, upload and download files, browse typescript examples, invoke postgres functions via rpc, invoke supabase edge functions, query pgvector.
https://supabase.com
MIT License
3.15k stars 251 forks source link

After updating to Supabase-js 2.0, expected return type is genericStringError #551

Open devlukedreamstage opened 2 years ago

devlukedreamstage commented 2 years ago

Bug report

Describe the bug

When trying to run a select query with supabase-js 2.0, typescript throws an error that the data returned by the api call is a generic string error causing issues.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

Here is the select function being ran:

 const { data, error } = await supabase
      .from("show")
      .select(attributes)
      .eq("slug", slug);
    if (error) throw error;
    return data;

Expected behavior

Not entirely sure what the return type should be, but I know it shouldn't expect to return a genericStringError. The data does get returned but this genericStringError is causing problems

Screenshots

If applicable, add screenshots to help explain your problem.

System information

MacOS Supabase-js: 2.0

Additional context

Add any other context about the problem here.

soedirgo commented 2 years ago

If anyone else bumps into this: .select() expects a string literal, not a string variable, otherwise the typings don't work properly. To ignore the GenericStringError, you can do .select(foo as any).

juanvilladev commented 1 year ago

Unfortunately, still seeing this issue:

    const { data: publicData, error: publicError } = await supabase.from(tableName).select(columns as any).eq('id', viewableObjectId).single();
    if (publicError) {
      throw new Error(publicError.message);
    }

The types being returned for publicData shows the genericstringerror

Has this fix perhaps been broken by the latest updates?

Aldo111 commented 1 year ago

Hi I have the same issue with the same setup as the OP, I keep seeing "GenericStringError" for the return and it errors out.

Doing as any didn't work but doing columns as '*' seems to kill the error. Still very unwieldy as a hack.

cco3 commented 10 months ago

It'd be nice if they more intentionally exposed the type to do this, but you can accomplish this by doing something like:

import type { GetResult } from "@supabase/postgrest-js/dist/module/select-query-parser.d.ts";
export type { Database } from "~/types/database"; // This is the database types file produced by 

const supabase = createClient<Database>("...", "...");

type Tables = Database["public"]["Tables"];
type TableName = keyof Tables;
type RowType<T extends TableName> = Tables[T]["Row"];
type RelationshipsType<T extends TableName> = Tables[T]["Relationships"];

type QueryResult<T extends TableName, Q extends string> = GetResult<
    Database,
    RowType<T>,
    RelationshipsType<T>,
    Q
  >;

const myWrappedQuery = async <T extends TableName, Q extends string = "*">(
  table: T,
  select: Q,
  query: Record<string, unknown> = {},
): QueryResult<T, Q> => {
  const {data} = await supabase
        .from(table)
        .select(select)
        .match(query);
  return data
};
jsonMartin commented 7 months ago

Hi I have the same issue with the same setup as the OP, I keep seeing "GenericStringError" for the return and it errors out.

Doing as any didn't work but doing columns as '*' seems to kill the error. Still very unwieldy as a hack.

Thank you very much for posting this solution; it's the only way I was able to solve the problem since the other solutions, including as any also did not work for dynamically passed select query strings. But I'd still consider this an issue in 2024, as ideally solving this wouldn't require implementing a hack 🤷🏼‍♂️

fmorroni commented 6 months ago

Hi having the same problem... Why was this closed? Not having type support unless we use string literals seems pretty limiting. Is this a typescript limitation which can't be fixed or is it a problem with how it's handled in the api?

jsonMartin commented 5 months ago

Should a new issue be opened for this? Having to use a hack isn't really a good long term solution.

If this is not going to be fixed for some reason, I'd like to at least know why. But as it stands now, this is still an open issue...

DylanGoodfellow commented 4 months ago

Also facing this issue when using a template literal on the select method like:

const { data, error } = await supabase
        .from('users')
        .update({ [attribute]: value })
        .eq('id', `${user.id}`)
        .select(`${attribute}`) // Offending line
        .single();

Would be great to see this acknowledged!

devlukedreamstage commented 4 months ago

Hi, sorry for the late response. My team and I resorted to this solution about a year ago:

async function getShowBySlug(
  slug: string,
  selectQuery: string = "*",
): Promise<any> {
  try {
    const res = await supabase
      .from("show")
      .select(selectQuery as any)
      .eq("org_id", siteOrg)
      .eq("slug", slug)
      .maybeSingle();
    return res.data;
  } catch {
    throw new Error("Error getting show");
  }
}

Don't get typescript errors here when accessing attributes on the data. However, if I remove the Promise<any>, I do get genericStringError when trying to access the data that is returned by this call.

antonio-bluco commented 2 months ago

Any news on this?

carcinocron commented 3 weeks ago

discovered this strange anomoly today:

const cols = 'id,name'
query.select(cols)
// good and normal

const cols = `
id,
name
`
query.select(cols)
// good and normal

const cols = [
  'id',
  'name'
].join(',')
query.select(cols)
// GenericStringError | null

const cols = [
  'id',
  'name'
].join(',') as const
// A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.
SkeltalFlamingo commented 2 weeks ago

This problem should not have been closed. like others, this is what worked for me: .select(columns as "*")