Hi @rflynn,
great to hear that the sdk is now type safe!
However, when I try to execute a query to fetch boards, I’m getting a TS error while trying to grab the fetched data:
Is there anything I’m missing?
Thank you in advance!
Cheers
Jona
Hi @rflynn,
great to hear that the sdk is now type safe!
However, when I try to execute a query to fetch boards, I’m getting a TS error while trying to grab the fetched data:
Is there anything I’m missing?
Thank you in advance!
Cheers
Jona
From what I understand, the Typescript support is currently limited to the SDK methods and not the results returned by monday. Those you will have to handle yourself
In the client-api.interface.ts
(see Github) the type is written like this:
// ...
api(query: string, options?: APIOptions): Promise<{ data: object }>;
// ...
I think that Promise<{data: object}>
needs to be changed in order to have correct types or at least to have no TS errors (maybe to something like Promise<{data: Record<string, any>}>
). Else one would have to disable type checking for all lines where one is trying to access res.data
from an api call.
Why do you have to display type checking for res.data
? Giving that the data returned by res.data
is dynamic, you can create your own custom interface or class and you it like this res: CustomInterface
Maybe my explanation wasn’t that good. So let me try to summarize:
res.data
is dynamic and type checking would not really have any benifit because it would be only type casting and you never could be sure that the types are really met.res.data
because it is of type object
and this type does not have any properties that I could access (see error in my screenshot above).res.data
object throughout all api calls in my code, we would have to do type casting so that TS wouldn’t complain. However, this seems to be quite an overhead for us since this would be a fix on our side due to misleading types in the monday sdk. E.g.api(query: string, options?: APIOptions): Promise<{ data: any }>;
// or
api(query: string, options?: APIOptions): Promise<{ data: Record<string, any>}>;
would allow any access on res.data
so that we don’t have to type cast it on our end.res: CustomInterface
does not work because you cannot just overwrite existing typingsSo, all in all, my issue is not that there is no concrete type checking but that there is “wrong” type checking with data: object
.
Thanks for your clarification! I can see how this would cost some additional effort.
I’ve submitted these suggestions to our development team so they consider implementing this fix.
Good morning @alessandra,
are there any updates, e.g. maybe a public github issue I could watch to get updates regarding the implementation progress of the fix? Or will you post updates here as soon as there are some?
Hello @j-ittermann-decadis,
We do not have an update yet.
Any changes like this one would be announced in our changelog. You can an eye open over there to check our updates!
Cheers,
Matias
Hey @j-ittermann-decadis – I like the suggestion of using a record for this.
But I want your 2c: if we changed the return type of api
to Record, would it be a breaking change?
Aka, will the following be a breaking change for people already using the types?
Old version –
api(query: string, options?: APIOptions): Promise<{ data: object }>;
New version –
api(query: string, options?: APIOptions): Promise<{ data: Record<string, any>}>;
BTW, I moved this to a new topic to keep the original announcement clean!
Hi @dipro,
thank you for taking a look and creating the new topic!
As far as I can estimate it, this should not be a breaking change because:
Record<string, any>
would still be an object. So when doing for example typeof data
for both the old and new version, it would return "object"
. So anybody out there who is doing type checking like so would not see any difference in their outcome.object
is not a real TS type you could work upon as I stated in the beginning of the post, so I’m assuming that everybody who wants to have here some type safety or in general wants to work with data
, is already casting it to some other type. If they didn’t want to have type safety, e.g. by casting to type any
, it would not make any difference of which type data
is anyways.data: SomeCustomType
or data as SomeCustomType
that means that TS allows that casting from object
to SomeCustomType
Let me know, if you can follow my train of thought and if it does also make sense for you
Cheers!
PS: FYI there is also some PR open for changing the types in another place where using Record
is being considered, too.
You’re the best, thanks for the explanation! Sounds like it won’t be a breaking change.
Anyway, I’ll test it out a bit when making a PR, to double check.
I vote that ideal solution is using generics with a default of whatever is decided. That way we can specify the type when we call the method monday.api<CustomResponseType>()
and the response will be of a type like:
interface MondayResponse<T = Record<string, any>> {
data?: T
error_code?: string //ideally a union type of all the error_code values
// rest of the error related keys
}
This way if we provide our own type for T, then data will be our custom type, but otherwise Record<string, any> if T is not specified.
I think the response needs to be a type that includes more than data, we need to be checking if there are errors too still, correct? (unless the SDK is now throwing exceptions… I haven’t tested since I starting using my own custom client for NodeJS.)