diff --git a/scripts/emitted-baseline-runtime.txt b/scripts/emitted-baseline-runtime.txt index 7a4c385a..e881bc49 100644 --- a/scripts/emitted-baseline-runtime.txt +++ b/scripts/emitted-baseline-runtime.txt @@ -946,6 +946,7 @@ object-integrity-uses-physical-index-protocol.runtime.ts.cpp 23551c4185ed object-is-over-union-and-optional-carriers.runtime.ts.cpp 199c1035ac10 object-key-enumeration-requires-native-object.runtime.ts.cpp f6c110078688 object-keyed-map-index-matches-node.runtime.ts.cpp ab5c357ecdd6 +object-keys-over-recursive-dictionary-or-array-union.runtime.ts.cpp 061e846e55a7 object-literal-beside-class-in-or-keeps-its-own-layout.runtime.ts.cpp d86094099c83 object-literal-empty-array-filled-through-untyped-computed-read.runtime.js.cpp d13b67ac0d25 object-literal-es5-method-receiver.runtime.js.cpp 4c1c19bfe47a diff --git a/src/targets/cpp/runtime/gea_runtime.h b/src/targets/cpp/runtime/gea_runtime.h index ddf5d293..6de309da 100644 --- a/src/targets/cpp/runtime/gea_runtime.h +++ b/src/targets/cpp/runtime/gea_runtime.h @@ -15981,6 +15981,15 @@ struct ArrayObjectElementOf> { using type = Element; }; +namespace detail { +template +ArrayObject arrayObjectBaseProbe(const ArrayObject&); +template +using ArrayObjectBaseOf = decltype(arrayObjectBaseProbe(std::declval())); +template +concept DerivedArrayObject = !IsArrayObjectStruct::value && requires { typename ArrayObjectBaseOf; }; +} + namespace detail { template struct DynamicCarrier; @@ -32639,6 +32648,26 @@ bool assignOwnPropertiesUnorderedWith(const gea::Ref& source, const gea::Ref< } /** Array exotic own enumerable string keys, followed by enumerable expandos. */ +template +std::vector arrayOwnEnumerableKeys(const gea::Ref>& array); +template +bool arrayHasOwnEnumerableKey(const gea::Ref>& array, const std::string& key); +template +std::vector arrayOwnPropertyNames(const gea::Ref>& array); + +template +std::vector arrayOwnEnumerableKeys(const gea::Ref& array) { + return arrayOwnEnumerableKeys(gea::Ref>(array)); +} +template +bool arrayHasOwnEnumerableKey(const gea::Ref& array, const std::string& key) { + return arrayHasOwnEnumerableKey(gea::Ref>(array), key); +} +template +std::vector arrayOwnPropertyNames(const gea::Ref& array) { + return arrayOwnPropertyNames(gea::Ref>(array)); +} + template std::vector arrayOwnEnumerableKeys(const gea::Ref>& array) { std::vector keys; diff --git a/test/runtime/object-keys-over-recursive-dictionary-or-array-union.runtime.ts b/test/runtime/object-keys-over-recursive-dictionary-or-array-union.runtime.ts new file mode 100644 index 00000000..ab8e8e1e --- /dev/null +++ b/test/runtime/object-keys-over-recursive-dictionary-or-array-union.runtime.ts @@ -0,0 +1,16 @@ +type Leaf = string +type Tree = { [key: string]: Leaf | Tree | Branch } +type Branch = (Leaf | Tree | Branch | undefined)[] +type Container = Tree | Branch + +const keysOf = (container: Container): string => Object.keys(container).join(',') + +const tree: Tree = { a: 'x', b: ['y', { c: 'z' }] } +const branch: Branch = ['p', tree, undefined, 'q'] +tree['self'] = branch + +console.log(keysOf(tree)) +console.log(keysOf(branch)) + +//! expect: a,b,self +//! expect: 0,1,2,3