typebox icon indicating copy to clipboard operation
typebox copied to clipboard

TypeCheck.Check and TypeCheck.Errors inconsistent with getter methods

Open hstaudacher opened this issue 1 year ago • 1 comments

We encountered the following problem using the TypeCheck:

When there is a schema defining a property and a class providing this property via a getter function, Check and Errors do different things. Check passes while Errors report errors. Here is a mocha test to reproduce:

    test('TypeBox error is different to check', function () {
        const FooSchema = Type.Object({
            foo: Type.String(),
        });
        class Foo {
            _foo: string;
            constructor(foo: string) {
                this._foo = foo;
            }
            get foo() {
                return this._foo;
            }
        }

        const foo = new Foo('bar');
        const compiled = TypeCompiler.Compile(FooSchema);

        assert.ok(compiled.Check(foo));
        const errors = Array.of(compiled.Errors(foo));
        assert.strictEqual(errors.length, 0);
    });

hstaudacher avatar Mar 03 '25 15:03 hstaudacher

Just took a brief look into this

The root cause is that compiled.Check passes becuase in the generated code

(typeof value.foo === 'string')

is passed, while compiled.Errors produces error because a ValueErrorType.ObjectRequiredProperty is yielded, for that foo is not in Object.getOwnPropertyNames(foo) (it's in Object.getOwnPropertyNames(Object.getPrototypeOf(foo)) instead)

There may need a way to fix this mismatch. The related code is at compiler.ts:419 and errors.ts:402

yaindrop avatar Mar 14 '25 02:03 yaindrop

@hstaudacher @yaindrop Hi, sorry for the extended delay on this, I meant to get around to this way sooner.

When there is a schema defining a property and a class providing this property via a getter function, Check and Errors do different things. Check passes while Errors report errors. Here is a mocha test to reproduce:

Yeah, this looks like a bug to me. Based on @yaindrop's assessment, the property enumeration disparities between Errors and Compiler look like the cause. This should have been fixed to keep things consistent, however it can be worked around by avoiding passing class instances in for validation (as TypeBox is only really setup to validate plain object / data)

This said, there exists a new version of TypeBox (1.0) which goes to some lengths to ensure all property enumeration is consistent across the codebase. It might be worth checking out this version and seeing if it resolves the issue.

Documentation on TypeBox 1.0 can be found below.

https://sinclairzx81.github.io/typebox/#/


For now, I might close out this issue as stale given 1.0 has gone stable. However I am happy to receive a PR to resolve the property enumeration issue on 0.34.x. Currently the 0.34.x is managed on the master branch, 1.0 is on the main branch. If you do submit a PR to fix up 0.34.x, just make sure you target the master branch.

If you have any follow up questions on this or the new version, feel free to ping on this thread. Again, sorry for the delay All the best S

sinclairzx81 avatar Sep 09 '25 16:09 sinclairzx81