w3c / wot-scripting-api

Web of Things (WoT) Scripting API
http://w3c.github.io/wot-scripting-api/
Other
43 stars 28 forks source link

Better types for Scripting API #489

Open relu91 opened 1 year ago

relu91 commented 1 year ago

This PR can be considered editorial in the sense that improves artifacts of the main note document. In typescript, Generics can be used to improve the description of a certain API. Here I add generic parameters to ExposedThing and ConsumeThing in order to capture compile-time errors like reading a property that does not exist in the consumed Thing Description or attaching a handler for an action that was not defined in the ExposeThingInit. The downside is that it makes the types a little bit more complex.

danielpeintner commented 1 year ago

Looks very promising 👍

I tried to copy the update to a local node-wot instance and run into some issues.. image

I simply replaced index.d.ts with the updated version. Am I supposed to do more?

relu91 commented 1 year ago

Thank you for testing @danielpeintner ! Can you give me a little bit more context, thing is a ConsumedThing that is using which TD?

danielpeintner commented 1 year ago

Can you give me a little bit more context, thing is a ConsumedThing that is using which TD?

I simply manually updated index.d.ts in the node-wot repo and looked at the counter-client sample which gave me all these warnings..

relu91 commented 1 year ago

Ah I see, then the problem is here:

const thing = await WoT.consume(td as ThingDescription);

Casting to plain ThingDescription type will cause keyof T.properties to return never 😢 . I don't if there is easy why to fix this without changing the example code 🤔

danielpeintner commented 1 year ago

I see. The problem is that it is shown as an "error" and I don't think this is very good either from developers point of view. Mhh, not sure how to move on from here...

relu91 commented 1 year ago

One option is to default to string instead of never. This allows people to cast variables to ThingDescription type and use readProperty and the other functions as before. If they use the correct typing (i.e., do not cast to ThingDescription) they get the type guards about names. However, this solution does not understand the difference between a TD without any property and a TD that has been cast to ThingDescription.

My preferred solution is to avoid casting to ThingDescription and let the compiler do its work. However, it seems that the ThingDescription type is a little bit too restrictive and as in the counter example, is not easy to create an already good TD using inline object literals 😢 .

danielpeintner commented 1 year ago

Scripting API call Nov 20