Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Promises? #88

Closed
ryan-mahoney opened this Issue Jul 31, 2018 · 7 comments

Comments

Projects
None yet
2 participants
@ryan-mahoney
Copy link

ryan-mahoney commented Jul 31, 2018

What if a function returns a promise? Is that something that this library handles? Sorry if this is something very easy to do... just didn't see it in the documentation.

Thanks!

@sylvainpolletvillard

This comment has been minimized.

Copy link
Owner

sylvainpolletvillard commented Jul 31, 2018

Promise is a type among others. What do you expect from the library ? A code example could help you get your point accross

@ryan-mahoney

This comment has been minimized.

Copy link
Author

ryan-mahoney commented Jul 31, 2018

Thank you for response -- I was doing it wrong!

I had:

import { FunctionModel, Model } from "objectmodel";

const inputType = Model({ name: String });
const returnType = Model({ count: Number });
const fn = async ({ name }) => ({
  count: await new Promise(resolve =>
    setTimeout(() => {
      resolve(name.length);
    }, 100)
  )
});

const typedFn = FunctionModel(inputType).return(returnType)(fn);

console.log(typedFn({ name: "Ryan" }));

But it should have been:

import { FunctionModel, Model } from "objectmodel";

const inputType = Model({ name: String });
const returnType = Promise;
const fn = async ({ name }) => ({
  count: await new Promise(resolve =>
    setTimeout(() => {
      resolve(name.length);
    }, 100)
  )
});

const typedFn = FunctionModel(inputType).return(returnType)(fn);

console.log(typedFn({ name: "Ryan" }));

I guess there is probably no way to add type checking to what a promise will eventually resolve to... which I think is fine, because that data would be checked (in my case) when it is passed as input to another function.

Sorry for false alarm!

@sylvainpolletvillard

This comment has been minimized.

Copy link
Owner

sylvainpolletvillard commented Jul 31, 2018

Actually it is possible to typecheck what the promise will eventually resolve to, but this has to be done once the promise is resolved. Because validation is done at runtime, it is impossible to validate before the promise actually resolved:

let PromiseModel = BasicModel(Promise);
let NumberModel = BasicModel(Number);

x = new Promise(resolve => setTimeout(() => resolve(42), 1000));
PromiseModel .test(x) // true
NumberModel.test(x) // false

x.then(resolvedValue => {
  NumberModel.test(resolvedValue) // true
})

You won't be able to validate both the promise and the promise resolved value at the same place, like you would do with a static typechecker like TypeScript and Promise<Number>. A static typechecker analyze all your code at the sametime, it doesn't care what is async and what is synchronous. But what if you need to validate something dynamically, like an async network response of your API ? ObjectModel can validate this kind of stuff, but the validation has to be done once the promise resolved:

const PromiseOf = model => p => Model(Promise)(p).then(x => model(x));

const asyncPromiseModel = PromiseOf(Model({ count: Number }))
x = new Promise(resolve => setTimeout(() => resolve({ count: 42 }), 1000));

asyncPromiseModel(x).then(({ count }) => {
   // ObjectModel has validated both the Promise type, and the Promise resolved value model
  console.log(count);
})
@ryan-mahoney

This comment has been minimized.

Copy link
Author

ryan-mahoney commented Jul 31, 2018

Very cool!

Maybe this is something that you might consider adding to the documentation. I had done a cursory search of the documentation / examples for the word "promise", and since I didn't see it I made a false assumption about the capabilities.

@sylvainpolletvillard

This comment has been minimized.

Copy link
Owner

sylvainpolletvillard commented Jul 31, 2018

I suppose I can add an entry in the FAQ section. The thing is that library doesn't have to do something special to handle promises, you just wrap what you want to validate in a model and that's it. Same goes for Observables or other async structures.

@ryan-mahoney

This comment has been minimized.

Copy link
Author

ryan-mahoney commented Jul 31, 2018

Now that we have had this conversation I completely understand your point. I do think though, for a new user of the library there may be an expectation to see how this library handles Promises because they are a little bit of a special case in Javascript... at least when you are using the async / await syntax.

@sylvainpolletvillard

This comment has been minimized.

Copy link
Owner

sylvainpolletvillard commented Aug 1, 2018

I added an entry to the FAQ in the docs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.