Skip to content

Functions like pcall #947

@LoganDark

Description

@LoganDark

pcall prepends its own success value to the values returned by a function. Unfortunately this is probably impossible to represent in TypeScript.

Since functions that return multiple values use an array you can use the spread operator like so:

declare function pcall<F extends (...args: any) => any>(this: void, f: F, ...args: Parameters<F>): [true, ...ReturnType<F>] | [false, string]

But functions that return an indexed table will have their return values erroneously spread.

Likewise this works for functions that do not return multiple values:

declare function pcall<F extends (...args: any) => any>(this: void, f: F, args: Parameters<F>): [true, ...ReturnType<F>] | [false, string]

but breaks for functions that do:

function returnsMultipleValues() {
	return [4, 5, 6]
}

const [success, message, two, three] = pcall(returnsMultipleValues)

transpiles to

success, message, two, three = pcall(returnsMultipleValues)

which is correct, however:

main.ts(5,26): error TS2339: Property '2' does not exist on type '[false, string] | [true, number[]]'.
main.ts(5,31): error TS2339: Property '3' does not exist on type '[false, string] | [true, number[]]'.
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! cc-path-tracer@0.0.1 build: `tstl`
npm ERR! Exit status 2

Since the @tupleReturn does not look like anything to TypeScript, it can't detect that annotation on its own.

Perhaps some type could be introduced by TypeScriptToLua to help this.

declare function pcall<F extends (...args: any) => any>(this: void, f: F, args: Parameters<F>): [true, ...TuplifyReturnType<F>] | [false, string]

Which would act like ReturnType, but wrap the return type in a tuple if the function does not have the @tupleReturn annotation.

However I am not sure how this would work because the goal of these types is for IDE support and reading it at the transpilation step is too late.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions