Comments (4)
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 typeDocumentTypes[T]
, it should be safe, and it should be unnecessary to validate it. Unless somehow there are objects being passed tocall
that areany
for example, but then it seems the responsibility of the caller to validate it, or the signature ofcall
should reflect that and acceptunknown
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.
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 intsconfig.json
typescript-is
will emit runtime type checking code in thisoutFile
typescript-is
will transform allimport
s tois
,createIs
, etc. to import frompath.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.
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.
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)
- Feature Request: Shortcut to simplify `const v = func(); is<type>(v) ? v : default` HOT 1
- Fix intersections with primitives to add support for branded/flavored types HOT 1
- Intersection disables `disallowSuperfluousProperties` all the way down
- Non-deterministic code generated HOT 1
- Support typeof on object types
- Parsing fails when target & aliasTypeArguments are at different levels HOT 1
- Investigation of Unbound Type Parameters
- typescript-is introduces "typescript" dependency into production environment
- TypeError: Cannot read property 'text' of undefined
- Bug: A missing key and a key with a value of undefined are not considered the same
- Fail to check Enum in Record HOT 9
- Have you plan to support Deno? HOT 2
- use instantiation expressions in typescript 4.7
- Make generated code smaller by putting reusable strings to constants or functions HOT 1
- feature request: set custom error class in AssertType
- Thoughts on extending createAssertType() HOT 1
- Incompatible with TypeScript 4.8 HOT 2
- What about re-export `typia` for maintenance? HOT 1
- ttypescript not support TS@5
- Deprecation message and recommends to use `typia` instead HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typescript-is.