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

Broken Array.protoype.from with generic 'length' array-like object without map predicate #1526

Open
BribeFromTheHive opened this issue Jan 26, 2024 · 0 comments

Comments

@BribeFromTheHive
Copy link

BribeFromTheHive commented Jan 26, 2024

Hi,

Array.protoype.from is malformed without a mapping predicate function. Granted, the predicate should be used instead of a map, but it gave very unusual results:

    function __TS__ArrayFrom(arrayLike, mapFn, thisArg)
        local result = {}
        if mapFn == nil then
            for ____, v in arrayLikeIterator(arrayLike) do
                result[#result + 1] = v
            end
        else
            for i, v in arrayLikeIterator(arrayLike) do
                result[#result + 1] = mapFn(thisArg, v, i - 1)
            end
        end
        return result
    end

If the mapFn is nil and the arrayLike is just an object with a length property set, like {length=16}, the whole thing just doesn't do anything because of how Lua tables handle nil assignments.

Lua doesn't offer an elegant solution to this problem. We'd either have to pack the table with zeros in this case, or perhaps throw an exception or warning. I'm not sure if interface declaration merging can at least warn users to make them aware of this issue in the TypeScript environment like by adding a deprecation warning or something. I tried to create an 'exact' type in TypeScript to handle the scenario where the passed object only has a 'length', but it seems that the built-in typescript definition clauses for 'from' still override this custom instruction. Due to declaration merging rather than replacing, the only thing I was able to leak through was the deprecation warning:

type HasOnlyLengthProp<T> = T & {
  [K in keyof T as Exclude<K, 'length'>]: never;
};

interface ArrayConstructor {
  /**
   * @deprecated Do not use this process due to broken interaction within Lua.
   */
  from<T>(arrayLike: HasOnlyLengthProp<T>, mapFn: never): [];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant