You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since now there is no difference between {} and [], it's impossible to implement a stable Array.isArray. Transpling array literals to setmetatable({}, ____arrayMetatable) gives required data for Array.isArray and doesn't affect performance too much.
A major issue is that there would be a need for a new decorator (or a type) to mark functions that return standard lua arrays, and then set the metatable of returned values.
Any flags that affect transpilation have a major issue - using files built with different options won't work (which is especially important for lualib).
A metatable has a low performance cost on 5.3 and doesn't affect performance on JIT at all, so IMO an option doesn't worth the issues it has.
Also, is a metatable even needed?
Not really, any special mark would do it. I think metatable may work better with some native environment functions that would iterate over an array.
I propose a new, class-based Array implementation, enabled by an opt-in tsconfig.json setting like "arrayClass": true. All array will use this class to construct. Except Array.isArray, other Array static and non-static methods will still compiled to use lualib implementations.
_G.Array ??= class Array {
public static isArray(arg: any): arg is any[] {
return arg instanceof _G.Array;
}
} as ArrayConstructor;
This would provide:
A reliable way to distinguish [] and {}.
The ability to extend the Array class (class MyArray extends Array {}).
Making this optional ensures no breaking changes or performance impact for existing projects.
The lualib Implementation Challenge
A simple opt-in feature is difficult due to the static, pre-compiled lualib_bundle.lua.
Core functions within this bundle, like __TS__ArrayMap, internally create new arrays (e.g., const result = []). This code is part of the static bundle and cannot be compiled conditionally based on a user's tsconfig.json options. This prevents library functions from correctly creating class-based arrays when the feature is enabled.
Potential Solutions
Dynamic lualib output:
Compile all lualib functions (__TS__ArrayMap, etc.) to create arrays via a new internal helper, e.g., __TS__NewArray(rawTable?:any[]).
Default __TS__NewArray just return raw table, but return Array instance if "arrayClass": true, so we need some way to modify the output of __TS__NewArray in compile time (Pls tell me the right way to do this), and the performance impact of calling __TS__NewArray function will be inevitable.
No arrayClass options, always use Array class.
This is a Big change, but I believe this is the right way.
@Perryvw Please tell me your thought about this, then I can decide what to do.
I don't think adding this would be worth the trouble. If you want this special data structure for some reason you can define your own class, no need to mainline it into core tstl
I don't think adding this would be worth the trouble. If you want this special data structure for some reason you can define your own class, no need to mainline it into core tstl
The main reaason for me is to distinguish [] and {}, so I am suppose to use my custom plugin to solve this right? Even I write my custom plugin to override array transform, there are still some raw table defined in lualib.
Not only for this trouble, it is more ECMAScript standand.
Activity
tomblind commentedon Apr 24, 2019
I definitely think this should be optional, so folks can keep things as minimal lua if they desire.
Also, is a metatable even needed? Something like this could work:
ark120202 commentedon Apr 24, 2019
Any flags that affect transpilation have a major issue - using files built with different options won't work (which is especially important for lualib).
A metatable has a low performance cost on 5.3 and doesn't affect performance on JIT at all, so IMO an option doesn't worth the issues it has.
Not really, any special mark would do it. I think metatable may work better with some native environment functions that would iterate over an array.
pilaoda commentedon Aug 11, 2025
Hi. I would like to add a PR about this.
Proposed Solution
I propose a new, class-based Array implementation, enabled by an opt-in
tsconfig.jsonsetting like"arrayClass": true. All array will use this class to construct. ExceptArray.isArray, otherArraystatic and non-static methods will still compiled to uselualibimplementations.This would provide:
[]and{}.Arrayclass (class MyArray extends Array {}).Making this optional ensures no breaking changes or performance impact for existing projects.
The
lualibImplementation ChallengeA simple opt-in feature is difficult due to the static, pre-compiled
lualib_bundle.lua.Core functions within this bundle, like
__TS__ArrayMap, internally create new arrays (e.g., const result = []). This code is part of the static bundle and cannot be compiled conditionally based on a user's tsconfig.json options. This prevents library functions from correctly creating class-based arrays when the feature is enabled.Potential Solutions
Dynamic
lualiboutput:__TS__NewArray(rawTable?:any[]).__TS__NewArrayjust return raw table, but returnArrayinstance if"arrayClass": true, so we need some way to modify the output of__TS__NewArrayin compile time (Pls tell me the right way to do this), and the performance impact of calling__TS__NewArrayfunction will be inevitable.No
arrayClassoptions, always useArrayclass.This is a Big change, but I believe this is the right way.
@Perryvw Please tell me your thought about this, then I can decide what to do.
Perryvw commentedon Aug 11, 2025
I don't think adding this would be worth the trouble. If you want this special data structure for some reason you can define your own class, no need to mainline it into core tstl
Zamiell commentedon Aug 11, 2025
In order to use a custom class for this purpose, one would have to use a plugin to override the Array implementation right?
pilaoda commentedon Aug 12, 2025
The main reaason for me is to distinguish
[]and{}, so I am suppose to use my custom plugin to solve this right? Even I write my custom plugin to overridearraytransform, there are still some raw table defined inlualib.Not only for this trouble, it is more ECMAScript standand.