Typescript Map Property

Hello,

I am trying to make a component property using the Map typescript class.

Here is a minimal example.

import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('NewComponent')
export class NewComponent extends Component {
    @property(Map)
    public myMap: Map<string, string> = new Map<string, string>([['a' , 'b']]);
}

This compiles, but here is what is displayed in the editor :

map_property

I found on the end of this topic from 2018 that maps were not supported. Typescript array @property - #13 by jare
It has been 4 years though, and i don’t find any other mentions in the doc or the forum.

The fact that it compiles and display something without errors or warning makes me ask myself whether it’s still not supported or if it’s me doing something wrong. Could someone tell me which one it is ?

If it is not yet supported, is there a way to constraint two different Array properties to always have the same size in the editor ? So that i can safely remap them at runtime.

Thanks in advance.

Typescript Map Property already has plans to support it, maybe in 3.6.1 you can see it, look forward to it!

Thank you.

In the meantime, i tried something to force two arrays of keys and values to be the same size in the editor and then remap them at runtime.

import { _decorator, Component, CCString } from 'cc';
const { ccclass, property} = _decorator;

@ccclass('NewComponent')
export class NewComponent extends Component {
    private map: Map<string, string>;

    private keysArray : Array<string> = [];
    private valuesArray : Array<string> = [];

    private set keys(value : Array<string> ) {
        this.keysArray = value;
        this.ensureArraysLength();
    }

    @property([CCString])
    private get keys() : Array<string> {
        return this.keysArray;
    }

    private set values(value : Array<string> ) {
        this.valuesArray = value;
        this.ensureArraysLength();
    }

    @property([CCString])
    private get values() : Array<string> {
        return this.valuesArray;
    }

    protected onLoad() : void {
        this.map = new Map<string, string>();
        for(let i = 0; i < this.keysArray.length - 1; i++) {
            this.map.set(this.keysArray[i], this.valuesArray[i]);
        }

        console.log(this.map);
    }

    private ensureArraysLength() : void {
        console.log('ensureArraysLength');

        if(this.keysArray.length > this.valuesArray.length) {
            let newValues = [];
            for(let i = 0; i < this.keysArray.length - this.valuesArray.length; i++) {
                newValues.push('');
            }

            this.valuesArray.concat(newValues);
        } else if(this.keysArray.length < this.valuesArray.length) {
            this.valuesArray.slice(0, this.valuesArray.length - this.keysArray.length);
        }
    }
}

It doesn’t work because it doesn’t seem to execute the setters code when i edit the arrays in the editor.

Is there a reliable way to execute code when the arrays are modified in the editor and update the arrays length ?

Ok nevermind, I made it work. It needed a hidden property for the get/set and i made mistakes in my arrays manipulations. Here is the code :

import { _decorator, Component, CCString } from 'cc';
const { ccclass, property} = _decorator;

@ccclass('NewComponent')
export class NewComponent extends Component {
    private map: Map<string, string>;

    @property([CCString])
    private _keys : Array<string> = [];
    @property([CCString])
    private _values : Array<string> = [];

    private set Keys(value : Array<string> ) {
        this._keys = value;
        this.ensureArraysLength();
    }

    @property([CCString])
    private get Keys() : Array<string> {
        return this._keys;
    }

    private set Values(value : Array<string> ) {
        this._values = value;
        this.ensureArraysLength();
    }

    @property([CCString])
    private get Values() : Array<string> {
        return this._values;
    }

    protected onLoad() : void {
        this.map = new Map<string, string>();
        for(let i = 0; i < this._keys.length; i++) {
            this.map.set(this._keys[i], this._values[i]);
        }

        console.log(this.map);
    }

    private ensureArraysLength() : void {
        console.log('ensureArraysLength');

        if(this._keys.length > this._values.length) {
            let newValues = [];
            for(let i = 0; i < this._keys.length - this._values.length; i++) {
                newValues.push('');
            }

            this._values = this._values.concat(newValues);
            console.log(this._values.length);
        } else if(this._keys.length < this._values.length) {
            this._values = this._values.slice(0, this._values.length - (this._values.length - this._keys.length));
            console.log(this._values.length);
        }
    }
}