Git Product home page Git Product logo

Comments (4)

woutervh- avatar woutervh- commented on May 29, 2024 1

Hi @ArashMotamedi

I checked out your gist, cool stuff. I've been thinking about generated documentation for APIs in TypeScript myself as well, but unfortunately didn't have the time to get to it.

Regarding the way typescript-is is used, here are my two cents:

  • In the client, it seems like the type guard is unnecessary. Since the type of the object passed to the call function is already of type DocumentTypes[T], it should be safe, and it should be unnecessary to validate it. Unless somehow there are objects being passed to call that are any for example, but then it seems the responsibility of the caller to validate it, or the signature of call should reflect that and accept unknown for example.
import { DocumentTypes, is } from "my-document-types";
function call<T extends keyof DocumentTypes>(request: DocumentTypes[T]) {
   ...
   // request is already valid because of the type in the function signature!
   if (!is[request.type](request)) throw "Invalid Request Object";
   ...
}
  • In the server you could use a union type (actually also in the client, but I'll use the server to demonstrate what I mean). Since typescript-is can handle union types, you can use a single call to it to determine if the incoming request body is a valid request, and the use type narrowing from TypeScript to determine which type of request it is.
export type DocumentTypes = SigninRequest | GetUserDetailsRequest | <...>;
<...>
if (!is<DocumentTypes>(req.body)) {
   // send error
}
// body is one of the DocumenTypes and type narrowing can be used as well
res.send(apis[req.body.type](req.body));
res.end();

I use this kind of pattern a lot in my code as well, define a union type where each possibility of the union has a different value for {type} and then narrow the types with a string comparison in the type.

type A = {type: 'B'} | {type: 'C'};
if (is<A>(obj)) {
   switch (obj.type) {
      case 'B':
         // can safely use obj as {type: 'B'}
      <...>
   }
}

from typescript-is.

woutervh- avatar woutervh- commented on May 29, 2024

Hi @ArashMotamedi

Glad to hear you like the project!

I'm guessing just using is<Interface>(obj) where ever you need to check the type is not an option for you, and that's why you're using the createIs<Interface>() function. Probably to reduce the size of the transformed code? I agree that it would be easier to have a generated module in that case.

In fact, my first attempt when I started this project was to try to emit such a runtime file with all validations in it: folder transform-module in https://github.com/woutervh-/typescript-is/tree/master/src
However I abandoned this idea in favor of creating the inline transformer because it was much easier to implement.
The problem I had with creating a module file was that I'd have to somehow include this generated code in the build output and point all of the imports to that new file. Ideally the generated file would be in the node_modules/typescript-is directory, but this is usually not bundled with an application.

To get a better idea for a good implementation, can you describe how you envision the file will be included?
For example, I thought this might work:

  • Specify an outFile option in the transformer options in tsconfig.json
  • typescript-is will emit runtime type checking code in this outFile
  • typescript-is will transform all imports to is, createIs, etc. to import from path.relative(__file, outFile)

Edit
I haven't thought about this either yet, but what about when you're using the application with ts-node? I'm not sure if and how the emitted file can be included. Something to figure out.

from typescript-is.

ArashMotamedi avatar ArashMotamedi commented on May 29, 2024

Hey @woutervh-

Thanks for your reply and sorry for my delay. I went back and forth a bunch of times to figure out what exactly I'm trying to achieve, and realized that my true goal is to create a semi-reflection solution, to be able to validate objects at runtime, with as little manual coding as possible. This is what I have done so far: https://gist.github.com/ArashMotamedi/7f3ee81839618939c6dc5625bd4e9093

Your library has been super valuable in performing the checks to have peace of mind: by the time my api functions start operating on the request, it's guaranteed that the request object conforms to the interface definition.

from typescript-is.

ArashMotamedi avatar ArashMotamedi commented on May 29, 2024

Great points, thanks @woutervh-. Please keep up your great work.

The API extractor and request validator have proven very valuable for my code. I have 3 projects setup: api-types, webapp, api-server. I create interfaces in the api-types project, and have integrated my API extractor and your is transformer as part of the build/install script. Then I reference this project (as a subtree) in my webapp and api-server projects. Anytime I need a tweak to my API signatures or want to create a new API, all I have to do is define the interfaces, pull subtrees, and npm install (all of which I've scripted). Maybe at some point I'll turn that API extractor to a library as well.

from typescript-is.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.