-
-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[v0.31.0-rc.5] The internal function _stringify
has a problem
#608
Comments
Perhaps the solution is to use |
Thank you for reporting this issue. How can I reproduce it? I thought due to |
For example, if an object is created with const test1 = Object.create(null);
console.log(typeof test1, test1.constructor); // "object", "undefined"
function Empty() {}
Empty.prototype = Object.create(null);
const test2 = new Empty();
console.log(typeof test2, test2.constructor); // "object", "undefined" |
Nice catch! Thank you! Something like this could work: type = (input && Object.getPrototypeOf(input)?.constructor.name) || 'null'; |
Almost, it should actually be |
I have tested this change in my project but this change brings other problems. As you can see, the const Empty = function () {};
Empty.prototype = Object.create(null);
const schema = object({
id: string(),
});
const input = new Empty();
input.id = 'abc';
const validation = safeParse(schema, input);
console.log(validation); {
typed: false,
success: false,
output: {
id: "123",
},
issues: [
{
kind: "schema",
type: "object",
input: [Object ...],
expected: "Object",
received: "null",
message: "Invalid type: Expected Object but received null",
requirement: undefined,
path: undefined,
issues: undefined,
lang: undefined,
abortEarly: undefined,
abortPipeEarly: undefined,
skipPipe: undefined,
}
],
} |
Although it may seem like an isolated case where |
Sorry for so many comments, but I think issue #602 is related to this problem. Since if we force |
Can you provide me sample input where
This is probably related to our |
Yes, the problem is this line.
Here we could use if (Object.prototype.toString.call(input).slice(8, -1) === 'Object') { |
Sorry, it is not const test1 = Object.create(null);
console.log(Object.getPrototypeOf(test1)); // null
function Empty() {}
Empty.prototype = Object.create(null);
const test2 = new Empty();
console.log(Object.getPrototypeOf(test2)); // {} |
I don't know if I want to change the code this way but I will think about it. If we stick to the current implementation we probably should change
I mean |
The first function Empty() {}
Empty.prototype = Object.create(null);
const test2 = new Empty();
Object.getPrototypeOf(test2); // {}
Object.getPrototypeOf(test2)?.constructor; // undefiend
Object.getPrototypeOf(test2)?.constructor.name; // TypeError: Cannot read properties of undefined (reading 'name')
Object.getPrototypeOf(test2)?.constructor?.name; // undefined |
The problem with using For example, the function Empty() {}
Empty.prototype = Object.create(null); so if with |
As far I as know, class Box<T> {
#value: T;
constructor(value: T) {
this.#value = value;
}
getValue() {
return this.#value;
}
setValue(newValue: T) {
this.#value = newValue;
}
}
const box = new Box("Hello world");
Object.setPrototypeOf(box, {constructor: null});
_stringify(box); // Runtime error |
In conclusion, it seems to be best to remove the plain object check and only check |
I think I will remove it for now until we find a better solution. |
The only solution I see is your recommendation @devcaeg. We could change the type check in Should we also change |
My reply #608 (comment) - Yes, I agree. I think |
class Box<T> {
#value: T;
constructor(value: T) {
this.#value = value;
}
getValue() {
return this.#value;
}
setValue(newValue: T) {
this.#value = newValue;
}
get [Symbol.toStringTag]() {
return "SomethingBox";
}
}
// Custom object type
console.log(Object.prototype.toString.call(new Box("Hello world"))); // [object SomethingBox]
const arrayPrototype = Object.getPrototypeOf([]);
arrayPrototype[Symbol.toStringTag] = "xyz";
// JS provided complex object type
console.log(Object.prototype.toString.call([1, 2, 3])); // [object xyz]
// JS provided plain object
const message = {
value: "Hi",
[Symbol.toStringTag]: "Message"
};
console.log(Object.prototype.toString.call(message)); // [object Message] |
Perhaps it helps to see what |
Due to our small bundle size, Zods solution does not work for us. 🫤 |
This is fixed in v0.31.0-rc.6 |
The internal function
_stringify
has a problem. It may happen thatconstructor
is undefined, so when trying to accessconstructor.name
an error is thrown becausename
cannot be accessed sinceconstructor
is `undefined.valibot/library/src/utils/_stringify/_stringify.ts
Lines 10 to 20 in 2bdb2c8
The text was updated successfully, but these errors were encountered: