Skip to content

[IMP] owl-core: add types for Set and Map - #2016

Open
seb-odoo wants to merge 2 commits into
odoo:masterfrom
seb-odoo:master-set-map-types--seb
Open

[IMP] owl-core: add types for Set and Map#2016
seb-odoo wants to merge 2 commits into
odoo:masterfrom
seb-odoo:master-set-map-types--seb

Conversation

@seb-odoo

Copy link
Copy Markdown
Contributor

Before this commit, a set or a map could only be typed with t.instanceOf(Set), which validates the container and nothing else: what it holds is unchecked, and the type derived from the schema is Set<any>. t.customValidator can check the content, but it keeps the type of the base it wraps, so the reader gets no completion.

This commit adds t.set(valueType?) and t.map(keyType?, valueType?), which validate every element, key and value, and resolve to Set<V> and Map<K, V>. A failing entry is reported by its iteration index (0 > key, 0 > value for a map), as a map key can be any value.

Note that the validation context gains withEntry(key, value): a set element and a map key are not reachable by key on the validated value.

Closes #1939

@ged-odoo

Copy link
Copy Markdown
Contributor

i think you should do something like this: ad592dd to avoid observing values when validating types

Before this commit, validating inside a computation subscribes it to
what it validates: an effect calling
`assertType(state.items, t.array(t.number()))` re-runs on every write
to the array, and a `t.customValidator` predicate reading a signal
subscribes to that signal.

This happens because the validators read the value through its proxy,
which also allocates a per-key atom for every key they walk, even
when no computation is active.

This commit runs `validateType` untracked and hands each validation
context the raw value: nothing a validator or a custom predicate
reads is observed, and a reactive value is walked without allocating
anything. Note that an issue now reports the raw value in `received`.
Before this commit, a set or a map could only be typed with
`t.instanceOf(Set)`, which validates the container and nothing else:
what it holds is unchecked, and the type derived from the schema is
`Set<any>`. `t.customValidator` can check the content, but it keeps the
type of the base it wraps, so the reader gets no completion.

This commit adds `t.set(valueType?)` and `t.map(keyType?, valueType?)`,
which validate every element, key and value, and resolve to `Set<V>`
and `Map<K, V>`. A failing entry is reported by its iteration index
(`0 > key`, `0 > value` for a map), as a map key can be any value.

Note that the validation context gains `withEntry(key, value)`: a set
element and a map key are not reachable by key on the validated value.

Closes odoo#1939
@seb-odoo
seb-odoo force-pushed the master-set-map-types--seb branch from c7e6bcc to 744438e Compare August 24, 2026 10:46
@seb-odoo

Copy link
Copy Markdown
Contributor Author

@ged-odoo but then the issue is generic and pre-existing, it should apply to all types, including custom validators that use signal internally, so untrack should be used. toRaw is only useful for performance when walking through proxy (and kills the reactivity as a side effect, which would make it inconsistent with signal that are unaffected).

I pushed a new commit to take this into account, but I'm not sure if we really need this.

Is there anything actually observing while validate?

If the validator is called in an effect/computed like in the tests, wouldn't it be the expected behavior that it actually re-validates on change?

@seb-odoo

Copy link
Copy Markdown
Contributor Author

Should I push the PR without the no-observing commit, so we can already merge the Set/Map, and determine later/when we have time whether observing should be handled or not and how?

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

Successfully merging this pull request may close these issues.

add types for Set and Map

2 participants