rbxts-flamework / core

Flamework is an extensible game framework. It requires typescript and offers many useful features.
MIT License
112 stars 8 forks source link

Type guard generation fails on Enum unions #25

Closed Zyrakia closed 3 years ago

Zyrakia commented 3 years ago

I have a remote function set up to update PlayerData, which looks like this:

interface ServerFunctions {
    updatePlayerData(newData: Partial<PlayerData>): PlayerData | undefined;
}

When attempting to compile this it exceeds the maximum call stack size and does not compile, is there any way to rectify this? Because this function is designed to take in PlayerData that should be updated, and then on the server it checks if the player that invoked the function has access to change the data that they changed, if they do it will return the new data to them, otherwise it will return nothing.

By removing Partial it compiles, but I specifically want that the function to be used to update parts of the data, without having to reconstruct the complete data and only changing the value that you want changed.

Versions:

Stack trace:

RangeError: Maximum call stack size exceeded
    at Object.getExpressionPrecedence (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:17268:24)
    at parenthesizeExpressionForDisallowedComma MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:21222:43)
    at Object.sameMap (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:668:30)
    at Object.parenthesizeExpressionsOfCommaDelimitedList (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:21217:29)
    at Object.createCallExpression (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:23293:51)
    at Object.call (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\factory.js:101:24)
    at buildGuardFromType (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\functions\buildGuardFromType.js:147:28)
    at buildGuardsFromType (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\functions\buildGuardFromType.js:47:29)
    at buildGuardFromType (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\functions\buildGuardFromType.js:242:90)
    at buildGuardsFromType (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\functions\buildGuardFromType.js:47:29)
(node:11852) UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
    at Object.getExpressionPrecedence (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:17268:24)
    at parenthesizeExpressionForDisallowedComma (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:21222:43)
    at Object.sameMap (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:668:30)
    at Object.parenthesizeExpressionsOfCommaDelimitedList (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:21217:29)
    at Object.createCallExpression (MY_PATH\node_modules\roblox-ts\node_modules\typescript\lib\typescript.js:23293:51)
    at Object.call (MY_PATHA\node_modules\rbxts-transformer-flamework\out\util\factory.js:101:24)
    at buildGuardFromType (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\functions\buildGuardFromType.js:147:28)
    at buildGuardsFromType (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\functions\buildGuardFromType.js:47:29)
    at buildGuardFromType (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\functions\buildGuardFromType.js:242:90)
    at buildGuardsFromType (MY_PATH\node_modules\rbxts-transformer-flamework\out\util\functions\buildGuardFromType.js:47:29)
Fireboltofdeath commented 3 years ago

Can you send your PlayerData interface?

Zyrakia commented 3 years ago

This is the interface at the time of the error.

interface PlayerData {
    customName: string;
    playMinutes: number;
    font: Enum.Font;
    color: Color3;
    gradient: ColorSequence;
    gradientEnabled: boolean;
    idle: boolean;
    readonly premium: boolean;
}
Fireboltofdeath commented 3 years ago

I see. Enums aren't fully functional with unions yet. As a temporary workaround, you can use the name of fonts as an alternative (Exclude<keyof typeof Enum.Font, "GetEnumItems">) which can then simply be accessed via Enum.Font[name]

Fireboltofdeath commented 3 years ago

Fixed in https://github.com/rbxts-flamework/transformer/commit/b56acbcca2066c579426849120246f80959f8be3