Giter Site home page Giter Site logo

typed-luau-promise's Introduction

Typed Roblox Promises

This is a wrapper that adds full Luau type support for roblox-lua-promise. It does this using some fancy Luau type trickery. The result is a way more pleasant experience when using Promises in luau where everything is fully typed, even when you chain promises.

Installation

To install, simply copy the Promise.lua script into your project and modify the game.ReplicatedStorage.Packages.UntypedPromise at the bottom with the path to roblox-lua-promise.

Usage

You can simply use this typed wrapper the same way you'd use roblox-lua-promise itself. This is a drop-in replacement that you will immediately reap the benefits of in your existing code.

What's so special about this?

This wrapper fully supports chaining promises, which most other wrappers are unable to. It does this by repeating the type definition of Promise multiple times. This is because recursive types are not supported in Luau, making this neccessary to have a correct definition for promises. image

Why is there a generation script?

Instead of having to manually write out a repeated type definition 10 times, there's a generate-promise.ts script that does this for us, making it very easy to modify the definition without having to make the change multiple times. To run the generation script, simply do deno run generate-promise.ts > Promise.lua

Things you may run into

Incomplete definition

This wrapper doesn't define every single function in roblox-lua-promise because I never got around to it. Adding new ones is relatively straight forward, and may be added whenever I run into the need. Feel free to contribute a pull request adding any missing definitions.

Promise.all

The definition of Promise.all requires all of the promises passed in to have the same non-variable return type. This is so that the output promise can be typed as Promise<{ T }>. It will cause issues if you have code like this:

local pA = fetchA() -- returns `string`
local pB = fetchB() -- returns `number`
local pC = fetchC() -- returns `boolean`
local a, b, c = unpack(Promise.all({pA, pB, pC}):expect()) -- errors since promise types aren't uniform

You should ideally rewrite the code to look this instead:

local pA = fetchA()
local pB = fetchB()
local pC = fetchC()
local a = pA:expect()
local b = pB:expect()
local c = pC:expect()

Generic variable type

For cases where a variable may need to store a generic promise, you can use the AnyPromise type. This stores any promise, however you don't get any type info about what the promise will return.

local p: Promise.AnyPromise

p = Promise.resolve("hello")
p = Promise.resolve(5)
p = p:andThen(function(r) -- r is typed as `any`
    return r
end)

typed-luau-promise's People

Contributors

fewkz avatar

Stargazers

omar avatar sleeper avatar Regis Frey avatar Fizzy avatar

Watchers

 avatar

Forkers

trheliad

typed-luau-promise's Issues

Add support for returning Promises

As described in the comment, we're unable to support this at the moment due to Luau not being smart enough to infer the type at the moment.

// If a successHandler or failureHandler return a Promise, the Promise will be chained on.
// Therefore, we type our handlers as a union of functions, the first
// returning PromiseLike<T2...> and the second returning T2...
// This has the consequence of the function passed to andThen not registering it's
// parameters correctly, instead being inferred from the body of the function.
// For example, the following code:
// local function foo(a: number) end
// Promise.resolve("hi"):andThen(function(b)
// foo(b)
// end)
// Will infer b as a number, rather than know that it's a string.
// And it will precede to give a very verbose error about how:
// Type '(number) -> ()' could not be converted into '((string) -> (a...)) | ((string) -> PromiseLike<a...>)';
// Therefore, we put it behind a flag that we have off, until Luau becomes a little smarter.
// Until then, a replacement for :andThenCall(promise) is :andThen(function() return promise:expect() end)
const allowReturningPromises = false;

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.