sdk-generator icon indicating copy to clipboard operation
sdk-generator copied to clipboard

Add typing support to query

Open Suven-p opened this issue 2 years ago • 11 comments

Closes #581

What does this PR do?

Adds typing support for web SDK

Test Plan

Manually test. Verified using typescript playground

Related PRs and Issues

#581

Have you read the Contributing Guidelines on issues?

Yes

Suven-p avatar May 09 '23 03:05 Suven-p

Suggestion for attribute value: Screenshot from 2023-05-09 09-27-32 Screenshot from 2023-05-09 09-27-48

Error for incorrect type: Screenshot from 2023-05-09 09-31-35

Suven-p avatar May 09 '23 03:05 Suven-p

Updated playground link: https://tsplay.dev/WYQJzW

Suven-p avatar May 09 '23 13:05 Suven-p

Would it be possible to even infer the type from the listDocuments as well?

TorstenDittmann avatar May 09 '23 14:05 TorstenDittmann

Would it be possible to even infer the type from the listDocuments as well?

Could you explain what you mean? I don't think its possible to infer the type returned by listDocuments.

Suven-p avatar May 09 '23 14:05 Suven-p

Would it be possible to even infer the type from the listDocuments as well?

Could you explain what you mean? I don't think its possible to infer the type returned by listDocuments.

I think this is what @TorstenDittmann meant: TS playground

You'll see I added a listDocuments, that checks if the return type from Query.isNull is valid, without having to pass the type to Query.isNull.

Doing this for all the query methods would be complicated, but I believe it is possible.

image

TGlide avatar May 10 '23 12:05 TGlide

Modifying your example slightly https://tsplay.dev/wXr2Dm provides autocomplete and type validation for attribute parameter. However, I cant think of a way of enforce type of value parameter. Screenshot from 2023-05-11 01-07-48

Suven-p avatar May 10 '23 19:05 Suven-p

I think it might not be possible to skip the type when creating a query with list documents, at least not with the current implementation. This is because:

  1. Any function signature for listDocuments would only have access to the value returned by Query.* methods. The most type restrictive version of return value of Query.equal is equal(${string & keyof T}, [${string}]). The second parameter has to be string in order to support array of values ie both "hello" and "hello","world". Since, the return type does not depend on type of T[K] it wouldn't influence the second argument to Query.equal and hence no typechecking.
  2. Even for functions such as isNull in @TGlide 's example, the type of the generic type extends string instead of T. I couldn't find an implementation that allows using T. Query.equal needs T in order to find type of T[typeof attribute].

I haven't thought this through but I think it might be possible to skip the type by changing the return value of Query.equal. IMO this would be way too complex and totally not worth it.

About 2: Usage outside listDocuments is either

export type QueryStr<T extends ModelType> = Query.isNull<string & keyof T>;
const a: QueryStr<TodoList> = Query.isNull("id")

or

Query.isNull<string & keyof TodoList>("id")

which looks weird to me.

Suven-p avatar May 12 '23 04:05 Suven-p

I think it might not be possible to skip the type when creating a query with list documents, at least not with the current implementation. This is because:

1. Any function signature for listDocuments would only have access to the value returned by Query.* methods. The most type restrictive version of return value of Query.equal is `equal(${string & keyof T}, [${string}])`. The second parameter has to be string in order to support array of values ie both `"hello"` and `"hello","world"`. Since, the return type does not depend on type of T[K] it wouldn't influence the second argument to Query.equal and hence no typechecking.

2. Even for functions such as isNull in @TGlide 's example, the type of the generic type extends string instead of T. I couldn't find an implementation that allows using T. Query.equal needs T in order to find type of `T[typeof attribute]`.

I haven't thought this through but I think it might be possible to skip the type by changing the return value of Query.equal. IMO this would be way too complex and totally not worth it.

About 2: Usage outside listDocuments is either

export type QueryStr<T extends ModelType> = Query.isNull<string & keyof T>;
const a: QueryStr<TodoList> = Query.isNull("id")

or

Query.isNull<string & keyof TodoList>("id")

which looks weird to me.

I also thought about changing the return types, would be way easier to infer types. But would change how listDocuments works.

@TorstenDittmann thoughts?

TGlide avatar May 16 '23 15:05 TGlide

For now I don't think we should change the return type of Query.

@TorstenDittmann, what do you think of https://github.com/appwrite/sdk-generator/pull/655#issuecomment-1549861465?

stnguyen90 avatar Jul 11 '23 19:07 stnguyen90

Anything new on this one?

HarunKilic avatar Aug 29 '23 04:08 HarunKilic

It would be very great if we can merge this PR ^^

Anyone can review it ?

🙏

Horsty80 avatar Mar 15 '24 22:03 Horsty80